djangoユニットテストを複数のファイルに分散する方法は?


126
  • 私はpython-djangoアプリケーションを持っています
  • 単体テストフレームワークを使用しています
  • テストは、モジュールディレクトリの「tests.py」ファイルに配置されています。
  • 私はテストを実行しています ./manage.py test app

今…

  • tests.pyファイルはかなり大規模/複雑になっている/汚いです
  • tests.pyテストの小さなコレクションに分割したい...

どうやって?

回答:


47

Django 1.6では動作が変更されたため、パッケージを作成する必要がなくなりました。ファイルに名前を付けるだけですtest*.py

Django 1.7ドキュメントから

テストを実行すると、テストユーティリティのデフォルトの動作では、名前がtestで始まるファイル内のすべてのテストケース(つまり、unittest.TestCaseのサブクラス)が検索され、それらのテストケースからテストスイートが自動的に構築されます。そのスイートを実行します。

Django 1.6のドキュメントから、

テストディスカバリは、unittestモジュールの組み込みテストディスカバリに基づいています。デフォルトでは、現在の作業ディレクトリの下にある「test * .py」という名前のファイル内のテストが検出されます。

以前の動作、Django 1.5ドキュメントから

テストを実行すると、テストユーティリティのデフォルトの動作では、models.pyとtests.pyですべてのテストケース(つまり、unittest.TestCaseのサブクラス)が検出され、それらのテストケースから自動的にテストスイートが構築されます。そのスイートを実行します。

モジュールのテストスイートを定義する2つ目の方法があります。models.pyまたはtests.pyでsuite()という関数を定義すると、Djangoテストランナーはその関数を使用して、そのモジュールのテストスイートを構築します。これは、単体テスト用に提案された編成に従います。複雑なテストスイートの作成方法の詳細については、Pythonのドキュメントをご覧ください。


4
django 2.6では、実際には何も検出されません…
LtWorf 2015年

2
現在Django 1.10を使用しているので、 test*.pytestsしているため、フォルダをクリーンに保つために呼び出されるフォルダファイル -これは可能ですが、実行する必要が./manage.py test app.testsあり、すべての相対インポートはレベルを上げる必要があります(にfrom .modelsなるfrom ..models)。
スコットスティーブンス

123

このアプローチはDjango 1.6から有効ではなくなったことに注意してください。この投稿を参照してください。

(パッケージになるように)内部でtestsフォルダを作成できます___init___.py。次に、そこに分割テストの.pyファイルを追加し、それらすべてをにインポートし___init___.pyます。

test.pyつまり、ファイルのように見え、動作するモジュールでファイルを置き換えます。

tests問題のアプリの下にディレクトリを作成します

アプリ
app \ models.py
app \ views.py
app \ tests
app \ tests \ __ init__.py
app \ tests \ bananas.py
app \ tests \ apples.py

サブモジュールをにインポートしapp\tests\__init__.pyます。

from bananas import *
from apples import *

これで、。/ manage.pyをすべて1つのファイルにあるかのように使用できます。

./manage.py test app.some_test_in_bananas

1
どー。私がテストしているアプリケーションの下に「テスト」モジュールを作成することを意味しました。テストと呼ばれる新しいアプリケーションではありません。わかった。驚くばかり。ありがとう!
John Mee

@ジョン:もう答えがわからない!:-)しかし、あなたはそれが正しいとしても、曖昧すぎるということは完全に正しいです-あなたの例は、私の元の文言に反して、それを明確にします。
TomaszZieliński11年

2
@Tomasz ..あなたの言葉はまだ残っています-完全に無傷です。あなたが私を正しい軌道に乗せたので、私はそれを少し肉付けしました。
John Mee

@ジョン:それがあなたの意味するところなら、私はまったく怒っていませんでした:)少し違う形で自分の答えを見るのは面白いです
TomaszZielińskiJun

4
@jMyles、「通常のdjangoテストランナー」とはpython manage.py test myapp、実際にはこの答えがうまく機能することを意味します。(試してみただけ)
カークウォル2012

