質問編集履歴
2
質問内容書き換え他。
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
|
1
|
+
自作モジュールのテストコードがImportErrorで動きません
|
body
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
- Ubuntu Wily
|
4
4
|
- Python3.5
|
5
|
+
- Flask
|
5
6
|
- MongoDB
|
6
7
|
|
7
8
|
リポジトリは以下に公開しております。
|
@@ -13,14 +14,167 @@
|
|
13
14
|
- アプリケーションコード
|
14
15
|
- テストコード
|
15
16
|
|
17
|
+
しかし、この構成でリポジトリのコードだと、unittestやnose2を動かすと
|
18
|
+
`ImportError: No module named 'conf'`
|
16
|
-
|
19
|
+
とでてしまい、テストも実行されません。また、pudbでテストコードを動かしても
|
20
|
+
`ImportError: No module named 'setsuna'`
|
21
|
+
となってしまい、テストが全く実行出来ずに困っています。
|
17
22
|
|
18
|
-
|
23
|
+
Pythonのモジュールインポートの話だと思うのですが、
|
19
|
-
|
24
|
+
もしかしたらconf.pyの中身が変数しか無いことが原因なのかもしれないのかと思っているのですが、僕自身現状がどうなっているのかわかりません。
|
20
|
-
`python -m unittest`では`ImportError: Failed to import test module: setsuna.test.test_models`と`ImportError: No module named 'conf'`
|
21
25
|
|
22
|
-
|
26
|
+
参考までに、該当するテストコードとテスト対象のコードを貼り付けます。
|
23
27
|
|
28
|
+
```python
|
24
|
-
import
|
29
|
+
import unittest
|
25
30
|
|
31
|
+
from setsuna import conf, models
|
32
|
+
from unittest import TestCase, expectedFailure
|
33
|
+
from pymongo import MongoClient
|
34
|
+
import json
|
35
|
+
import datetime
|
36
|
+
import calendar
|
37
|
+
|
38
|
+
|
39
|
+
testdata = {"content": "美味しい美味しいスープカレー",
|
40
|
+
"limit": calendar.timegm(
|
41
|
+
datetime.datetime.utcnow().timetuple()),
|
42
|
+
"delkey": "hogefuga"}
|
43
|
+
|
44
|
+
class TestPost(TestCase):
|
45
|
+
client = MongoClient(conf._conf["address"], conf._conf["port"])
|
46
|
+
db = client[conf._conf["database"]]
|
47
|
+
collection = db[conf._conf["collection"]]
|
48
|
+
|
49
|
+
def setUp(self):
|
50
|
+
# とりあえず書く
|
51
|
+
self.testindex = TestPost.collection.insert_one(testdata)
|
52
|
+
|
53
|
+
def tearDown(self):
|
54
|
+
TestPost.collection.delete_one(self.testindex)
|
55
|
+
|
56
|
+
def test_make_model(self):
|
57
|
+
""" モデルが読み込まれてインスタンスが生成されるか """
|
58
|
+
model = models.Post()
|
59
|
+
model.read(self.testindex)
|
60
|
+
|
61
|
+
d = {"content": model.content,
|
62
|
+
"limit": model.limit,
|
63
|
+
"delkey": model.delkey}
|
64
|
+
|
65
|
+
del testdata['_id']
|
66
|
+
|
67
|
+
self.assertDictEqual(d, testdata)
|
68
|
+
|
69
|
+
def test_insert_model(self):
|
70
|
+
""" 生成したインスタンスが、インスタンスの情報を維持したまま挿入されるか """
|
71
|
+
model = models.Post()
|
72
|
+
model.content = "にくまん、あんまん、カレーまん"
|
73
|
+
model.delkey = "nununeno"
|
74
|
+
sample_id = model.post()
|
75
|
+
|
76
|
+
model_sample = models.Post.read(sample_id)
|
77
|
+
|
78
|
+
self.assertDictEqual(model, model_sample)
|
79
|
+
|
80
|
+
|
81
|
+
def test_delete_model(self):
|
82
|
+
""" 狙ったレコードがパスワードが合致した場合に削除されるか """
|
83
|
+
model = models.Post(self.testindex)
|
84
|
+
model.delete(testdata["delkey"])
|
85
|
+
|
86
|
+
self.assertRaises(NoneRecordException,
|
87
|
+
self.collection.find_one({"unique_id": testdata["unique_id"]}))
|
88
|
+
|
89
|
+
def test_dead_model(self):
|
90
|
+
""" リミットオーバーした場合投稿が削除されるか """
|
91
|
+
model = models.Post(self.testindex)
|
92
|
+
model.apoptosis()
|
93
|
+
|
94
|
+
self.assertRaises(NoneRecordException,
|
95
|
+
self.collection.find_one({"unique_id": testdata["unique_id"]}))
|
96
|
+
|
97
|
+
if __name__ == "__main__":
|
98
|
+
unittest.main()
|
99
|
+
```
|
100
|
+
|
101
|
+
```python
|
102
|
+
from conf import _conf
|
103
|
+
from pymongo import MongoClient
|
104
|
+
import json
|
105
|
+
import datetime
|
106
|
+
import random
|
107
|
+
import bson
|
108
|
+
|
109
|
+
|
110
|
+
class Post():
|
111
|
+
# DB Connection
|
112
|
+
connect = MongoClient(_conf["address"], _conf["port"])
|
113
|
+
posts = connect[_conf["database"]][_conf["collection"]]
|
114
|
+
|
115
|
+
def __init__(self):
|
116
|
+
# Read DB
|
117
|
+
self._id = None
|
118
|
+
self.content = ""
|
119
|
+
self.limit = 0.0
|
120
|
+
self.delkey = ""
|
121
|
+
|
122
|
+
def read(self, _id):
|
123
|
+
# Read DB
|
124
|
+
self._id = _id
|
125
|
+
post = Post.posts.find_one({"_id": self._id})
|
126
|
+
self.content = post["content"]
|
127
|
+
self.limit = post["limit"]
|
128
|
+
self.delkey = post["delkey"]
|
129
|
+
|
130
|
+
def post(self, content="", delkey=""):
|
131
|
+
self.content = content
|
132
|
+
self.delkey = delkey
|
133
|
+
if self.delkey == "":
|
134
|
+
self.delkey = make_delkey()
|
135
|
+
self.limit = datetime.timedelta(seconds=28800)
|
136
|
+
|
137
|
+
# Writing DB
|
138
|
+
try:
|
139
|
+
result = Post.posts.insert_one({"content": self.content,
|
140
|
+
"limit": self.limit,
|
141
|
+
"delkey": self.delkey})
|
142
|
+
return str(result["_id"])
|
143
|
+
except Exception as e:
|
144
|
+
return e
|
145
|
+
|
146
|
+
def delete(self, delkey):
|
147
|
+
try:
|
148
|
+
if self._id == _id and self.delkey == delkey:
|
149
|
+
# Remove post in DB
|
150
|
+
collection.delete_one({"_id": self._id})
|
151
|
+
return True
|
152
|
+
else:
|
153
|
+
return False
|
154
|
+
except Exception as e:
|
155
|
+
return e
|
156
|
+
|
157
|
+
def make_delkey(length=6):
|
158
|
+
# Make font map
|
159
|
+
alphabets = []
|
160
|
+
codes = (('a', 'z'), ('A', 'Z'), ('0', '9'))
|
161
|
+
for r in codes:
|
162
|
+
chars = map(chr, range(ord(r[0]), ord(r[1]) + 1))
|
163
|
+
alphabets.extend(chars)
|
164
|
+
|
165
|
+
password = [random.choice(alphabets) for _ in range(length)]
|
166
|
+
delkey = "".join(password)
|
167
|
+
|
168
|
+
return delkey
|
169
|
+
|
170
|
+
if __name__ == "__main__":
|
171
|
+
test = Post()
|
172
|
+
|
173
|
+
test.connect = "にくまん"
|
174
|
+
test.delkey = "hogefuga"
|
175
|
+
test.limit = 123456.78
|
176
|
+
|
177
|
+
print(test.post())
|
178
|
+
```
|
179
|
+
|
26
180
|
以上です。長文失礼いたします。
|
1
初心者アイコンを取り消し。
title
CHANGED
File without changes
|
body
CHANGED
File without changes
|