25.3. unittest
— ユニットテストフレームワーク¶
バージョン 2.1 で追加.
(読者の方がすでにテストの基本概念についてなじみがあるようでしたら、この部分をとばして the list of assert methods に進むと良いでしょう。)
この Python ユニットテストフレームワークは時に "PyUnit" とも呼ばれ、 Kent Beck と Erich Gamma による JUnit の Python 版です。 JUnit はまた Kent の Smalltalk 用テストフレームワークの Java 版で、どちらもそれぞれの言語で業界標準のユニットテストフレームワークとなっています。
unittest
では、テストの自動化・初期設定と終了処理の共有・テストの分類・テスト実行と結果レポートの分離などの機能を提供しており、 unittest
のクラスを使って簡単にたくさんのテストを開発できるようになっています。
これを実現するために、 unittest
はいくつかの重要な概念をサポートしています:
- テストフィクスチャ (test fixture)
- test fixture とは、テスト実行のために必要な準備や終了処理を指します。例: テスト用データベースの作成・ディレクトリ・サーバプロセスの起動など。
- テストケース (test case)
- test case はテストの最小単位で、各入力に対する結果をチェックします。テストケースを作成する場合は、
unittest
が提供するTestCase
クラスを基底クラスとして利用することができます。 - テストスイート (test suite)
- test suite はテストケースとテストスイートの集まりで、同時に実行しなければならないテストをまとめる場合に使用します。
- テストランナー (test runner)
- test runner はテストの実行と結果表示を管理するコンポーネントです。ランナーはグラフィカルインターフェースでもテキストインターフェースでも良いですし、何も表示せずにテスト結果を示す値を返すだけの場合もあります。
unittest
では、テストケースとテストフィクスチャーを、 TestCase
クラスと FunctionTestCase
クラスで提供しています。 TestCase
クラスは新規にテストを作成する場合に使用し、 FunctionTestCase
は既存のテストを unittest
に組み込む場合に使用します。テストフィクスチャーの初期化処理と終了処理は、 TestCase
では setUp()
メソッドと tearDown()
をオーバーライドして記述し、 FunctionTestCase
では初期化・終了処理を行う既存の関数をコンストラクタで指定します。テスト実行時、まずテストフィクスチャーの初期設定が最初に実行されます。初期化処理が正常終了した場合、テスト実行後にはテスト結果に関わらず終了処理が実行されます。 TestCase
の各インスタンスが実行するテストは一つだけで、テストフィクスチャーは各テストごとに新しく作成されます。
テストスイートは TestSuite
クラスで実装されており、複数のテストとテストスイートをまとめる事ができます。テストスイートを実行すると、スイートと 子 スイートに追加されている全てのテストが実行されます。
テストランナーは run()
メソッドを持つオブジェクトです。このメソッドは引数として TestCase
か TestSuite
オブジェクトを受け取り、テスト結果を TestResult
オブジェクトで戻します。 unittest
ではデフォルトでテスト結果を標準エラーに出力する TextTestRunner
をサンプルとして実装しています。これ以外のランナー (グラフィックインターフェース用など) を実装する場合でも、特別なクラスから派生させて実装する必要はありません。
参考
doctest
モジュール- もうひとつのテストをサポートするモジュールで、本モジュールと趣きが異なっています。
- unittest2: A backport of new unittest features for Python 2.4-2.6
- Python 2.7 になり多くの機能が unittest に追加されました。特に、テストディスカバリが追加されました。 unittest2 を導入する事で以前のバージョンの Python でもこれらの機能を使えます。
- Simple Smalltalk Testing: With Patterns
- Kent Beck のテスティングフレームワークに関する原論文で、ここに記載されたパターンを
unittest
が使用しています。 - Nose と py.test
- サードパーティのユニットテストフレームワークで軽量な文法でテストを書くことができます。例えば、
assert func(10) == 42
のように書きます。 - The Python Testing Tools Taxonomy
- 多くの Python のテストツールが一覧で紹介されています。ファンクショナルテストのフレームワークやモックライブラリも掲載されています。
- Testing in Python メーリングリスト
- Python でテストやテストツールについての議論に特化したグループです。
25.3.1. 基礎的な例¶
unittest
モジュールには、テストの開発や実行の為の優れたツールが用意されており、この節では、その一部を紹介します。ほとんどのユーザとっては、ここで紹介するツールだけで十分でしょう。
以下は、三つの文字列メソッドをテストするスクリプトです:
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
unittest.main()
テストケースは、 unittest.TestCase
のサブクラスとして作成します。メソッド名が test
で始まる三つのメソッドがテストです。テストランナーはこの命名規約によってテストを行うメソッドを検索します。
これらのテスト内では、予定の結果が得られていることを確かめるために assertEqual()
を、条件のチェックに assertTrue()
や assertFalse()
を、例外が発生する事を確認するために assertRaises()
をそれぞれ呼び出しています。 assert
文の代わりにこれらのメソッドを使用すると、テストランナーでテスト結果を集計してレポートを作成する事ができます。
setUp()
および tearDown()
メソッドによって各テストメソッドの前後に実行する命令を実装することが出来ます。詳細は テストの構成 を参照してください。
サンプルの末尾が、簡単なテストの実行方法です。 unittest.main()
は、テストスクリプトのコマンドライン用インターフェースです。コマンドラインから起動された場合、上記のスクリプトから以下のような結果が出力されます:
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
簡略化した結果を出力したり、コマンドライン以外からも起動する等のより細かい制御が必要であれば、 unittest.main()
を使用せずに別の方法でテストを実行します。コマンドラインから起動する必要もありません。例えば、上記サンプルの最後の2行は以下のように書くことができます:
suite = unittest.TestLoader().loadTestsFromTestCase(TestStringMethods)
unittest.TextTestRunner(verbosity=2).run(suite)
変更後のスクリプトをインタープリタや別のスクリプトから実行すると、以下の出力が得られます:
test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
以上が unittest
モジュールでよく使われる機能で、ほとんどのテストではこれだけでも十分です。基礎となる概念や全ての機能については以降の章を参照してください。
25.3.2. コマンドラインインターフェイス¶
ユニットテストモジュールはコマンドラインから使うこともできます。モジュール、クラス、もしくは、特定のテストメソッドで定義されたテストを実行します:
python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method
引数として渡す事ができるのは、テストが定義されたモジュール名、もしくはクラス、メソッドのフルパス名です。
テスト実行時に (より冗長な) 詳細を表示するには -v フラグを渡します:
python -m unittest -v test_module
コマンドラインプションの一覧を表示するには以下のコマンドを実行します:
python -m unittest -h
バージョン 2.7 で変更: 以前のバージョンでは、個々のテストメソッドしか実行することができず、モジュール単位やクラス単位で実行することは不可能でした。
25.3.2.1. コマンドラインオプション¶
unittest には以下のコマンドラインオプションがあります:
-
-b
,
--buffer
¶
標準出力と標準エラーのストリームをテスト実行の間バッファリングします。テストが成功している間は結果の出力は破棄されます。テストが失敗、もしくはエラーが発生した場合には、結果にエラーメッセージが追加されたうえで通常通り出力されます。
-
-c
,
--catch
¶
Control-C
を実行中のテストが終了するまで遅延させ、そこまでの結果を出力します。二回目のControl-C
は、通常通りKeyboardInterrupt
の例外を発生させます。この機能の仕組みについては、シグナルハンドリング を参照してください。
-
-f
,
--failfast
¶
初回のエラーもしくは失敗の時にテストを停止します。
バージョン 2.7 で追加: コマンドラインオプションの -b
、-c
、-f
が追加されました。
このコマンドラインは、プロジェクト内の全テストを実行したり、サブセットのみを実行したりといった、テストディスカバリを使用することもできます。
25.3.3. テストディスカバリ¶
バージョン 2.7 で追加.
unittest はシンプルなテストディスカバリをサポートします。このテストディスカバリに対応するために、テストが定義された全ファイルは modules もしくは packages としてプロジェクトの最上位のディスカバリでインポート可能である必要があります (つまり、これらのファイルは identifiers として有効である必要があるということです)。
テストディスカバリは TestLoader.discover()
で実装されています。しかし、コマンドラインからも使う事ができます。コマンドラインからは以下のように使用します:
cd project_directory
python -m unittest discover
discover
サブコマンドには以下のオプションがあります:
-
-v
,
--verbose
¶
詳細な出力
-
-s
,
--start-directory
directory
¶ ディスカバリを開始するディレクトリ (デフォルトは
.
)
-
-p
,
--pattern
pattern
¶ テストファイル名を識別するパターン (デフォルトは
test*.py
)
-
-t
,
--top-level-directory
directory
¶ プロジェクトの最上位のディスカバリのディレクトリ (デフォルトは開始のディレクトリ)
-s
、 -p
、および -t
の各オプションは、この順番で指定すれば位置固定の引数として指定する事ができます。以下の二つのコマンドは同じ結果になります:
python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"
パスを渡すのはもちろんのこと、例えば myproject.subpackage.test
のように、パッケージ名をスタートディレクトリとして渡すことができます。指定したパッケージがインポートされ、そのパッケージのファイルシステム上のパスがスタートディレクトリになります。
ご用心
テストディスカバリはテストをインポートすることで読み込みます。テストディスカバリは一度、指定した開始ディレクトリから全テストファイルを探索し、そのファイルのパスをパッケージ名に変換してインポートします。例えば、 foo/bar/baz.py
は foo.bar.baz
としてインポートされます。
もしパッケージをグローバルにインストールしていて、インストールしたのとは異なるパッケージのコピーをディスカバリしようとすると、間違った場所からインポートして しまうかもしれません。このような状態になるとテストディスカバリは警告を出し、停止します。
スタートディレクトリとしてディレクトリのパスではなくパッケージ名を指定した場合は、いずれかの場所からインポートされます。この場合は警告が表示されません。
テストモジュールとテストパッケージは、テストのロードとディスカバリをカスタマイズすることができます。そのために load_tests プロトコル を使用します。
25.3.4. テストの構成¶
ユニットテストの基礎となる構築要素は、 test case — セットアップを行い、正しさのチェックを行う、独立したシナリオ — です。 unittest
では、テストケースは unittest
モジュールの TestCase
クラスのインスタンスで表現します。テストケースを作成するには TestCase
のサブクラスを記述するか、または FunctionTestCase
を使用します。
TestCase
から派生したクラスのインスタンスは、このオブジェクトだけで単独のテストメソッドをお膳立て (set-up) と後片付け (tidy-up / clean-up) を伴って実行します。
TestCase
インスタンスは外部から完全に独立し、単独で実行する事も、他の任意のテストと一緒に実行する事もできなければなりません。
以下のように、 TestCase
のサブクラスは runTest()
をオーバライドし、必要なテスト処理を記述するだけで簡単に書くことができます:
import unittest
class DefaultWidgetSizeTestCase(unittest.TestCase):
def runTest(self):
widget = Widget('The widget')
self.assertEqual(widget.size(), (50, 50), 'incorrect default size')
何らかのテストを行う場合、ベースクラス TestCase
の assert*()
系メソッドのどれかを使用してください。テストが失敗すると例外が送出され、 unittest
はテスト結果を failure とします。その他の例外は error となります。これによりどこに問題があるかが判ります。 failure は間違った結果 (6 になるはずが 5 だった) で発生します。 error は間違ったコード (たとえば間違った関数呼び出しによる TypeError
) で発生します。
テストの実行方法については後述とし、まずはテストケースインスタンスの作成方法を示します。テストケースインスタンスは、以下のように引数なしでコンストラクタを呼び出して作成します。:
testCase = DefaultWidgetSizeTestCase()
さて、そのようなテストケースが夥しい数になってくると、セットアップ処理は繰り返しになりがちです。例えば上記のような Widget のテストが 100 種類も必要な場合、それぞれのサブクラスで Widget
オブジェクトを生成する処理を記述するのは好ましくありません。
ラッキーですね、私たちは初期化処理を setUp()
メソッドに追い出すことが出来ます。これでテスト実行時にテストフレームワークが、私たちのためにそれを自動的に実行してくれます:
import unittest
class SimpleWidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):
def runTest(self):
self.assertEqual(self.widget.size(), (50,50),
'incorrect default size')
class WidgetResizeTestCase(SimpleWidgetTestCase):
def runTest(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(), (100,150),
'wrong size after resize')
テスト中に setUp()
メソッドで例外が発生した場合、テストフレームワークはテストを実行することができないとみなし、 runTest()
を実行しません。
同様に、終了処理を tearDown()
メソッドに記述すると、 runTest()
メソッド終了後に実行されます:
import unittest
class SimpleWidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
self.widget = None
setUp()
が正常終了した場合、 runTest()
が成功したかどうかに関わらず tearDown()
が実行されます。
このような、テストを実行する環境を fixture と呼びます。
多数の小さなテストケース群が同じフィクスチャを使うことは良くあります。今の場合だと私たちは結局 SimpleWidgetTestCase
を派生して、 DefaultWidgetSizeTestCase
のような小さくて一つだけメソッドを持つクラスをたくさん作る必要があるところでした。これは退屈で時間のかかるものです。ですから JUnit と同じようなやり方で、 unittest
ではより簡単なメカニズムを用意しています:
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
self.widget = None
def test_default_size(self):
self.assertEqual(self.widget.size(), (50,50),
'incorrect default size')
def test_resize(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(), (100,150),
'wrong size after resize')
この例では runTest()
がありませんが、二つのテストメソッドを定義しています。このクラスのインスタンスは test_*()
メソッドのどちらか一方の実行と、 self.widget
の生成・解放を行います。この場合、テストケースインスタンス生成時に、コンストラクタの引数として実行するメソッド名を指定します:
defaultSizeTestCase = WidgetTestCase('test_default_size')
resizeTestCase = WidgetTestCase('test_resize')
unittest
では test suite
によってテストケースインスタンスをテスト対象の機能によってグループ化することができます。 test suite は、 unittest
の TestSuite
クラスで作成します。:
widgetTestSuite = unittest.TestSuite()
widgetTestSuite.addTest(WidgetTestCase('test_default_size'))
widgetTestSuite.addTest(WidgetTestCase('test_resize'))
各テストモジュールで、テストケースを組み込んだテストスイートオブジェクトを作成する呼び出し可能オブジェクトを用意しておくと、テストの実行や参照が容易になります:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_size'))
suite.addTest(WidgetTestCase('test_resize'))
return suite
または:
def suite():
tests = ['test_default_size', 'test_resize']
return unittest.TestSuite(map(WidgetTestCase, tests))
良く似た名前のテスト関数をたくさん定義した TestCase
のサブクラスを作るのはよくあるパターンなので、 unittest
ではテストスイートの作成と個々のテストをそれを追加するのを自動化するのに使える、 TestLoader
を用意しています。たとえば、:
suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)
は WidgetTestCase.test_default_size()
と WidgetTestCase.test_resize
を走らせるテストスイートを作成します。 TestLoader
は自動的にテストメソッドを識別するのに 'test'
というメソッド名の接頭辞を使います。
テストケースはテスト関数名を組み込みの文字列順に並べ替えた順序で実行されることに注意してください。
システム全体のテストを一度に行う場合など、テストスイートをさらにグループ化したい場合がよくあります。これは簡単です。 TestSuite
インスタンスには TestCase
インスタンスだけでなく TestSuite
も追加出来るからです:
suite1 = module1.TheTestSuite()
suite2 = module2.TheTestSuite()
alltests = unittest.TestSuite([suite1, suite2])
テストケースやテストスイートは (widget.py
のような) テスト対象のモジュール内にも記述できますが、テストは (test_widget.py
のような) 独立したモジュールに置いた方が以下のような点で有利です:
- テストモジュールだけをコマンドラインから実行することができる。
- テストコードと出荷するコードを分離する事ができる。
- テストコードを、テスト対象のコードに合わせて修正する誘惑に駆られにくい。
- テストコードは、テスト対象コードほど頻繁に更新されない。
- テストコードをより簡単にリファクタリングすることができる。
- Cで書いたモジュールのテストはどっちにしろ独立したモジュールとなるのだから、同様にしない理由もない
- テスト戦略を変更した場合でも、ソースコードを変更する必要がない。
25.3.5. 既存テストコードの再利用¶
既存のテストコードが有るとき、このテストを unittest
で実行しようとするために古いテスト関数をいちいち TestCase
クラスのサブクラスに変換するのは大変です。
このような場合は、 unittest
では TestCase
のサブクラスである FunctionTestCase
クラスを使い、既存のテスト関数をラップします。初期設定と終了処理も行なえます。
以下のテストコードがあった場合:
def testSomething():
something = makeSomething()
assert something.name is not None
# ...
等価なテストケースインスタンスは次のように作成できます:
testcase = unittest.FunctionTestCase(testSomething)
テストケースの操作の部品として呼び出されるべき追加的なお膳立てと後片付けメソッドを手持ちなのであれば、このようにして提供出来ます:
testcase = unittest.FunctionTestCase(testSomething,
setUp=makeSomethingDB,
tearDown=deleteSomethingDB)
既存のテストスイートからの移行を容易にするため、 unittest
は AssertionError
の送出でテストの失敗を示すような書き方もサポートしています。しかしながら、 TestCase.fail*()
および TestCase.assert*()
メソッドを使って明確に書くことが推奨されています。 unittest
の将来のバージョンでは、 AssertionError
は別の目的に使用される可能性があります。
注釈
FunctionTestCase
を使って既存のテストを unittest
ベースのテスト体系に変換することができますが、この方法は推奨されません。時間を掛けて TestCase
のサブクラスに書き直した方が将来的なテストのリファクタリングが限りなく易しくなります。
既存のテストが doctest
を使って書かれている場合もあるでしょう。その場合、 doctest
は DocTestSuite
クラスを提供します。このクラスは、既存の doctest
ベースのテストから、自動的に unittest.TestSuite
のインスタンスを作成します。
25.3.6. テストのスキップと意図的な失敗¶
バージョン 2.7 で追加.
unittest は特定のテストメソッドやテストクラス全体をスキップする仕組みを備えています。さらに、この機能はテスト結果を「意図的な失敗 (expected failure)」とすることができ、テストが失敗しても TestResult
の失敗数にはカウントされなくなります。
テストをスキップするには、単に skip()
デコレータ(decorator) を使用するか、条件を表現するための skip()
に類するデコレータを使用します。
スキップは以下のようになります:
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass
このサンプルを詳細モードで実行すると以下のように出力されます:
test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'
test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'
----------------------------------------------------------------------
Ran 3 tests in 0.005s
OK (skipped=3)
テストクラスは以下のようにメソッドをスキップすることができます:
@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
def test_not_run(self):
pass
TestCase.setUp()
もスキップすることができます。この機能はセットアップの対象のリソースが使用不可能な状態の時に便利です。
意図的な失敗の機能を使用するには、 expectedFailure()
デコレータを使います。
class ExpectedFailureTestCase(unittest.TestCase):
@unittest.expectedFailure
def test_fail(self):
self.assertEqual(1, 0, "broken")
独自のスキップ用のデコレータも簡単に作成することができます。 そのためには、独自のデコレータのスキップしたい時点で skip()
を呼び出します。 以下のデコレータはオブジェクトに指定した属性が無い場合にテストをスキップします:
def skipUnlessHasattr(obj, attr):
if hasattr(obj, attr):
return lambda func: func
return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))
以下のデコレータはテストのスキップと意図的な失敗を実装しています:
-
unittest.
skip
(reason)¶ デコレートしたテストを無条件でスキップします。reason にはテストをスキップした理由を記載します。
-
unittest.
skipIf
(condition, reason)¶ condition が真の場合に、デコレートしたテストをスキップします。
-
unittest.
skipUnless
(condition, reason)¶ condition が偽の場合に、デコレートしたテストをスキップします。
-
unittest.
expectedFailure
()¶ テストの失敗が意図的であることを表します。該当のテストが失敗しても、そのテストは失敗にカウントされません。
-
exception
unittest.
SkipTest
(reason)¶ この例外はテストをスキップするために送出されます。
ふつうはこれを直接送出する代わりに
TestCase.skipTest()
やスキッピングデコレータの一つを使用出来ます。
スキップしたテストの前後では、 setUp()
および tearDown()
は実行されません。同様に、スキップしたテストクラスの前後では、 setUpClass()
および tearDownClass()
は実行されません。
25.3.7. クラスと関数¶
この節では、 unittest
モジュールのAPIの詳細について説明します。
25.3.7.1. テストクラス¶
-
class
unittest.
TestCase
(methodName='runTest')¶ TestCase
クラスのインスタンスは、unittest
の世界におけるテストの最小実行単位を示します。このクラスをベースクラスとして使用し、必要なテストを具象サブクラスに実装します。TestCase
クラスでは、テストランナーがテストを実行するためのインターフェースと、各種のチェックやテスト失敗をレポートするためのメソッドを実装しています。それぞれの
TestCase
クラスのインスタンスはただ一つのテストメソッド、 methodName という名のメソッドを実行します。既に次のような例を扱ったことを憶えているでしょうか。:def suite(): suite = unittest.TestSuite() suite.addTest(WidgetTestCase('test_default_size')) suite.addTest(WidgetTestCase('test_resize')) return suite
ここでは、それぞれが一つずつのテストを実行するような
WidgetTestCase
の二つのインスタンスを作成しています。methodName のデフォルトは
runTest()
です。TestCase
のインスタンスのメソッドは3種類のグループに分けられます。 1つ目のグループのメソッドはテストの実行で使用します。2つ目のグループのメソッドは条件の確認および失敗のレポートといったテストの実装で使用されます。3つ目のグループである問い合わせ用のメソッドはテスト自身の情報を収集するために使用します。はじめのグループ (テスト実行) に含まれるメソッドは以下の通りです:
-
setUp
()¶ テストフィクスチャの準備のために呼び出されるメソッドです。テストメソッドの直前に呼び出されます。このメソッドを実行中に
AssertionError
やSkipTest
以外の例外が発生した場合、テストの失敗ではなくエラーとされます。デフォルトの実装では何も行いません。
-
tearDown
()¶ テストメソッドが実行され、結果が記録された直後に呼び出されるメソッドです。このメソッドはテストメソッドで例外が投げられても呼び出されます。そのため、サブクラスでこのメソッドを実装する場合は、内部状態を確認することが必要になるでしょう。このメソッドで
AssertionError
やSkipTest
以外の例外が発生した場合、テストの失敗とは別のエラーとみなされます (従って報告されるエラーの総数は増えます)。このメソッドは、テストの結果に関わらずsetUp()
が成功した場合にのみ呼ばれます。デフォルトの実装では何も行いません。
-
setUpClass
()¶ クラス内に定義されたテストが実行される前に呼び出されるクラスメソッドです。
setUpClass
はクラスを唯一の引数として取り、classmethod()
でデコレートされている必要があります:@classmethod def setUpClass(cls): ...
詳しくは クラスとモジュールのフィクスチャ を参照してください。
バージョン 2.7 で追加.
-
tearDownClass
()¶ クラス内に定義されたテストが実行された後に呼び出されるクラスメソッドです。
tearDownClass
はクラスを唯一の引数として取り、classmethod()
でデコレートされている必要があります:@classmethod def tearDownClass(cls): ...
詳しくは クラスとモジュールのフィクスチャ を参照してください。
バージョン 2.7 で追加.
-
run
(result=None)¶ テストを実行し、テスト結果を result に指定されたテスト結果オブジェクトに渡します。 result 省略されるか
None
か渡された場合、一時的な結果オブジェクトを (defaultTestCase()
メソッドを呼んで) 生成して、それを使用します。結果オブジェクトはrun()
の呼び出し元には返されません。このメソッドは、単に
TestCase
インスタンスを呼び出した場合と同様に振る舞います。
-
skipTest
(reason)¶ 現在のテストでテストクラスもしくは
setUp()
をスキップする場合に呼ばれます。詳細については、 テストのスキップと意図的な失敗 を参照してください。バージョン 2.7 で追加.
-
debug
()¶ テスト結果を収集せずにテストを実行します。例外が呼び出し元に通知されます。また、テストをデバッガで実行することができます。
TestCase
クラスは失敗の検査と報告を行う多くのメソッドを提供しています。以下の表は最も一般的に使われるメソッドを列挙しています (より多くのアサートメソッドについては表の下を見てください):Method 確認事項 初出 assertEqual(a, b)
a == b
assertNotEqual(a, b)
a != b
assertTrue(x)
bool(x) is True
assertFalse(x)
bool(x) is False
assertIs(a, b)
a is b
2.7 assertIsNot(a, b)
a is not b
2.7 assertIsNone(x)
x is None
2.7 assertIsNotNone(x)
x is not None
2.7 assertIn(a, b)
a in b
2.7 assertNotIn(a, b)
a not in b
2.7 assertIsInstance(a, b)
isinstance(a, b)
2.7 assertNotIsInstance(a, b)
not isinstance(a, b)
2.7 (
assertRaises()
とassertRaisesRegexp()
を除く) すべてのアサートメソッドには msg 引数を指定することができ、テストの失敗時のエラーメッセージで使用されます (longMessage
も参照してください)。-
assertEqual
(first, second, msg=None)¶ first と second が等しいことをテストします。両者が比較出来ない場合は、テストが失敗します。
さらに、 first と second が厳密に同じ型であり、その型が、list, tuple, dict, set, frozenset もしくは unicode のいずれか、または
addTypeEqualityFunc()
で比較関数が登録されている型の場合には、より有益なデフォルトのエラーメッセージを生成するために、その型特有の比較関数が呼ばれます (list of type-specific methods も参照してください)。バージョン 2.7 で変更: 自動で型特有の比較関数が呼ばれるようになりました。
-
assertNotEqual
(first, second, msg=None)¶ first と second が等しくないことをテストします。両者が比較出来ない場合は、テストが失敗します。
-
assertTrue
(expr, msg=None)¶ -
assertFalse
(expr, msg=None)¶ expr が真 (偽) であることをテストします。
このメソッドは、
bool(expr) is True
と等価であり、expr is True
と等価ではないことに注意が必要です (後者のためには、assertIs(expr, True)
が用意されています)。また、専用のメソッドが使用できる場合には、そちらを使用してください (例えばassertTrue(a == b)
の代わりにassertEqual(a, b)
を使用してください)。そうすることにより、テスト失敗時のエラーメッセージを詳細に表示することができます。
-
assertIs
(first, second, msg=None)¶ -
assertIsNot
(first, second, msg=None)¶ first と second が同じオブジェクトであること (そうでないこと) をテストします。
バージョン 2.7 で追加.
-
assertIsNone
(expr, msg=None)¶ -
assertIsNotNone
(expr, msg=None)¶ expr が
None
であること (および、そうでないこと) をテストします。バージョン 2.7 で追加.
-
assertIn
(first, second, msg=None)¶ -
assertNotIn
(first, second, msg=None)¶ first が second に含まれること (そうでないこと) をテストします。
バージョン 2.7 で追加.
-
assertIsInstance
(obj, cls, msg=None)¶ -
assertNotIsInstance
(obj, cls, msg=None)¶ obj が cls のインスタンスであること (あるいはそうでないこと) をテストします (この cls は、
isinstance()
が扱うことのできる、クラスもしくはクラスのタプルである必要があります)。正確な型をチェックするためには、assertIs(type(obj), cls)
を使用してください。バージョン 2.7 で追加.
例外と例外発生時の警告を確認するために以下のメソッドを使用することができます:
Method 確認事項 初出 assertRaises(exc, fun, *args, **kwds)
fun(*args, **kwds)
raises excassertRaisesRegexp(exc, r, fun, *args, **kwds)
fun(*args, **kwds)
が exc を raise してメッセージが正規表現 r とマッチすること2.7 -
assertRaises
(exception, callable, *args, **kwds)¶ -
assertRaises
(exception) callable を呼び出した時に例外が発生することをテストします。
assertRaises()
で指定した位置パラメータとキーワードパラメータを該当メソッドに渡します。 exception が投げられた場合にテストが成功します。また、他の例外が投げられた場合はエラー、例外が投げられなかった場合は失敗になります。複数の例外をキャッチする場合には、例外クラスのタプルを exception に指定してください。exception 引数のみが渡された場合には、コンテキストマネージャが返されます。これにより関数名を渡す形式ではなく、インラインでテスト対象のコードを書くことができます。
with self.assertRaises(SomeException): do_something()
このコンテキストマネージャは
exception
で指定されたオブジェクトを格納します。これにより、例外発生時の詳細な確認をおこなうことができます:with self.assertRaises(SomeException) as cm: do_something() the_exception = cm.exception self.assertEqual(the_exception.error_code, 3)
バージョン 2.7 で変更:
assertRaises()
がコンテキストマネージャとして使えるようになりました。
-
assertRaisesRegexp
(exception, regexp, callable, *args, **kwds)¶ -
assertRaisesRegexp
(exception, regexp) assertRaises()
と同等ですが、例外の文字列表現が regexp にマッチすることもテストします。 regexp は正規表現オブジェクトか、re.search()
が扱える正規表現が書かれた文字列である必要があります。例えば以下のようになります:self.assertRaisesRegexp(ValueError, "invalid literal for.*XYZ'$", int, 'XYZ')
もしくは:
with self.assertRaisesRegexp(ValueError, 'literal'): int('XYZ')
バージョン 2.7 で追加.
さらに特有の確認を行うために以下のメソッドが用意されています:
Method 確認事項 初出 assertAlmostEqual(a, b)
round(a-b, 7) == 0
assertNotAlmostEqual(a, b)
round(a-b, 7) != 0
assertGreater(a, b)
a > b
2.7 assertGreaterEqual(a, b)
a >= b
2.7 assertLess(a, b)
a < b
2.7 assertLessEqual(a, b)
a <= b
2.7 assertRegexpMatches(s, r)
r.search(s)
2.7 assertNotRegexpMatches(s, r)
not r.search(s)
2.7 assertItemsEqual(a, b)
意味的に sorted(a) == sorted(b)
ですが、ハッシュ不能オブジェクトでも動作2.7 assertDictContainsSubset(a, b)
a の全てのキー/値ペアが b に存在すること 2.7 -
assertAlmostEqual
(first, second, places=7, msg=None, delta=None)¶ -
assertNotAlmostEqual
(first, second, places=7, msg=None, delta=None)¶ first と second が近似的に等しい (等しくない) ことをテストします。この比較は、places (デフォルト7) で指定した小数位で丸めた差分をゼロと比べることでおこないます。これらのメソッドは、 (
round()
と同様に) 小数位 を指定するのであって、有効桁数 を指定するのではないことに注意してください。places の代わりに delta が渡された場合には、first と second の差分が delta 以下 (以上) であることをテストします。
delta と places の両方が指定された場合は
TypeError
が投げられます。バージョン 2.7 で変更:
assertAlmostEqual()
は、オブジェクトが等しい場合には自動で近似的に等しいとみなすようになりました。assertNotAlmostEqual()
は、オブジェクトが等しい場合には自動的に失敗するようになりました。 delta 引数が追加されました。
-
assertGreater
(first, second, msg=None)¶ -
assertGreaterEqual
(first, second, msg=None)¶ -
assertLess
(first, second, msg=None)¶ -
assertLessEqual
(first, second, msg=None)¶ first が second と比べて、メソッド名に対応して >, >=, < もしくは <= であることをテストします。そうでない場合はテストが失敗します:
>>> self.assertGreaterEqual(3, 4) AssertionError: "3" unexpectedly not greater than or equal to "4"
バージョン 2.7 で追加.
-
assertRegexpMatches
(text, regexp, msg=None)¶ regexp の検索が text とマッチすることをテストします。テスト失敗時には、エラーメッセージにパターンと text が表示されます (もしくは、パターンと意図しないかたちでマッチした text の一部が表示されます)。 regexp は正規表現オブジェクトか、
re.search()
が扱える正規表現が書かれた文字列である必要があります。バージョン 2.7 で追加.
-
assertNotRegexpMatches
(text, regexp, msg=None)¶ regexp の検索が text とマッチしないことをテストします。テスト失敗時には、エラーメッセージにマッチしたパターンと text が表示されます。 regexp は正規表現オブジェクトか、
re.search()
が扱える正規表現が書かれた文字列である必要があります。バージョン 2.7 で追加.
-
assertItemsEqual
(actual, expected, msg=None)¶ シーケンス expected が actual と同じ要素を含んでいることをテストします。要素の順序はテスト結果に影響しません。要素が含まれていない場合には、シーケンスの差分がエラーメッセージとして表示されます。
actual と expected の比較では、重複した要素は無視 されません 。両者に同じ数の要素が含まれていることを検証します。このメソッドは
assertEqual(sorted(expected), sorted(actual))
と同等に振る舞うことに加えて、ハッシュ化できないオブジェクトのシーケンスでも動作します。Python 3 ではこのメソッドは
assertCountEqual
と名付けられています。バージョン 2.7 で追加.
-
assertDictContainsSubset
(expected, actual, msg=None)¶ 辞書 actual のキー/値ペアが expected のスーパーセットになっているかどうかをテストします。そうなっていない場合には、欠けたキーと不一致の値を一覧するエラーメッセージが生成されます。
バージョン 2.7 で追加.
バージョン 3.2 で撤廃.
assertEqual()
メソッドは、同じ型のオブジェクトの等価性確認のために、型ごとに特有のメソッドにディスパッチします。これらのメソッドは、ほとんどの組み込み型用のメソッドは既に実装されています。さらに、addTypeEqualityFunc()
を使う事で新たなメソッドを登録することができます:-
addTypeEqualityFunc
(typeobj, function)¶ assertEqual()
で呼び出される型特有のメソッドを登録します。登録するメソッドは、比較する2つのオブジェクトの型が厳密に typeobj と同じ (サブクラスでもいけません) の場合に等価性を確認します。 function はassertEqual()
と同様に、2つの位置固定引数と、3番目に msg=None のキーワード引数を取れる必要があります。このメソッドは、始めの2つに指定したパラメータ間の差分を検出した時にself.failureException(msg)
の例外を投げる必要があります。この例外を投げる際は、出来る限り、エラーの内容が分かる有用な情報と差分の詳細をエラーメッセージに含めてください。バージョン 2.7 で追加.
assertEqual()
が自動的に呼び出す型特有のメソッドの概要を以下の表示に記載しています。これらのメソッドは通常は直接呼び出す必要がないことに注意が必要です。Method 比較の対象 初出 assertMultiLineEqual(a, b)
文字列 2.7 assertSequenceEqual(a, b)
シーケンス 2.7 assertListEqual(a, b)
リスト 2.7 assertTupleEqual(a, b)
タプル 2.7 assertSetEqual(a, b)
set または frozenset 2.7 assertDictEqual(a, b)
辞書 2.7 -
assertMultiLineEqual
(first, second, msg=None)¶ Test that the multiline string first is equal to the string second. When not equal a diff of the two strings highlighting the differences will be included in the error message. This method is used by default when comparing Unicode strings with
assertEqual()
.バージョン 2.7 で追加.
-
assertSequenceEqual
(seq1, seq2, msg=None, seq_type=None)¶ 2つのシーケンスが等しいことをテストします。 seq_type が指定された場合、 seq1 と seq2 が seq_type のインスタンスで無い場合にはテストが失敗します。シーケンスどうしが異なる場合には、両者の差分がエラーメッセージに表示されます。
このメソッドは直接
assertEqual()
からは呼ばれませんが、assertListEqual()
とassertTupleEqual()
の実装で使われています。バージョン 2.7 で追加.
-
assertListEqual
(list1, list2, msg=None)¶ -
assertTupleEqual
(tuple1, tuple2, msg=None)¶ 2つのリストまたはタプルが等しいかどうかをテストします。等しくない場合には、両者の差分を表示します。2つのパラメータの型が異なる場合にはテストがエラーになります。このメソッドは、デフォルトで、
assertEqual()
が list または tuple を比較するときに自動的に使用します。バージョン 2.7 で追加.
-
assertSetEqual
(set1, set2, msg=None)¶ 2つのセットが等しいかどうかをテストします。等しくない場合には、両者の差分を表示します。このメソッドは、デフォルトで、
assertEqual()
が set もしくは frozenset を比較するときに自動的に使用します。set1 or set2 のいずれかに
set.difference()
メソッドが無い場合にはテストは失敗します。バージョン 2.7 で追加.
-
assertDictEqual
(expected, actual, msg=None)¶ 2つの辞書が等しいかどうかをテストします。等しくない場合には、両者の差分を表示します。このメソッドは、デフォルトで、
assertEqual()
が dict を比較するときに自動的に使用します。バージョン 2.7 で追加.
最後に、
TestCase
の残りのメソッドと属性を紹介します:-
fail
(msg=None)¶ 無条件にテストを失敗させます。エラーメッセージの表示に、msg または
None
が使われます。
-
failureException
¶ test()
メソッドが送出する例外を指定するクラス属性です。例えばテストフレームワークで追加情報を付した特殊な例外が必要になる場合、この例外のサブクラスとして作成します。この属性の初期値はAssertionError
です。
-
longMessage
¶ この属性に
True
が設定された場合、 assert methods で指定したすべての明示的な失敗メッセージが、通常の失敗メッセージに追加されます。通常の失敗メッセージには、オブジェクトに関する有用な情報が含まれています。例えば、 assertEqual は異なるオブジェクトの repr を表示します。この属性をTrue
にすることで、カスタマイズしたエラーメッセージを通常のメッセージに追加することができます。この属性はデフォルトで
False
になっていて、カスタムメッセージが渡されても表示しないようになっています。アサートメソッドを呼び出す前に、インスタンス属性として
True
またはFalse
を指定することで、この設定をオーバーライドすることができます。バージョン 2.7 で追加.
-
maxDiff
¶ この属性は、アサーションメソッドが失敗をレポートする時に表示する差分の長さをコントロールします。デフォルトは 80*8 文字です。この属性が影響するメソッドは、
assertSequenceEqual()
(およびこのメソッドに委譲するシーケンス比較メソッド)、assertDictEqual()
とassertMultiLineEqual()
です。maxDiff
をNone
に設定すると差分表示の上限がなくなります。バージョン 2.7 で追加.
テストフレームワークは、テスト情報を収集するために以下のメソッドを使用します:
-
defaultTestResult
()¶ このテストケースクラスで使われるテスト結果クラスのインスタンスを (もし
run()
メソッドに他の結果インスタンスが提供されないならば) 返します。TestCase
インスタンスに対しては、いつもTestResult
のインスタンスですので、TestCase
のサブクラスでは必要に応じてこのメソッドをオーバライドしてください。
-
id
()¶ テストケースを特定する文字列を返します。通常、id はモジュール名・クラス名を含む、テストメソッドのフルネームを指定します。
-
shortDescription
()¶ テストの説明を一行分、または説明がない場合には
None
を返します。デフォルトでは、テストメソッドの docstring の先頭の一行、またはNone
を返します。
-
addCleanup
(function, *args, **kwargs)¶ tearDown()
の後に呼び出される関数を追加します。この関数はリソースのクリーンアップのために使用します。追加された関数は、追加された順と逆の順番で呼び出されます (LIFO)。addCleanup()
に渡された引数とキーワード引数が追加された関数にも渡されます。setUp()
が失敗した場合、つまりtearDown()
が呼ばれなかった場合でも、追加されたクリーンアップ関数は呼び出されます。バージョン 2.7 で追加.
-
doCleanups
()¶ このメソッドは、
tearDown()
の後、もしくは、setUp()
が例外を投げた場合はsetUp()
の後に、無条件で呼ばれます。このメソッドは、
addCleanup()
で追加された関数を呼び出す責務を担います。もし、クリーンアップ関数をtearDown()
より前に呼び出す必要がある場合には、doCleanups()
を明示的に呼び出してください。doCleanups()
は、どこで呼び出されても、クリーンアップ関数をスタックから削除して実行します。バージョン 2.7 で追加.
-
-
class
unittest.
FunctionTestCase
(testFunc, setUp=None, tearDown=None, description=None)¶ このクラスでは
TestCase
インターフェースの内、テストランナーがテストを実行するためのインターフェースだけを実装しており、テスト結果のチェックやレポートに関するメソッドは実装していません。既存のテストコードをunittest
によるテストフレームワークに組み込むために使用します。
25.3.7.1.1. 廃止予定のエイリアス¶
歴史的な経緯で、 TestCase
のいくつかのエイリアスは廃止予定となりました。以下の表に、廃止予定のエイリアスをまとめます:
メソッド名 廃止予定のエリアス assertEqual()
failUnlessEqual, assertEquals assertNotEqual()
failIfEqual assertTrue()
failUnless, assert_ assertFalse()
failIf assertRaises()
failUnlessRaises assertAlmostEqual()
failUnlessAlmostEqual assertNotAlmostEqual()
failIfAlmostEqual バージョン 2.7 で撤廃: この表の「廃止予定」だったものが実際に廃止されました。
25.3.7.2. テストのグルーピング¶
-
class
unittest.
TestSuite
(tests=())¶ このクラスは、個々のテストケースやテストスイートの集約を示します。通常のテストケースと同じようにテストランナーで実行するためのインタフェースを備えています。
TestSuite
インスタンスを実行することはスイートの繰り返しを使って個々のテストを実行することと同じです。引数 tests が指定された場合、それはテストケースに亘る繰り返し可能オブジェクトまたは内部でスイートを組み立てるための他のテストスイートでなければなりません。後からテストケースやスイートをコレクションに付け加えるためのメソッドも提供されています。
TestSuite
はTestCase
オブジェクトのように振る舞います。違いは、スイートにはテストを実装しない点にあります。代わりに、テストをまとめてグループ化して、同時に実行します。TestSuite
のインスタンスにテスト追加するためのメソッドが用意されています:-
addTests
(tests)¶ イテラブル tests に含まれる全ての
TestCase
又はTestSuite
のインスタンスをスイートに追加します。このメソッドは tests 上のイテレーションをしながらそれぞれの要素に
addTest()
を呼び出すのと等価です。
TestSuite
クラスはTestCase
と以下のメソッドを共有します:-
run
(result)¶ スイート内のテストを実行し、結果を result で指定した結果オブジェクトに収集します。
TestCase.run()
と異なり、TestSuite.run()
では必ず結果オブジェクトを指定する必要があります。
-
debug
()¶ このスイートに関連づけられたテストを結果を収集せずに実行します。これによりテストで送出された例外は呼び出し元に伝わるようになり、デバッガの下でのテスト実行をサポートできるようになります。
-
countTestCases
()¶ このテストオブジェクトによって表現されるテストの数を返します。これには個別のテストと下位のスイートも含まれます。
-
__iter__
()¶ TestSuite
でグループ化されたテストはイテレータでアクセスできます。サブクラスは__iter__()
をオーバーライドすることで、テストへのアクセスを定義します。1つのメソッド内でこのメソッドは何度も呼ばれる可能性があることに注意してください (例えば、テスト数のカウントと等価性の比較)。そのため、イテレーションを繰り返しても同じテストを返すように実装してください。バージョン 2.7 で変更: 以前のバージョンでは
TestSuite
はイテレータではなく、直接テストにアクセスしていました。そのため、__iter__()
をオーバーラードしてもテストにアクセスできませんでした。
通常、
TestSuite
のrun()
メソッドはTestRunner
が起動するため、ユーザが直接実行する必要はありません。-
25.3.7.3. テストのロードと起動¶
-
class
unittest.
TestLoader
¶ TestLoader
クラスはクラスとモジュールからテストスイートを生成します。通常、このクラスのインスタンスを明示的に生成する必要はありません。unittest
モジュールのunittest.defaultTestLoader
を共用インスタンスとして使用することができます。 しかし、このクラスのサブクラスやインスタンスで、属性をカスタマイズすることができます。TestLoader
のオブジェクトには以下のメソッドがあります:-
loadTestsFromModule
(module)¶ 指定したモジュールに含まれる全テストケースのスイートを返します。このメソッドは module 内の
TestCase
派生クラスを検索し、見つかったクラスのテストメソッドごとにクラスのインスタンスを作成します。注釈
TestCase
クラスを基底クラスとしてクラス階層を構築すると fixture や補助的な関数をうまく共用することができますが、基底クラスに直接インスタンス化できないテストメソッドがあると、このloadTestsFromModule()
を使うことができません。この場合でも、 fixture が全て別々で定義がサブクラスにある場合は使用することができます。モジュールが
load_tests
関数を用意している場合、この関数がテストのロードに使われます。これによりテストのロードをカスタマイズできます。これが load_tests プロトコル です。バージョン 2.7 で変更:
load_tests
のサポートが追加されました。
-
loadTestsFromName
(name, module=None)¶ 文字列で指定される全テストケースを含むスイートを返します。
name には "ドット修飾名" でモジュールかテストケースクラス、テストケースクラス内のメソッド、
TestSuite
インスタンスまたはTestCase
かTestSuite
のインスタンスを返す呼び出し可能オブジェクトを指定します。このチェックはここで挙げた順番に行なわれます。すなわち、候補テストケースクラス内のメソッドは「呼び出し可能オブジェクト」としてではなく「テストケースクラス内のメソッド」として拾い出されます。例えば
SampleTests
モジュールにTestCase
から派生したSampleTestCase
クラスがあり、SampleTestCase
にはテストメソッドtest_one()
・test_two()
・test_three()
があるとします。この場合、 name に'SampleTests.SampleTestCase'
と指定すると、SampleTestCase
の三つのテストメソッドを実行するテストスイートが作成されます。'SampleTests.SampleTestCase.test_two'
と指定すれば、test_two()
だけを実行するテストスイートが作成されます。インポートされていないモジュールやパッケージ名を含んだ名前を指定した場合は自動的にインポートされます。また、module を指定した場合、module 内の name を取得します。
-
loadTestsFromNames
(names, module=None)¶ loadTestsFromName()
と同じですが、名前を一つだけ指定するのではなく、複数の名前のシーケンスを指定する事ができます。戻り値は names 中の名前で指定されるテスト全てを含むテストスイートです。
-
getTestCaseNames
(testCaseClass)¶ testCaseClass 中の全てのメソッド名を含むソート済みシーケンスを返します。 testCaseClass は
TestCase
のサブクラスでなければなりません。
-
discover
(start_dir, pattern='test*.py', top_level_dir=None)¶ 指定された開始ディレクトリからサブディレクトリに再帰することですべてのテストモジュールを検索し、それらを含む TestSuite オブジェクトを返します。pattern にマッチしたテストファイルだけがロードの対象になります。 (シェルスタイルのパターンマッチングが使われます)。その中で、インポート可能なもジュール (つまり Python の識別子として有効であるということです) がロードされます。
すべてのテストモジュールはプロジェクトのトップレベルからインポート可能である必要があります。開始ディレクトリがトップレベルディレクトリでない場合は、トップレベルディレクトリが分離できなくてはいけません。
例えば、シンタックスエラーなどで、モジュールのインポートに失敗した場合、エラーが記録され、ディスカバリ自体は続けられます。
テストパッケージ名 (
__init__.py
の置かれたディレクトリ名) がパターンにマッチした場合、load_tests
関数がチェックされます。この関数が存在している場合、この関数に loader, tests, pattern が渡され呼び出されます。load_tests が存在して、ディスカバリがパッケージ内を再帰的な検索を続けている途中で ない 場合、
load_tests
はそのパッケージ内の全てのテストをロードする責務を担います。意図的にパターンはローダの属性として保持されないようになっています。それにより、パッケージが自分自身のディスカバリを続ける事ができます。top_level_dir は保持されるため、
load_tests
はこの引数をloader.discover()
に渡す必要はありません。start_dir はドット付のモジュール名でもディレクトリでも構いません。
バージョン 2.7 で追加.
以下の属性は、サブクラス化またはインスタンスの属性値を変更して
TestLoader
をカスタマイズする場合に使用します:-
testMethodPrefix
¶ テストメソッドの名前と判断されるメソッド名の接頭語を示す文字列。デフォルト値は
'test'
です。この値は
getTestCaseNames()
と全てのloadTestsFrom*()
メソッドに影響を与えます。
-
sortTestMethodsUsing
¶ getTestCaseNames()
および全てのloadTestsFrom*()
メソッドでメソッド名をソートする際に使用する比較関数。デフォルト値は組み込み関数cmp()
です。ソートを行なわないようにこの属性にNone
を指定することもできます。
-
-
class
unittest.
TestResult
¶ このクラスはどのテストが成功しどのテストが失敗したかという情報を収集するのに使います。
TestResult
は、複数のテスト結果を記録します。TestCase
クラスとTestSuite
クラスのテスト結果を正しく記録しますので、テスト開発者が独自にテスト結果を管理する処理を開発する必要はありません。unittest
を利用したテストフレームワークでは、TestRunner.run()
が返すTestResult
インスタンスを参照し、テスト結果をレポートします。TestResult
インスタンスの以下の属性は、テストの実行結果を検査する際に使用することができます:-
errors
¶ TestCase
と例外のトレースバック情報をフォーマットした文字列の 2 要素タプルからなるリスト。それぞれのタプルは予想外の例外を送出したテストに対応します。バージョン 2.2 で変更:
sys.exc_info()
の結果ではなく、フォーマットしたトレースバックを保存するようにしました。
-
failures
¶ TestCase
と例外のトレースバック情報をフォーマットした文字列の 2 要素タプルからなるリスト。それぞれのタプルはTestCase.assert*()
メソッドを使って見つけ出した失敗に対応します。バージョン 2.2 で変更:
sys.exc_info()
の結果ではなく、フォーマットしたトレースバックを保存するようにしました。
-
testsRun
¶ これまでに実行したテストの総数です。
-
buffer
¶ True
が設定されると、sys.stdout
とsys.stderr
は、startTest()
からstopTest()
が呼ばれるまでの間バッファリングされます。実際に、結果がsys.stdout
とsys.stderr
に出力されるのは、テストが失敗するかエラーが発生した時になります。表示の際には、全ての失敗 / エラーメッセージが表示されます。バージョン 2.7 で追加.
-
wasSuccessful
()¶ これまでに実行したテストが全て成功していれば
True
を、それ以外ならFalse
を返します。
-
stop
()¶ このメソッドを呼び出して
TestResult
のshouldStop
属性にTrue
をセットすることで、実行中のテストは中断しなければならないというシグナルを送ることができます。TestRunner
オブジェクトはこのフラグを尊重してそれ以上のテストを実行することなく復帰しなければなりません。たとえばこの機能は、ユーザのキーボード割り込みを受け取って
TextTestRunner
クラスがテストフレームワークを停止させるのに使えます。TestRunner
の実装を提供する対話的なツールでも同じように使用することができます。
TestResult
クラスの以下のメソッドは内部データ管理用のメソッドですが、対話的にテスト結果をレポートするテストツールを開発する場合などにはサブクラスで拡張することができます。-
startTest
(test)¶ test を実行する直前に呼び出されます。
-
stopTest
(test)¶ test の実行直後に、テスト結果に関わらず呼び出されます。
-
startTestRun
()¶ 全てのテストが実行される前に一度だけ実行されます。
バージョン 2.7 で追加.
-
stopTestRun
()¶ 全てのテストが実行された後に一度だけ実行されます。
バージョン 2.7 で追加.
-
addError
(test, err)¶ テスト test 実行中に、想定外の例外が発生した場合に呼び出されます。 err は
sys.exc_info()
が返すタプル(type, value, traceback)
です。デフォルトの実装では、タプル、
(test, formatted_err)
をインスタンスのerrors
属性に追加します。ここで、 formatted_err は、 err から導出される、整形されたトレースバックです。
-
addFailure
(test, err)¶ テストケース test が失敗した場合に呼び出されます。 err は
sys.exc_info()
が返すタプル(type, value, traceback)
です。デフォルトの実装では、タプル、
(test, formatted_err)
をインスタンスのfailures
属性に追加します。ここで、 formatted_err は、 err から導出される、整形されたトレースバックです。
-
addSuccess
(test)¶ テストケース test が成功した場合に呼び出されます。
デフォルトの実装では何もしません。
-
addSkip
(test, reason)¶ test がスキップされた時に呼び出されます。reason はスキップの際に渡された理由の文字列です。
デフォルトの実装では、
(test, reason)
のタプルをインスタンスのskipped
属性に追加します。
-
addExpectedFailure
(test, err)¶ expectedFailure()
のデコレータでマークされた test が失敗した時に呼び出されます。デフォルトの実装では
(test, formatted_err)
のタプルをインスタンスのexpectedFailures
に追加します。ここで formatted_err は err から派生した整形されたトレースバックです。
-
addUnexpectedSuccess
(test)¶ expectedFailure()
のデコレータでマークされた test が成功した時に呼び出されます。デフォルトの実装ではテストをインスタンスの
unexpectedSuccesses
属性に追加します。
-
-
class
unittest.
TextTestResult
(stream, descriptions, verbosity)¶ TextTestRunner
に使用されるTestResult
の具象実装です。バージョン 2.7 で追加: このクラスは以前
_TextTestResult
という名前でした。以前の名前はエイリアスとして残っていますが非推奨です。
-
unittest.
defaultTestLoader
¶ TestLoader
のインスタンスで、共用することが目的です。TestLoader
をカスタマイズする必要がなければ、新しいTestLoader
オブジェクトを作らずにこのインスタンスを使用します。
-
class
unittest.
TextTestRunner
(stream=sys.stderr, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None)¶ 実行結果を標準エラーに出力する、単純なテストランナー。いくつかの設定項目がありますが、非常に単純です。グラフィカルなテスト実行アプリケーションでは、独自のテストランナーを作成してください。
-
_makeResult
()¶ このメソッドは
run()
で使われるTestResult
のインスタンスを返します。このメソッドは明示的に呼び出す必要はありませんが、サブクラスでTestResult
をカスタマイズすることができます。_makeResult()
は、TextTestRunner
のコンストラクタでresultclass
引数として渡されたクラスもしくはコーラブルオブジェクトをインスタンス化します。resultclass
が指定されていない場合には、デフォルトでTextTestResult
が使用されます。結果のクラスは以下の引数が渡されインスタンス化されます:stream, descriptions, verbosity
-
-
unittest.
main
([module[, defaultTest[, argv[, testRunner[, testLoader[, exit[, verbosity[, failfast[, catchbreak[, buffer]]]]]]]]]])¶ module から複数のテストを読み込んで実行するためのコマンドラインプログラム。この関数を使えば、簡単に実行可能なテストモジュールを作成する事ができます。一番簡単なこの関数の使い方は、以下の行をテストスクリプトの最後に置くことです:
if __name__ == '__main__': unittest.main()
より詳細な情報は verbosity 引数を指定して実行すると得られます:
if __name__ == '__main__': unittest.main(verbosity=2)
defaultTest 引数は、 argv で指定されるテスト名がない場合に実行するテスト名です。これを指定しないか
None
を指定し、また argv からも与えられない場合は、 module 内で見つかる全てのテストを実行します。argv 引数には、プログラムに渡されたオプションのリストを、最初の要素がプログラム名のままで渡せます。指定しないか
None
の場合はsys.argv
が使われます。引数、 testRunner は、test runner class、あるいは、そのインスタンスのどちらでも構いません。でフォルトでは
main
はテストが成功したか失敗したかに対応した終了コードと共にsys.exit()
を呼び出します。testLoader 引数は
TestLoader
インスタンスでなければなりません。デフォルトはdefaultTestLoader
です。main
は、exit=False
を指定する事で対話的なインタプリタから使用することもできます。この引数を指定すると、sys.exit()
を呼ばずに、結果のみを出力します:>>> from unittest import main >>> main(module='test_module', exit=False)
failfast, catchbreak, buffer は、コマンドラインオプション にある同名のオプションと同じ効果のあるパラメータです。
main
を呼び出すと、TestProgram
のインスタンスが返されます。このインスタンスは、result
属性にテスト結果を保持します。バージョン 2.7 で変更: パラメータ exit, verbosity, failfast, catchbreak, buffer が追加されました。
25.3.7.3.1. load_tests プロトコル¶
バージョン 2.7 で追加.
モジュールやパッケージには、load_tests
と呼ばれる関数を実装できます。これにより、通常のテスト実行時やテストディスカバリ時のテストのロードされ方をカスタマイズできます。
テストモジュールが load_tests
を定義していると、それが TestLoader.loadTestsFromModule()
から呼ばれます。引数は以下です:
load_tests(loader, standard_tests, None)
これは TestSuite
を返すべきです。
loader はローディングを行う TestLoader
のインスタンスです。 standard_tests は、そのモジュールからデフォルトでロードされるテストです。これは、テストの標準セットのテストの追加や削除のみを行いたいテストモジュールに一般に使われます。第三引数は、パッケージをテストディスカバリの一部としてロードするときに使われます。
特定の TestCase
クラスのセットからテストをロードする典型的な load_tests
関数は、このようになります:
test_cases = (TestCase1, TestCase2, TestCase3)
def load_tests(loader, tests, pattern):
suite = TestSuite()
for test_class in test_cases:
tests = loader.loadTestsFromTestCase(test_class)
suite.addTests(tests)
return suite
ディスカバリが開始されると、パッケージ名にマッチするパターンを、コマンドラインまたは TestLoader.discover()
に与えることで、 __init__.py
に load_tests
があるか調べられます。
注釈
デフォルトのパターンは 'test*.py'
です。これは 'test'
で始まるすべての Python ファイルにマッチしますが、テストディレクトリにはマッチ しません。
'test*'
のようなパターンは、モジュールだけでなくテストパッケージにもマッチします。
パッケージ __init__.py
が load_tests
を定義していると、それが呼び出され、ディスカバリはそれ以上パッケージ内で続けられません。 load_tests
が以下の引数で呼び出されます:
load_tests(loader, standard_tests, pattern)
これはパッケージ内のすべてのテストを表す TestSuite
を返すべきです。 (standard_tests
には、 __init__.py
から収集されたテストのみが含まれます。)
パターンは load_tests
に渡されるので、パッケージは自由にテストディスカバリを継続 (必要なら変更) できます。テストパッケージに '何もしない' load_tests
関数は次のようになります:
def load_tests(loader, standard_tests, pattern):
# top level directory cached on loader instance
this_dir = os.path.dirname(__file__)
package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
standard_tests.addTests(package_tests)
return standard_tests
25.3.8. クラスとモジュールのフィクスチャ¶
クラスレベルとモジュールレベルのフィクスチャが TestSuite
に実装されました。テストスイートが新しいクラスのテストを始める時、以前のクラス (あれば)の tearDownClass()
を呼び出し、その後に新しいクラスの setUpClass()
を呼び出します。
同様に、今回のテストのモジュールが前回のテストとは異なる場合、以前のモジュールの tearDownModule
を実行し、次に新しいモジュールの setUpModule
を実行します。
すべてのテストが実行された後、最後の tearDownClass
と tearDownModule
が実行されます。
なお、共有フィクスチャは、テストの並列化などの [潜在的な] 機能と同時にはうまくいかず、テストの分離を壊すので、気をつけて使うべきです。
unittest テストローダによるテスト作成のデフォルトの順序では、同じモジュールやクラスからのテストはすべて同じグループにまとめられます。これにより、setUpClass
/ setUpModule
(など) は、一つのクラスやモジュールにつき一度だけ呼ばれます。この順序をバラバラにし、異なるモジュールやクラスのテストが並ぶようにすると、共有フィクスチャ関数は、一度のテストで複数回呼ばれるようにもなります。
共有フィクスチャは標準でない順序で実行されることを意図していません。共有フィクスチャをサポートしたくないフレームワークのために、BaseTestSuite
がまだ存在しています。
共有フィクスチャ関数のいずれかで例外が発生した場合、そのテストはエラーとして報告されます。そのとき、対応するテストインスタンスが無いので(TestCase
と同じインタフェースの) _ErrorHolder
オブジェクトが生成され、エラーを表します。標準 unittest テストランナーを使っている場合はこの詳細は問題になりませんが、あなたがフレームワークの作者である場合は注意してください。
25.3.8.1. setUpClass と tearDownClass¶
これらはクラスメソッドとして実装されなければなりません:
import unittest
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
@classmethod
def tearDownClass(cls):
cls._connection.destroy()
基底クラスの setUpClass
および tearDownClass
を使いたいなら、それらを自分で呼び出さなければなりません。 TestCase
の実装は空です。
setUpClass
の中で例外が送出されたら、クラス内のテストは実行されず、 tearDownClass
も実行されません。スキップされたクラスは setUpClass
も tearDownClass
も実行されません。例外が SkipTest
例外であれば、そのクラスはエラーではなくスキップされたものとして報告されます。
25.3.9. シグナルハンドリング¶
unittest の -c/--catch
コマンドラインオプションや、 unittest.main()
の catchbreak
パラメタは、テスト実行中の control-C の処理をよりフレンドリーにします。中断捕捉動作を有効である場合、 control-C が押されると、現在実行されているテストまで完了され、そのテストランが終わると今までの結果が報告されます。control-C がもう一度押されると、通常通り KeyboardInterrupt
が送出されます。
シグナルハンドラを処理する control-c は、独自の signal.SIGINT
ハンドラをインストールするコードやテストの互換性を保とうとします。 unittest
ハンドラが呼ばれ、それがインストールされた signal.SIGINT
ハンドラで なければ 、すなわちテスト中のシステムに置き換えられて移譲されたなら、それはデフォルトのハンドラを呼び出します。インストールされたハンドラを置き換えて委譲するようなコードは、通常その動作を期待するからです。 unittest
の control-c 処理を無効にしたいような個別のテストには、 removeHandler()
デコレータが使えます。
フレームワークの作者がテストフレームワーク内で control-c 処理を有効にするための、いくつかのユーティリティ関数があります。
-
unittest.
installHandler
()¶ control-c ハンドラをインストールします。(主にユーザが control-c を押したことにより)
signal.SIGINT
が受け取られると、登録した結果すべてにstop()
が呼び出されます。バージョン 2.7 で追加.
-
unittest.
registerResult
(result)¶ control-c 処理のために
TestResult
を登録します。結果を登録するとそれに対する弱参照が格納されるので、結果がガベージコレクトされるのを妨げません。control-c 処理が有効でなければ、
TestResult
オブジェクトの登録には副作用がありません。ですからテストフレームワークは、処理が有効か無効かにかかわらず、作成する全ての結果を無条件に登録できます。バージョン 2.7 で追加.
-
unittest.
removeResult
(result)¶ 登録された結果を削除します。一旦結果が削除されると、control-c が押された際にその結果オブジェクトに対して
stop()
が呼び出されなくなります。バージョン 2.7 で追加.
-
unittest.
removeHandler
(function=None)¶ 引数なしで呼び出されると、この関数はCtrl+Cのシグナルハンドラを(それがインストールされていた場合)削除します。また、この関数はテストが実行されている間、Ctrl+Cのハンドラを一時的に削除するテストデコレーターとしても使用できます。
@unittest.removeHandler def test_signal_handling(self): ...
バージョン 2.7 で追加.