質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

Q&A

解決済

1回答

6253閲覧

自作モジュールのテストコードがImportErrorで動きません

manzyun

総合スコア2244

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

2グッド

1クリップ

投稿2016/03/06 02:53

編集2016/03/06 08:03

現在「投稿に期限がついており、期限になったら削除されるBBS」を以下で作っております。

  • Ubuntu Wily
  • Python3.5
  • Flask
  • MongoDB

リポジトリは以下に公開しております。
manzyun / Setsuna — Bitbucket

ディレクトリ構成に関しては以下になります。詳しくは上記リポジトリをご覧いただけると幸いです。

  • pyvenvディレクトリ
    • アプリケーションコード
      • テストコード

しかし、この構成でリポジトリのコードだと、unittestやnose2を動かすと
ImportError: No module named 'conf'
とでてしまい、テストも実行されません。また、pudbでテストコードを動かしても
ImportError: No module named 'setsuna'
となってしまい、テストが全く実行出来ずに困っています。

Pythonのモジュールインポートの話だと思うのですが、
もしかしたらconf.pyの中身が変数しか無いことが原因なのかもしれないのかと思っているのですが、僕自身現状がどうなっているのかわかりません。

参考までに、該当するテストコードとテスト対象のコードを貼り付けます。

python

1import unittest 2 3from setsuna import conf, models 4from unittest import TestCase, expectedFailure 5from pymongo import MongoClient 6import json 7import datetime 8import calendar 9 10 11testdata = {"content": "美味しい美味しいスープカレー", 12 "limit": calendar.timegm( 13 datetime.datetime.utcnow().timetuple()), 14 "delkey": "hogefuga"} 15 16class TestPost(TestCase): 17 client = MongoClient(conf._conf["address"], conf._conf["port"]) 18 db = client[conf._conf["database"]] 19 collection = db[conf._conf["collection"]] 20 21 def setUp(self): 22 # とりあえず書く 23 self.testindex = TestPost.collection.insert_one(testdata) 24 25 def tearDown(self): 26 TestPost.collection.delete_one(self.testindex) 27 28 def test_make_model(self): 29 """ モデルが読み込まれてインスタンスが生成されるか """ 30 model = models.Post() 31 model.read(self.testindex) 32 33 d = {"content": model.content, 34 "limit": model.limit, 35 "delkey": model.delkey} 36 37 del testdata['_id'] 38 39 self.assertDictEqual(d, testdata) 40 41 def test_insert_model(self): 42 """ 生成したインスタンスが、インスタンスの情報を維持したまま挿入されるか """ 43 model = models.Post() 44 model.content = "にくまん、あんまん、カレーまん" 45 model.delkey = "nununeno" 46 sample_id = model.post() 47 48 model_sample = models.Post.read(sample_id) 49 50 self.assertDictEqual(model, model_sample) 51 52 53 def test_delete_model(self): 54 """ 狙ったレコードがパスワードが合致した場合に削除されるか """ 55 model = models.Post(self.testindex) 56 model.delete(testdata["delkey"]) 57 58 self.assertRaises(NoneRecordException, 59 self.collection.find_one({"unique_id": testdata["unique_id"]})) 60 61 def test_dead_model(self): 62 """ リミットオーバーした場合投稿が削除されるか """ 63 model = models.Post(self.testindex) 64 model.apoptosis() 65 66 self.assertRaises(NoneRecordException, 67 self.collection.find_one({"unique_id": testdata["unique_id"]})) 68 69if __name__ == "__main__": 70 unittest.main()

python

1from conf import _conf 2from pymongo import MongoClient 3import json 4import datetime 5import random 6import bson 7 8 9class Post(): 10 # DB Connection 11 connect = MongoClient(_conf["address"], _conf["port"]) 12 posts = connect[_conf["database"]][_conf["collection"]] 13 14 def __init__(self): 15 # Read DB 16 self._id = None 17 self.content = "" 18 self.limit = 0.0 19 self.delkey = "" 20 21 def read(self, _id): 22 # Read DB 23 self._id = _id 24 post = Post.posts.find_one({"_id": self._id}) 25 self.content = post["content"] 26 self.limit = post["limit"] 27 self.delkey = post["delkey"] 28 29 def post(self, content="", delkey=""): 30 self.content = content 31 self.delkey = delkey 32 if self.delkey == "": 33 self.delkey = make_delkey() 34 self.limit = datetime.timedelta(seconds=28800) 35 36 # Writing DB 37 try: 38 result = Post.posts.insert_one({"content": self.content, 39 "limit": self.limit, 40 "delkey": self.delkey}) 41 return str(result["_id"]) 42 except Exception as e: 43 return e 44 45 def delete(self, delkey): 46 try: 47 if self._id == _id and self.delkey == delkey: 48 # Remove post in DB 49 collection.delete_one({"_id": self._id}) 50 return True 51 else: 52 return False 53 except Exception as e: 54 return e 55 56def make_delkey(length=6): 57 # Make font map 58 alphabets = [] 59 codes = (('a', 'z'), ('A', 'Z'), ('0', '9')) 60 for r in codes: 61 chars = map(chr, range(ord(r[0]), ord(r[1]) + 1)) 62 alphabets.extend(chars) 63 64 password = [random.choice(alphabets) for _ in range(length)] 65 delkey = "".join(password) 66 67 return delkey 68 69if __name__ == "__main__": 70 test = Post() 71 72 test.connect = "にくまん" 73 test.delkey = "hogefuga" 74 test.limit = 123456.78 75 76 print(test.post())

以上です。長文失礼いたします。

ikuwow👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

2016/3/7 午前中

すみません、自己解決(?)しました。

Pythonで自作モジュールを手軽に使う - Qiita

ただ、この解法、個人的にはクールじゃないなあと思っているのですが、僕の能力ではこれ以上考えても埒が明かないので、この方法でテストを継続しようと思います。

2016/3/7 15:33 追記

各モジュールにsys.path.appendを入れるのはやっぱり面倒なので、以下モジュールを作ってテストディレクトリ以下に入れて使うのが良さそうですね。
import from parent directory | Python Adventures

2016/3/7 18:21 追記

拙いながらこんなモジュールを書きました。
コレをテストコードのディレクトリに置いてimport_my_moduleメソッドでPYTHONPATHにパスを追加することで、理想通りテストが動くようになりました。
This file deploy your script directory. Then your make module import easly maybe.

また、confのエラーに関しては相対インポートを使ってインポートさせるようにして動作させました。
6. モジュール (module) — Python 3.5.1 ドキュメント

投稿2016/03/07 04:11

編集2016/03/07 09:30
manzyun

総合スコア2244

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問