いくつかのtest_ *メソッドを持つ抽象的なTestCase
を作成することはできますが、このTestCase
は呼び出されず、それらのメソッドはサブクラスでのみ使用されますか?私は私のテストスイートに1つの抽象的なTestCase
を持つつもりだと思うし、それは1つのインタフェースのいくつかの異なる実装のためにサブクラス化されます。このため、すべてのテストメソッドは、唯一の内部メソッドの変更の一部です。どのように私はエレガントな方法でそれを行うことができますか?python unittestを使用した抽象テストケース
答えて
私は非常にあなたがする予定ですか何を理解していなかった - 親指のルールは、「テストとスマートではない」である - 単なる書かれ、そこにそれらを持っています。
しかし、あなたがunittest.main()を呼び出すたびにunittest.TestCaseを継承すると、抽象クラスが実行されます。これは避けたい状況です。
TestCaseではなく、「オブジェクト」を継承する「抽象的な」クラスを作成します。 実際の "具体的な"実装では、unittest.TestCaseと抽象クラスの両方から継承した複数の継承を使用してください。
import unittest
class Abstract(object):
def test_a(self):
print "Running for class", self.__class__
class Test(Abstract, unittest.TestCase):
pass
unittest.main()
更新は: - そのdefintionsが同様に蛇腹コメント欄で指摘し、TestCase
デフォルトで上書きされないように第一Abstract
継承順序を逆転させました。
これは私が最初にこれをやりたかった方法です。私は別のデータベースに対して自分のテストを実行しているので、賢くなりたいです。データベースにアクセスするためのインターフェイスは常に同じなので、データベースへの接続をインスタンス化するだけで、常に同じテストが実行されます。私はそれがテストにはあまりにもスマートなのか分かりませんが、たくさん入力するのが好きではありません;-) – gruszczy
はい、私は自分自身を「スマートなものにする」のが好きです。だから...私の答えに欠けているものを明確にすることができますか?コマンドラインのパラメータに応じて、testCaseクラスのテストメソッドを "プラグ"する方法があります。 – jsbueno
私が仕事に就いていないとき、私は非常に賢いことをするのが好きです。このようにして、何かをねじ込んでも、もっと学ぶことができます:-)ここにはリスクはありません。 – gruszczy
run_unittestのすべてのテストクラスを明示的にリストするという慣例に従うと、にはまっすぐになり、は特定のクラスをリストします。
unittest.mainの使用を継続したい場合、unittest2の使用を許可する場合(例えばPython 2.7から)は、load_testsプロトコルを使用して、テストケースを含むクラスを指定できます。以前のバージョンでは、TestLoaderをサブクラス化し、loadTestsFromModuleをオーバーライドする必要があります。
コマンドラインからこれらのテストを呼び出す能力を失うことはありませんか?デフォルトでは、すべてのテスト(抽象的なテストケースのものを除く)を実行したいと思いますが、場合によってはそれらのうちのいくつかのみを実行します。 – gruszczy
@ gruszczy:私の編集を参照してください。 –
多重継承は、主に次の二つの理由から、ここでは偉大な選択肢ではないではありません。TestCase
使用super()
のメソッドのいずれ
- ので、あなたは
setUp()
のような方法のために最初にあなたのクラスを一覧表示する必要があると思いますし、tearDown()
が動作します。 - pylintは、その時点で
self
で定義されていないself.assertEquals()
などをベースクラスが使用していることを警告します。
私が思いついたクルーは、run()
を基本クラスのノーオペレーションに限定してください。
class TestBase(unittest.TestCase):
def __init__(self, *args, **kwargs):
super(TestBase, self).__init__(*args, **kwargs)
self.helper = None
# Kludge alert: We want this class to carry test cases without being run
# by the unit test framework, so the `run' method is overridden to do
# nothing. But in order for sub-classes to be able to do something when
# run is invoked, the constructor will rebind `run' from TestCase.
if self.__class__ != TestBase:
# Rebind `run' from the parent class.
self.run = unittest.TestCase.run.__get__(self, self.__class__)
else:
self.run = lambda self, *args, **kwargs: None
def newHelper(self):
raise NotImplementedError()
def setUp(self):
print "shared for all subclasses"
self.helper = self.newHelper()
def testFoo(self):
print "shared for all subclasses"
# test something with self.helper
class Test1(TestBase):
def newHelper(self):
return HelperObject1()
class Test2(TestBase):
def newHelper(self):
return HelperObject2()
(1)は本当に問題ではありません - あなたのクラスが最初に来てスーパーを使用することです(私の答えは逆でした - 。 (2)あなたが使用している言葉で言えば、サードパーティ製の糸くず取りツールが正しくイントロスペクトすることができないため、PythonのOOPに組み込まれたきれいなメカニズムを使用しないように "kludge"を使用する必要があります。それはあなたのツールの選択です。 – jsbueno
それはおそらく、いくつかの規則に反するが、ちょうど私の2セント-に入れて、あなたはその実行を防止するための保護されたメンバーとしてあなたの抽象テストケースを定義することができます。私はDjangoで以下を実装し、必要に応じて動作します。以下の例を参照してください。
from django.test import TestCase
class _AbstractTestCase(TestCase):
"""
Abstract test case - should not be instantiated by the test runner.
"""
def test_1(self):
raise NotImplementedError()
def test_2(self):
raise NotImplementedError()
class TestCase1(_AbstractTestCase):
"""
This test case will pass and fail.
"""
def test_1(self):
self.assertEqual(1 + 1, 2)
class TestCase2(_AbstractTestCase):
"""
This test case will pass successfully.
"""
def test_1(self):
self.assertEqual(2 + 2, 4)
def test_2(self):
self.assertEqual(12 * 12, 144)
これはうまくいくようで、上のサルパッチアプローチよりもずっと簡単です。 – Fasaxc
これはdjango(と私の場合は鼻で動作するかもしれませんが、unittest発見メカニズムはまだこれらの抽象的なテストケースを見つけるようです... –
djangoでは動作しません。ちょうどテストした –
Pythonのunittestのライブラリには、あなたが正確に何をしたいです達成するために使用することができload_tests protocolを、持っている:
# Add this function to module with AbstractTestCase class
def load_tests(loader, tests, _):
result = []
for test_case in tests:
if type(test_case._tests[0]) is AbstractTestCase:
continue
result.append(test_case)
return loader.suiteClass(result)
誰もがこれまで見逃したこと非常に簡単な方法があります。いくつかの回答とは異なり、すべてテストドライバで動作します。
del AbstractTestCase
をモジュールの終わりに:
だけで、その後追加し、いつものように継承を使用しています。
欠点はありますか? –
@MaxMalyshスーパークラスへの古いスタイルの呼び出しは使用できません。しかし、「スーパー」はまだ動作しており、誰もが本当にそれを使用すべきです。 – o11c
- 1. のpythonは抽象testBaseクラスのテストを防ぐunittestの自身
- 2. Pythonのインタフェースと継承を使用したマルチレベル抽象化
- 3. 抽象ルーティングデータソースを使用したルーティングデータソース
- 4. 抽象メソッドを使用したインターフェイス
- 5. Python DDL抽象
- 6. Doctestを使用したPythonのテストケース
- 7. Pythonの抽象化
- 8. Pythonの抽象化?
- 9. Pythonの抽象プログラミング
- 10. Python抽象属性
- 11. Javaで抽象クラスと抽象メソッドを使用する理由
- 12. 抽象フォームWinFormsを使用して
- 13. Log4netを使った単純なインジェクタと抽象抽象
- 14. 抽象ファクトリパターン - 未使用コード
- 15. python unittestを使用した複数のテストファイルの要約
- 16. ライブラリ抽象をPythonで使用できますか?
- 17. Pythonの:抽象クラスの__init__
- 18. Python - 抽象クラスのサブクラス化
- 19. shared_ptrを使用してboost.pythonの所有者として抽象基盤を抽象化
- 20. python抽象基底クラス、mixinと抽象メソッドの違い
- 21. 抽象クラスを使用してPHPでインターフェイスを満たす
- 22. 抽象クラス番号を使用したPI割り当て
- 23. サブクラスを使用した抽象コレクションのJPA criteria検索プロパティ
- 24. ラムダ/矢印関数を使用したTypeScript抽象メソッド
- 25. コアデータを使用したモデルコントローラの抽象化
- 26. (Entity Frameworkを使用した)SqlExceptionsの抽象化
- 27. std :: make_shared抽象クラスのインスタンス化を使用したエラー
- 28. 抽象モデルを使用したSignalrクライアントからサーバープッシュ
- 29. 抽象ファクトリを使用した場合の欠点とパターンアドレス
- 30. 抽象クラスを使用した合成関係 - Java
これは、テストを実行するために鼻を使用するとやや簡単かもしれません。 [テストの検索と実行](http://somethingaboutorange.com/mrl/projects/nose/1.0.0/finding_tests.html)を参照してください。鼻では、たとえば、ベースクラスに '__test __ = False'を入れることができます。 – bstpierre
抽象的なテストケースでスキップを使用することはどうですか? – gruszczy
@bstpierre素晴らしい提案。それは私のために完璧に働いた –