27

トマシュが述べた答えは正しいです。ただし、輸入を確実にすることは退屈な作業になる可能性があります。__init__.pyファイル構造一致ます。

フォルダ内のすべてのテスト自動的に検出するには、これを__init__.py次の場所に追加できます

import unittest

def suite():   
    return unittest.TestLoader().discover("appname.tests", pattern="*.py")

これにより、実行はできます./manage.py test appnameが、特定のテストの実行は処理されません。これを行うには、次のコードを使用できます(これも__init__.py):

import pkgutil
import unittest

for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
    module = loader.find_module(module_name).load_module(module_name)
    for name in dir(module):
        obj = getattr(module, name)
        if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
            exec ('%s = obj' % obj.__name__)

これで、すべてのテストを実行するmanage.py test appか、特定のテストを実行できますmanage.py test app.TestApples


2番目のピースはどこに配置しますか?
rh0dium 2013

両方の作品が入る__init__.py
ブライスドレンナン2013

テストパッケージ名のいずれかが、テスト実行中にインポートされる最上位モジュール名と一致する場合、テストがとして追加されるため、pkgutilスニペットによりインポートが失敗することに注意してくださいsys.modules[packagename]。簡単な回避策はdel、上記の後に問題を引き起こすものです。(または、フォルダの名前を変更できます;))
Paul Fenney

これは素晴らしいことですが、アプリレベルのテスト(python manage.py test appName)を実行すると、コードの2番目のビットが__path__利用できないことを示すエラーをスローするエラーに遭遇しました。2つ目のスニペットをif '__path__' in locals():チェックでラップすることで回避しました。答えてくれてありがとう!
alukach 2013

1
+1これにより、initファイルが一般的なコーディング標準に準拠していること、つまり*または未使用のインポートがないことも保証されます
Martin B.

13

次のようにディレクトリ構造を作成するだけです。

myapp/
    __init__.py
    tests/
        __init__.py
        test_one.py
        test_two.py
        ...
    ...

そして、python manage.py test myapp期待通りに動作します。



2

initで何もコーディングする必要はありません。アプリにサブディレクトリを作成するだけです。要件はそれをテストと呼ぶことではありません*例の 場合

app/
app/__init_.py
app/serializers.py
app/testing/
app/testing/__init__.py
app/testing/tests_serializers.py

1
「テスト」で始まるものとは言えないのはなぜですか。
Serp C

私はDjango 1.11.4でこの回答を使用しています。使用する理由:(1)ファイル "app / testing / __ init__.py"は空のままで、(2)コマンドは基本的な "python manage.py test app"のままです
rprasad

2

Django 2.2を使用する場合、シンプルでかなり良い解決策はtest、アプリ内にフォルダーを作成することであり、関連test_...pyファイル__init__.pyをそのtestフォルダーに追加するだけです。


1

より複雑な設定がある場合、またはfrom ... import *-typeステートメントを使用したくない場合はsuite、tests.py(またはtests / __ init__.py)で呼び出される関数を定義できますunittest.TestSuite。これはのインスタンスを返します。


0

私は./manage.py test単にすべてのテストトリックを実行していると思います(django> = 1.7で)。

あなたの場合は整理テストについてですグループ化チェリーピッキング、あなたはのファンnoseを使用鼻ジャンゴ

python manage.py test another.test:TestCase.test_method

あなたが鼻を知っているなら、あなたはあなたのすべてのファイルをはるかにうまく「ワイルドカード」する方法を知っています。

PS

それは単なるより良い習慣です。お役に立てば幸いです。答えはここから借りました:アプリにテストディレクトリがある場合のDjangoでの特定のテストケースの実行


0

2つのファイルがあります。1つはtests.py、もう1つはですtest_api.py。以下のように個別に実行できます。

   manage.py test companies.tests
   manage.py test companies.test_api

ファイルの命名規則については、@ osaの応答を参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.