26.4. unittest — ユニットテストフレームワーク¶
ソースコード: Lib/unittest/__init__.py
(すでにテストの基本概念について詳しいようでしたら、この部分をとばして アサートメソッド一覧 に進むと良いでしょう。)
unittest ユニットテストフレームワークは元々 JUnit に触発されたもので、
他の言語の主要なユニットテストフレームワークと同じような感じです。
テストの自動化、テスト用のセットアップやシャットダウンのコードの共有、テストのコレクション化、そして報告フレームワークからのテストの独立性をサポートしています。
これを実現するために、 unittest はいくつかの重要な概念をオブジェクト指向の方法でサポートしています:
- テストフィクスチャ
テストフィクスチャ (test fixture) とは、テスト実行のために必要な準備や終了処理を指します。例: テスト用データベースの作成・ディレクトリ・サーバプロセスの起動など。
- テストケース
テストケース (test case) はテストの独立した単位で、各入力に対する結果をチェックします。テストケースを作成する場合は、
unittestが提供するTestCaseクラスを基底クラスとして利用することができます。- テストスイート
テストスイート (test suite) はテストケースとテストスイートの集まりで、同時に実行しなければならないテストをまとめる場合に使用します。
- テストランナー
テストランナー (test runner) はテストの実行を管理し結果を提供する要素です。ランナーはグラフィカルインターフェースやテキストインターフェースを使用しても構いませんし、テストの実行結果を示す特別な値を返しても構いません。
参考
doctestモジュールテストをサポートするもうひとつのモジュールで、このモジュールとは趣きがだいぶ異なります。
- 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 でテストやテストツールについての議論に特化したグループです。
Python のソースコード配布物にあるスクリプト Tools/unittestgui/unittestgui.py はテストディスカバリとテスト実行のための GUI ツールです。
主な目的は単体テストの初心者が簡単に使えるようにすることです。
実際の生産環境では、 Buildbot 、 Jenkins 、 Hudson のような継続的インテグレーションシステムでテストを実行することを推奨します。
26.4.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
-v オプションをテストスクリプトに渡すことで unittest.main() はより冗長になり、以下のような出力をします:
test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
上の例が unittest モジュールで最もよく使われる機能で、ほとんどのテストではこれで十分です。以下では全ての機能を一から解説しています。
26.4.2. コマンドラインインターフェイス¶
ユニットテストモジュールはコマンドラインから使って、モジュール、クラス、あるいは個別のテストメソッドで定義されたテストを実行することが出来ます:
python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method
モジュール名ならびに完全修飾されたクラス名やメソッド名の任意の組み合わせを一覧で渡すことが出来ます。
テストモジュールはファイルパスで指定することも出来ます:
python -m unittest tests/test_something.py
そのため、テストモジュールを指定するのにシェルのファイル名補完が使えます。指定されたファイルはやはりモジュールとしてインポート可能でなければなりません。パスから ‘.py’ を取り除き、パスセパレータを ‘.’ に置き換えることでモジュール名に変換されます。モジュールとしてインポート可能でないテストファイルを実行したい場合は、代わりにそのファイルを直接実行するのが良いでしょう。
テスト実行時に(冗長な)詳細を表示するには -v フラグを渡します:
python -m unittest -v test_module
引数無しで実行すると テストディスカバリ が開始されます:
python -m unittest
コマンドラインプションの一覧を表示するには以下のコマンドを実行します:
python -m unittest -h
バージョン 3.2 で変更: 以前のバージョンでは、個々のテストメソッドしか実行することができず、モジュール単位やクラス単位で実行することは不可能でした。
26.4.2.1. コマンドラインオプション¶
unittest には以下のコマンドラインオプションがあります:
-
-b,--buffer¶ 標準出力と標準エラーのストリームをテストの実行中にバッファします。テストが成功している間は結果の出力は破棄されます。テストの失敗やエラーの場合、出力は通常通り表示され、エラーメッセージに追加されます。
-
-c,--catch¶ Control-Cを実行中のテストが終了するまで遅延させ、そこまでの結果を出力します。二回目のControl-Cは、通常通りKeyboardInterruptの例外を発生させます。この機能の仕組みについては、シグナルハンドリング を参照してください。
-
-f,--failfast¶ 初回のエラーもしくは失敗の時にテストを停止します。
-
--locals¶ トレースバック内の局所変数を表示します。
バージョン 3.2 で追加: コマンドラインオプションの -b、-c、-f が追加されました。
バージョン 3.5 で追加: コマンドラインオプション --locals。
コマンドラインによってテストディスカバリ、すなわちプロジェクトの全テストを実行したりサブセットのみを実行したりすることも出来ます。
26.4.3. テストディスカバリ¶
バージョン 3.2 で追加.
unittest はシンプルなテストディスカバリをサポートします。 テストディスカバリに対応するには、全テストファイルはプロジェクトの最上位のディスカバリからインポート可能な モジュール か (名前空間パッケージ を含む) パッケージ でなければなりません (つまりそれらのファイル名は有効な 識別子 でなければなりません)。
テストディスカバリは TestLoader.discover() で実装されていますが、コマンドラインから使う事も出来ます。その基本的な使い方は:
cd project_directory
python -m unittest discover
注釈
python -m unittest は python -m unittest discover と等価なショートカットです。テストディスカバリに引数を渡したい場合は、discover サブコマンドを明示的に使用しなければなりません。
discover サブコマンドには以下のオプションがあります:
-
-v,--verbose¶ 詳細な出力
-
-s,--start-directorydirectory¶ ディスカバリを開始するディレクトリ(デフォルトは
.)
-
-p,--patternpattern¶ テストファイル名を識別するパターン (デフォルトは
test*.py)
-
-t,--top-level-directorydirectory¶ プロジェクトの最上位のディスカバリのディレクトリ(デフォルトは開始のディレクトリ)
-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 プロトコル によってテストのロードとディスカバリをカスタマイズすることができます。
バージョン 3.4 で変更: ディスカバリが 名前空間パッケージ をサポートしました。
26.4.4. テストコードの構成¶
ユニットテストの基本的な構成要素は、 テストケース — 設定され正しさのためにチェックされるべき単独のシナリオ — です。
unittest では、テストケースは unittest.TestCase クラスのインスタンスで表現されます。
独自のテストケースを作成するには TestCase のサブクラスを記述するか、 FunctionTestCase を使用しなければなりません。
TestCase インスタンスのテストコードは完全に独立していなければなりません。
すなわち単独でか、他の様々なテストケースの任意の組み合わせのいずれかで実行可能でなければなりません。
最も単純な TestCase のサブクラスは、特定のテストコードを実行するためのテストメソッド (すなわち名前が test で始まるメソッド) を実装するだけで簡単に書くことができます:
import unittest
class DefaultWidgetSizeTestCase(unittest.TestCase):
def test_default_widget_size(self):
widget = Widget('The widget')
self.assertEqual(widget.size(), (50, 50))
何らかのテストを行う場合、ベースクラス TestCase の assert*() メソッドの一つを使用してください。テスト が失敗すると例外が送出され、 unittest はテストケースを failure とします。その他の例外は error として扱われます。
テストは多くなり、それらの設定は繰り返しになるかもしれません。
幸いにも、setUp() メソッドを実装することで設定コードをくくり出すことができます。
テストフレームワークは実行するテストごとに自動的に setUp() を呼びます:
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def test_default_widget_size(self):
self.assertEqual(self.widget.size(), (50,50),
'incorrect default size')
def test_widget_resize(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(), (100,150),
'wrong size after resize')
注釈
いろいろなテストが実行される順序は、文字列の組み込みの順序でテストメソッド名をソートすることで決まります。
テスト中に setUp() メソッドで例外が発生した場合、フレームワークはそのテストに問題があるとみなし、そのテストメソッドは実行されません。
同様に、テストメソッド実行後に片付けをする tearDown() メソッドを提供出来ます:
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
setUp() が成功した場合、テストメソッドが成功したかどうかに関わらず tearDown() が実行されます。
このようなテストコードの実行環境を fixture と呼びます。
テストケースのインスタンスはテストする機能によってまとめられます。
unittest はこのための機構、unittest の TestSuite クラスで表現される test suite、を提供します。
たいていの場合 unittest.main() を呼び出しは正しい処理を行い、モジュールの全テストケースを集めて実行します。
しかし、テストスイートの構築をカスタマイズしたい場合、自分ですることができます:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_size'))
suite.addTest(WidgetTestCase('test_resize'))
return suite
テストケースやテストコードの定義を (widget.py のような) テスト対象コードと同じモジュールに置くことが出来ますが、テストコードを (test_widget.py のような) 独立したモジュールに置くのには以下のような利点があります:
テストモジュールだけをコマンドラインから独立に実行することができる。
テストコードと出荷するコードをより簡単に分ける事ができる。
余程のことがない限り、テスト対象のコードに合わせてテストコードを変更することになりにくい。
テストコードは、テスト対象コードほど頻繁に変更されない。
テストコードをより簡単にリファクタリングすることができる。
Cで書いたモジュールのテストはどうせ独立したモジュールなのだから、同様にしない理由がない
テストの方策を変更した場合でも、ソースコードを変更する必要がない。
26.4.5. 既存テストコードの再利用¶
既存のテストコードが有るとき、このテストを unittest で実行しようとするために古いテスト関数をいちいち TestCase クラスのサブクラスに変換するのは大変です。
このような場合は、 unittest では TestCase のサブクラスである FunctionTestCase クラスを使い、既存のテスト関数をラップします。初期設定と終了処理も行なえます。
以下のテストコードがあった場合:
def testSomething():
something = makeSomething()
assert something.name is not None
# ...
オプションの set-up と tear-down メソッドを持った同等のテストケースインスタンスは次のように作成します:
testcase = unittest.FunctionTestCase(testSomething,
setUp=makeSomethingDB,
tearDown=deleteSomethingDB)
注釈
FunctionTestCase を使って既存のテストを unittest ベースのテスト体系に変換することができますが、この方法は推奨されません。時間を掛けて TestCase のサブクラスに書き直した方が将来的なテストのリファクタリングが限りなく易しくなります。
既存のテストが doctest を使って書かれている場合もあるでしょう。その場合、 doctest は DocTestSuite クラスを提供します。このクラスは、既存の doctestベースのテストから、自動的に unittest.TestSuite のインスタンスを作成します。
26.4.6. テストのスキップと予期された失敗¶
バージョン 3.1 で追加.
unittest は特定のテストメソッドやテストクラス全体をスキップする仕組みを備えています。さらに、この機能はテスト結果を「予期された失敗 (expected failure)」とすることができ、テストが失敗しても TestResult の失敗数にはカウントされなくなります。
テストをスキップするには、単に 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() は実行されません。スキップしたモジュールの前後では、 setUpModule() および tearDownModule() は実行されません。
26.4.7. サブテストを利用して繰り返しテストの区別を付ける¶
バージョン 3.4 で追加.
パラメータの値しか違わないような小さな差しかない複数テストを書きたい場合に、コンテキストマネージャ subTest() を使うことで、複数の独立したテストのように扱われるテストを一つのメソッド本体内で書くことが出来ます。
例えば以下のテストは:
class NumbersTest(unittest.TestCase):
def test_even(self):
"""
Test that numbers between 0 and 5 are all even.
"""
for i in range(0, 6):
with self.subTest(i=i):
self.assertEqual(i % 2, 0)
以下の出力をします:
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=3)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=5)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
サブテスト無しの場合、最初の失敗で実行は停止し、i の値が表示されないためエラーの原因を突き止めるのは困難になります:
======================================================================
FAIL: test_even (__main__.NumbersTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
26.4.8. クラスと関数¶
この節では、 unittest モジュールのAPIの詳細について説明します。
26.4.8.1. テストクラス¶
-
class
unittest.TestCase(methodName='runTest')¶ TestCaseクラスのインスタンスは、unittestの世界における論理的なテストの単位を示します。このクラスをベースクラスとして使用し、必要なテストを具象サブクラスに実装します。TestCaseクラスでは、テストランナーがテストを実行するため のインターフェースと、各種の失敗をチェックしレポートするためのメソッドを実装しています。TestCaseの各インスタンスは methodName という名前の単一の基底メソッドを実行します。TestCaseを使用する大半の場合 methodName を変更したりデフォルトのrunTest()メソッドを再実装することはありません。バージョン 3.2 で変更:
TestCaseが methodName を指定しなくてもインスタンス化できるようになりました。これにより対話的インタプリタからTestCaseを簡単に試せるようになりました。TestCaseのインスタンスのメソッドは3種類のグループを提供します。 1つ目のグループはテストの実行で使用されします。 2つ目のグループは条件のチェックおよび失敗のレポートを行うテストの実装で使用されます。 3つ目のグループである問い合わせ用のメソッドによってテスト自身の情報が収集されます。最初のグループ(テスト実行)に含まれるメソッドは以下の通りです:
-
setUp()¶ テストフィクスチャの準備のために呼び出されるメソッドです。テストメソッドの直前に呼び出されます。このメソッドで
AssertionErrorやSkipTest以外の例外が発生した場合、テストの失敗ではなくエラーとされます。デフォルトの実装では何も行いません。
-
tearDown()¶ テストメソッドが実行され、結果が記録された直後に呼び出されるメソッドです。 このメソッドはテストメソッドで例外が投げられても呼び出されます。 そのため、サブクラスでこのメソッドを実装する場合は、内部状態を確認することが必要になるでしょう。 このメソッドで
AssertionErrorやSkipTest以外の例外が発生した場合、テストの失敗とは別のエラーとみなされます (従って報告されるエラーの総数は増えます)。 このメソッドは、テストの結果に関わらずsetUp()が成功した場合にのみ呼ばれます。 デフォルトの実装では何も行いません。
-
setUpClass()¶ 個別のクラス内のテストが実行される前に呼び出されるクラスメソッドです。
setUpClassはクラスを唯一の引数として取り、classmethod()でデコレートされていなければなりません:@classmethod def setUpClass(cls): ...
詳しくは クラスとモジュールのフィクスチャ を参照してください。
バージョン 3.2 で追加.
-
tearDownClass()¶ 個別のクラス内のテストが実行された後に呼び出されるクラスメソッドです。
tearDownClassはクラスを唯一の引数として取り、classmethod()でデコレーされていなければなりません:@classmethod def tearDownClass(cls): ...
詳しくは クラスとモジュールのフィクスチャ を参照してください。
バージョン 3.2 で追加.
-
run(result=None)¶ テストを実行し、テスト結果を result に指定された
TestResultオブジェクトにまとめます。 result が省略されるかNoneが渡された場合、 (defaultTestResult()メソッドを呼んで) 一時的な結果オブジェクトを生成し、使用します。 結果オブジェクトはrun()の呼び出し元に返されます。このメソッドは、単に
TestCaseインスタンスを呼び出した場合と同様に振る舞います。バージョン 3.3 で変更: 以前のバージョンの
runは結果オブジェクトを返しませんでした。またTestCaseインスタンスを呼び出した場合も同様でした。
-
skipTest(reason)¶ テストメソッドや
setUp()が現在のテストをスキップする間に呼ばれます。詳細については、 テストのスキップと予期された失敗 を参照してください。バージョン 3.1 で追加.
-
subTest(msg=None, **params)¶ このメソッドを囲っているブロックをサブテストとして実行するコンテキストマネージャを返します。 msg と params はサブテストが失敗したときに表示されるオプションの任意の値で、どんな値が使われたかを明確にするものです。
テストケースには subtest 宣言を幾らでも含めることができ、任意にネストすることができます。
詳細は サブテストを利用して繰り返しテストの区別を付ける を参照してください。
バージョン 3.4 で追加.
-
debug()¶ テスト結果を収集せずにテストを実行します。例外が呼び出し元に通知されます。また、テストをデバッガで実行することができます。
TestCaseクラスは失敗の検査と報告を行う多くのメソッドを提供しています。 以下の表は最も一般的に使われるメソッドを列挙しています (より多くのアサートメソッドについては表の下を見てください):メソッド
確認事項
初出
assertEqual(a, b)a == bassertNotEqual(a, b)a != bassertTrue(x)bool(x) is TrueassertFalse(x)bool(x) is FalseassertIs(a, b)a is b3.1 assertIsNot(a, b)a is not b3.1 assertIsNone(x)x is None3.1 assertIsNotNone(x)x is not None3.1 assertIn(a, b)a in b3.1 assertNotIn(a, b)a not in b3.1 assertIsInstance(a, b)isinstance(a, b)3.2 assertNotIsInstance(a, b)not isinstance(a, b)3.2 全てのアサートメソッドは msg 引数を受け取り、指定された場合、失敗時のエラーメッセージとして使われます。 (
longMessageも参照してください)。 msg キーワード引数はassertRaises()、assertRaisesRegex()、assertWarns()、assertWarnsRegex()には、そのメソッドをコンテキストマネージャとして使った場合にのみ使えます。-
assertEqual(first, second, msg=None)¶ first と second が等しいことをテストします。両者が等しくない場合、テストは失敗です。
さらに、 first と second が厳密に同じ型であり、list、tuple、dict、set、frozenset もしくは str のいずれか、またはサブクラスが
addTypeEqualityFunc()に登録されている任意の型の場合、より有用なデフォルトのエラーメッセージを生成するために、その型特有の比較関数が呼ばれます(型固有のメソッドの一覧 も参照してください)。バージョン 3.1 で変更: 自動で型固有の比較関数が呼ばれるようになりました。
バージョン 3.2 で変更: 文字列比較のデフォルトの比較関数として
assertMultiLineEqual()が追加されました。
-
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 が同じオブジェクトであること(そうでないこと)をテストします。
バージョン 3.1 で追加.
-
assertIsNone(expr, msg=None)¶ -
assertIsNotNone(expr, msg=None)¶ expr が
Noneであること (および、そうでないこと) をテストします。バージョン 3.1 で追加.
-
assertIn(first, second, msg=None)¶ -
assertNotIn(first, second, msg=None)¶ first が second に含まれること(そうでないこと)をテストします。
バージョン 3.1 で追加.
-
assertIsInstance(obj, cls, msg=None)¶ -
assertNotIsInstance(obj, cls, msg=None)¶ obj が cls のインスタンスであること(あるいはそうでないこと)をテストします(この cls は、
isinstance()が扱うことのできる、クラスもしくはクラスのタプルである必要があります)。正確な型をチェックするためには、assertIs(type(obj), cls)を使用してください。バージョン 3.2 で追加.
以下のメソッドを使用して例外、警告、およびログメッセージの発生を確認することが出来ます:
メソッド
確認事項
初出
assertRaises(exc, fun, *args, **kwds)fun(*args, **kwds)が exc を送出するassertRaisesRegex(exc, r, fun, *args, **kwds)fun(*args, **kwds)が exc を送出してメッセージが正規表現 r とマッチする3.1 assertWarns(warn, fun, *args, **kwds)fun(*args, **kwds)が warn を送出する3.2 assertWarnsRegex(warn, r, fun, *args, **kwds)fun(*args, **kwds)が warn を送出してメッセージが正規表現 r とマッチする3.2 assertLogs(logger, level)withブロックが 最低 level で logger を使用する3.4 -
assertRaises(exception, callable, *args, **kwds)¶ -
assertRaises(exception, msg=None) callable を呼び出した時に例外が発生することをテストします。
assertRaises()で指定した位置パラメータとキーワードパラメータを該当メソッドに渡します。 exception が送出された場合、テストは成功です。また、他の例外が投げられた場合はエラー、例外が送出されなかった場合は失敗になります。複数の例外をキャッチする場合には、例外クラスのタプルを exception に指定してください。exception 引数のみ(またはそれに加えて msg 引数)が渡された場合には、コンテキストマネージャが返されます。これにより関数名を渡す形式ではなく、インラインでテスト対象のコードを書くことができます:
with self.assertRaises(SomeException): do_something()
コンテキストマネージャとして使われたときは、
assertRaises()は加えて msg キーワード引数も受け付けます。このコンテキストマネージャは
exceptionで指定されたオブジェクトを格納します。これにより、例外発生時の詳細な確認をおこなうことができます:with self.assertRaises(SomeException) as cm: do_something() the_exception = cm.exception self.assertEqual(the_exception.error_code, 3)
バージョン 3.1 で変更:
assertRaises()がコンテキストマネージャとして使えるようになりました。バージョン 3.2 で変更:
exception属性が追加されました。バージョン 3.3 で変更: コンテキストマネージャとして使用したときに msg キーワード引数が追加されました。
-
assertRaisesRegex(exception, regex, callable, *args, **kwds)¶ -
assertRaisesRegex(exception, regex, msg=None) assertRaises()と同等ですが、例外の文字列表現が regex にマッチすることもテストします。 regex は正規表現オブジェクトか、re.search()が扱える正規表現が書かれた文字列である必要があります。例えば以下のようになります:self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$", int, 'XYZ')
もしくは:
with self.assertRaisesRegex(ValueError, 'literal'): int('XYZ')
バージョン 3.1 で追加:
assertRaisesRegexpという名前で追加されました。バージョン 3.2 で変更:
assertRaisesRegex()にリネームされました。バージョン 3.3 で変更: コンテキストマネージャとして使用したときに msg キーワード引数が追加されました。
-
assertWarns(warning, callable, *args, **kwds)¶ -
assertWarns(warning, msg=None) callable を呼び出した時に警告が発生することをテストします。
assertWarns()で指定した位置パラメータとキーワードパラメータを該当メソッドに渡します。 warning が発生した場合にテストが成功し、そうでなければ失敗になります。例外が送出された場合はエラーになります。複数の警告を捕捉する場合には、警告クラスのタプルを warnings に指定してください。warning 引数のみ(またはそれに加えて msg 引数)が渡された場合には、コンテキストマネージャが返されます。これにより関数名を渡す形式ではなく、インラインでテスト対象のコードを書くことができます:
with self.assertWarns(SomeWarning): do_something()
コンテキストマネージャとして使われたときは、
assertWarns()は加えて msg キーワード引数も受け付けます。このコンテキストマネージャは、捕捉した警告オブジェクトを
warning属性に、警告が発生したソース行をfilename属性とlineno属性に格納します。これは警告発生時に捕捉された警告に対して追加の確認を行いたい場合に便利です:with self.assertWarns(SomeWarning) as cm: do_something() self.assertIn('myfile.py', cm.filename) self.assertEqual(320, cm.lineno)
このメソッドは呼び出されたときに警告フィルタを無視して動作します。
バージョン 3.2 で追加.
バージョン 3.3 で変更: コンテキストマネージャとして使用したときに msg キーワード引数が追加されました。
-
assertWarnsRegex(warning, regex, callable, *args, **kwds)¶ -
assertWarnsRegex(warning, regex, msg=None) assertWarns()と同等ですが、警告メッセージが regex にマッチすることもテストします。 regex は正規表現オブジェクトか、re.search()が扱える正規表現が書かれた文字列である必要があります。例えば以下のようになります:self.assertWarnsRegex(DeprecationWarning, r'legacy_function\(\) is deprecated', legacy_function, 'XYZ')
もしくは:
with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'): frobnicate('/etc/passwd')
バージョン 3.2 で追加.
バージョン 3.3 で変更: コンテキストマネージャとして使用したときに msg キーワード引数が追加されました。
-
assertLogs(logger=None, level=None)¶ logger かその子ロガーのうちの1つに、少なくとも1つのログメッセージが少なくとも与えられた level で出力されることをテストするコンテキストマネージャです。
logger が与えられた場合、
logging.Loggerオブジェクトもしくはロガーの名前であるstrであるべきです。 デフォルトはルートロガーで、これは全てのメッセージを掴まえます。level が与えられた場合、ログレベルを表す数値もしくはそれに相当する文字列 (例えば
"ERROR"もしくはlogging.ERROR) であるべきです。 デフォルトはlogging.INFOです。withブロック内で出たメッセージの少なくとも一つが logger および level 条件に合っている場合、このテストをパスします。それ以外の場合は失敗です。コンテキストマネージャから返されるオブジェクトは、条件に該当するログメッセージを追跡し続ける記録のためのヘルパーです。 このオブジェクトには2つの属性があります:
-
records¶ 該当するログメッセージを表す
logging.LogRecordオブジェクトのリスト。
例
with self.assertLogs('foo', level='INFO') as cm: logging.getLogger('foo').info('first message') logging.getLogger('foo.bar').error('second message') self.assertEqual(cm.output, ['INFO:foo:first message', 'ERROR:foo.bar:second message'])
バージョン 3.4 で追加.
-
より具体的な確認を行うために以下のメソッドが用意されています:
メソッド
確認事項
初出
assertAlmostEqual(a, b)round(a-b, 7) == 0assertNotAlmostEqual(a, b)round(a-b, 7) != 0assertGreater(a, b)a > b3.1 assertGreaterEqual(a, b)a >= b3.1 assertLess(a, b)a < b3.1 assertLessEqual(a, b)a <= b3.1 assertRegex(s, r)r.search(s)3.1 assertNotRegex(s, r)not r.search(s)3.2 assertCountEqual(a, b)a と b に、順番によらず同じ要素が同じ数だけある
3.2 -
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が投げられます。バージョン 3.2 で変更:
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"
バージョン 3.1 で追加.
-
assertRegex(text, regex, msg=None)¶ -
assertNotRegex(text, regex, msg=None)¶ regex の検索が text とマッチする (またはマッチしない) ことをテストします。テスト失敗時には、エラーメッセージにパターンと text が表示されます(もしくは、パターンと意図しないかたちでマッチした text の一部が表示されます)。 regex は正規表現オブジェクトか、
re.search()が扱える正規表現が書かれた文字列である必要があります。バージョン 3.1 で追加:
assertRegexpMatchesという名前で追加されました。バージョン 3.2 で変更: メソッド
assertRegexpMatches()はassertRegex()にリネームされました。バージョン 3.2 で追加:
assertNotRegex()。
-
assertCountEqual(first, second, msg=None)¶ シーケンス first が second と同じ要素を含んでいることをテストします。要素の順序はテスト結果に影響しません。要素が含まれていない場合には、シーケンスの差分がエラーメッセージとして表示されます。
first と second の比較では、重複した要素は無視 されません。両者に同じ数の要素が含まれていることを検証します。このメソッドは
assertEqual(Counter(list(first)), Counter(list(second)))と同等に振る舞うことに加えて、ハッシュ化できないオブジェクトのシーケンスでも動作します。バージョン 3.2 で追加.
assertEqual()メソッドは、同じ型のオブジェクトの等価性確認のために、型ごとに特有のメソッドにディスパッチします。これらのメソッドは、ほとんどの組み込み型用のメソッドは既に実装されています。さらに、addTypeEqualityFunc()を使う事で新たなメソッドを登録することができます:-
addTypeEqualityFunc(typeobj, function)¶ assertEqual()で呼び出される型特有のメソッドを登録します。登録するメソッドは、比較する2つのオブジェクトの型が厳密に typeobj と同じ(サブクラスでもいけません)の場合に等価性を確認します。 function はassertEqual()と同様に、2つの位置固定引数と、3番目に msg=None のキーワード引数を取れる必要があります。このメソッドは、始めの2つに指定したパラメータ間の差分を検出した時にself.failureException(msg)の例外を投げる必要があります。この例外を投げる際は、出来る限り、エラーの内容が分かる有用な情報と差分の詳細をエラーメッセージに含めてください。バージョン 3.1 で追加.
assertEqual()が自動的に呼び出す型特有のメソッドの概要を以下の表示に記載しています。これらのメソッドは通常は直接呼び出す必要がないことに注意が必要です。メソッド
比較の対象
初出
assertMultiLineEqual(a, b)strings 3.1 assertSequenceEqual(a, b)sequences 3.1 assertListEqual(a, b)lists 3.1 assertTupleEqual(a, b)tuples 3.1 assertSetEqual(a, b)sets or frozensets 3.1 assertDictEqual(a, b)dicts 3.1 -
assertMultiLineEqual(first, second, msg=None)¶ 複数行の文字列 first が文字列 second と等しいことをテストします。等しくない場合には、両者の差分がハイライトされてエラーメッセージに表示されます。このメソッドは、デフォルトで、
assertEqual()が string を比較するときに自動的に使用します。バージョン 3.1 で追加.
-
assertSequenceEqual(first, second, msg=None, seq_type=None)¶ 2つのシーケンスが等しいことをテストします。seq_type が指定された場合、first と second が seq_type のインスタンスで無い場合にはテストが失敗します。シーケンスどうしが異なる場合には、両者の差分がエラーメッセージに表示されます。
このメソッドは直接
assertEqual()からは呼ばれませんが、assertListEqual()とassertTupleEqual()の実装で使われています。バージョン 3.1 で追加.
-
assertListEqual(first, second, msg=None)¶ -
assertTupleEqual(first, second, msg=None)¶ 2つのリストまたはタプルが等しいかどうかをテストします。等しくない場合には、両者の差分を表示します。2つのパラメータの型が異なる場合にはテストがエラーになります。このメソッドは、デフォルトで、
assertEqual()が list または tuple を比較するときに自動的に使用します。バージョン 3.1 で追加.
-
assertSetEqual(first, second, msg=None)¶ 2つのセットが等しいかどうかをテストします。等しくない場合には、両者の差分を表示します。このメソッドは、デフォルトで、
assertEqual()が set もしくは frozenset を比較するときに自動的に使用します。first or second のいずれかに
set.difference()が無い場合にはテストは失敗します。バージョン 3.1 で追加.
-
assertDictEqual(first, second, msg=None)¶ 2つの辞書が等しいかどうかをテストします。等しくない場合には、両者の差分を表示します。このメソッドは、デフォルトで、
assertEqual()が dict を比較するときに自動的に使用します。バージョン 3.1 で追加.
最後に、
TestCaseの残りのメソッドと属性を紹介します:-
fail(msg=None)¶ 無条件にテストを失敗させます。エラーメッセージの表示に、msg または
Noneが使われます。
-
failureException¶ test()メソッドが送出する例外を指定するクラス属性です。例えばテストフレームワークで追加情報を付した特殊な例外が必要になる場合、この例外のサブクラスとして作成します。この属性の初期値はAssertionErrorです。
-
longMessage¶ このクラス属性は、失敗した assertXYY の呼び出しで独自の失敗時のメッセージが msg 引数として渡されていたときにどうするかを決定します。
Trueがデフォルト値です。 この場合、標準の失敗時のメッセージの後に独自のメッセージが追記されます。Falseに設定したときは、標準のメッセージを独自のメッセージで置き換えます。アサートメソッドを呼び出す前に、個別のテストメソッドの中でインスタンス属性 self.longMessage を
TrueまたはFalseに設定して、この設定を上書きできます。このクラスの設定はそれぞれのテストを呼び出す前にリセットされます。
バージョン 3.1 で追加.
-
maxDiff¶ この属性は、アサーションメソッドが失敗をレポートする時に表示する差分の長さをコントロールします。デフォルトは 80*8 文字です。この属性が影響するメソッドは、
assertSequenceEqual()(およびこのメソッドに委譲するシーケンス比較メソッド)、assertDictEqual()とassertMultiLineEqual()です。maxDiffをNoneに設定すると差分表示の上限がなくなります。バージョン 3.2 で追加.
テストフレームワークは、テスト情報を収集するために以下のメソッドを使用します:
-
defaultTestResult()¶ このテストケースクラスで使われるテスト結果クラスのインスタンスを (もし
run()メソッドに他の結果インスタンスが提供されないならば) 返します。TestCaseインスタンスに対しては、いつもTestResultのインスタンスですので、TestCaseのサブクラスでは必要に応じてこのメソッドをオーバライドしてください。
-
id()¶ テストケースを特定する文字列を返します。通常、id はモジュール名・クラス名を含む、テストメソッドのフルネームを指定します。
-
shortDescription()¶ テストの説明を一行分、または説明がない場合には
Noneを返します。デフォルトでは、テストメソッドの docstring の先頭の一行、またはNoneを返します。バージョン 3.1 で変更: 3.1で docstring があったとしても、返される短い説明文字列にテスト名が付けられるようになりました。 この変更によって unittest 拡張に互換性の問題が発生し、 Python 3.2 でテスト名が追加される場所は
TextTestResultへ移動しました。
-
addCleanup(function, *args, **kwargs)¶ tearDown()の後に呼び出される関数を追加します。この関数はリソースのクリーンアップのために使用します。追加された関数は、追加された順と逆の順番で呼び出されます(LIFO)。addCleanup()に渡された引数とキーワード引数が追加された関数にも渡されます。setUp()が失敗した場合、つまりtearDown()が呼ばれなかった場合でも、追加されたクリーンアップ関数は呼び出されます。バージョン 3.1 で追加.
-
doCleanups()¶ このメソッドは、
tearDown()の後、もしくは、setUp()が例外を投げた場合はsetUp()の後に、無条件で呼ばれます。このメソッドは、
addCleanup()で追加された関数を呼び出す責務を担います。もし、クリーンアップ関数をtearDown()より前に呼び出す必要がある場合には、doCleanups()を明示的に呼び出してください。doCleanups()は、どこで呼び出されても、クリーンアップ関数をスタックから削除して実行します。バージョン 3.1 で追加.
-
-
class
unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)¶ このクラスでは
TestCaseインターフェースの内、テストランナーがテストを実行するためのインターフェースだけを実装しており、テスト結果のチェックやレポートに関するメソッドは実装していません。既存のテストコードをunittestによるテストフレームワークに組み込むために使用します。
26.4.8.1.1. 非推奨のエイリアス¶
歴史的な経緯で、 TestCase のいくつかのエイリアスは非推奨となりました。以下の表に、非推奨のエイリアスをまとめます:
メソッド名
非推奨のエイリアス
非推奨のエイリアス
assertEqual()failUnlessEqual assertEquals assertNotEqual()failIfEqual assertNotEquals assertTrue()failUnless assert_ assertFalse()failIf assertRaises()failUnlessRaises assertAlmostEqual()failUnlessAlmostEqual assertAlmostEquals assertNotAlmostEqual()failIfAlmostEqual assertNotAlmostEquals assertRegex()assertRegexpMatches assertRaisesRegex()assertRaisesRegexp バージョン 3.1 で撤廃: 2列目に記載されている fail* エイリアス。
バージョン 3.2 で撤廃: 3列目に記載されている assert* エイリアス。
バージョン 3.2 で撤廃:
assertRegexpMatchesとassertRaisesRegexpはassertRegex()とassertRaisesRegex()にリネームされました
26.4.8.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つのスイート内でこのメソッドは何度も呼ばれる可能性があることに注意してください (例えば、テスト数のカウントや等価性の比較)。 そのため、TestSuite.run()を実行する前に反復アクセスを何度繰り返しても同じテスト群を返すようにしなければなりません。 呼び出し側がTestSuite._removeTestAtIndex()をオーバーライドしたサブクラスを使いテストへの参照を保存していない限り、TestSuite.run()を実行した後はこのメソッドが返すテスト群を信頼すべきではありません。バージョン 3.2 で変更: 以前のバージョンでは
TestSuiteはイテレータではなく、直接テストにアクセスしていました。そのため、__iter__()をオーバーラードしてもテストにアクセスできませんでした。バージョン 3.4 で変更: 以前のバージョンでは、
TestSuite.run()の実行後はTestSuiteが各TestCaseへの参照を保持していました。 サブクラスでTestSuite._removeTestAtIndex()をオーバーライドすることでこの振る舞いを復元できます。
通常、
TestSuiteのrun()メソッドはTestRunnerが起動するため、ユーザが直接実行する必要はありません。-
26.4.8.3. テストのロードと起動¶
-
class
unittest.TestLoader¶ TestLoaderクラスはクラスとモジュールからテストスイートを生成します。通常、このクラスのインスタンスを明示的に生成する必要はありません。unittestモジュールのunittest.defaultTestLoaderを共用インスタンスとして使用することができます。 しかし、このクラスのサブクラスやインスタンスで、属性をカスタマイズすることができます。TestLoaderオブジェクトには以下の属性があります:-
errors¶ テストの読み込み中に起きた致命的でないエラーのリストです。 どの時点でもローダーからリセットされることはありません。 致命的なエラーは適切なメソッドが例外を送出して、呼び出し元に通知します。 致命的でないエラーも、実行したときのエラーを総合テストが通知してくれます。
バージョン 3.5 で追加.
TestLoaderのオブジェクトには以下のメソッドがあります:-
loadTestsFromTestCase(testCaseClass)¶ TestCaseの派生クラスtestCaseClassに含まれる全テストケースのスイートを返します。getTestCaseNames()で指定されたメソッドに対し、テストケースインスタンスが作成されます。 デフォルトではtestで始まる名前のメソッド群です。getTestCaseNames()がメソッド名を返さなかったが、runTest()メソッドが実装されている場合は、そのメソッドに対するテストケースが代わりに作成されます。
-
loadTestsFromModule(module, pattern=None)¶ 指定したモジュールに含まれる全テストケースのスイートを返します。このメソッドは module 内の
TestCase派生クラスを検索し、見つかったクラスのテストメソッドごとにクラスのインスタンスを作成します。注釈
TestCaseクラスを基底クラスとしてクラス階層を構築するとテストフィクスチャや補助的な関数をうまく共用することができますが、基底クラスに直接インスタンス化できないテストメソッドがあると、このloadTestsFromModule()を使うことができません。この場合でも、 fixture が全て別々で定義がサブクラスにある場合は使用することができます。モジュールが
load_tests関数を用意している場合、この関数がテストの読み込みに使われます。 これによりテストの読み込み処理がカスタマイズできます。 これが load_tests プロトコル です。 pattern 引数はload_testsに第3引数として渡されます。バージョン 3.2 で変更:
load_testsのサポートが追加されました。バージョン 3.5 で変更: ドキュメントにない、非公式の use_load_tests デフォルト引数は非推奨で、後方互換性のために残されていますが無視されます。 また、このメソッドはキーワード専用引数 pattern を受け取るようになりました。これは
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 を取得します。
バージョン 3.5 で変更: name を巡回している間に
ImportErrorかAttributeErrorが発生した場合、実行するとその例外を発生させるようなテストを合成して返します。それらのエラーは self.errors に集められます。
-
loadTestsFromNames(names, module=None)¶ loadTestsFromName()と同じですが、名前を一つだけ指定するのではなく、複数の名前のシーケンスを指定する事ができます。戻り値は names 中の名前で指定されるテスト全てを含むテストスイートです。
-
getTestCaseNames(testCaseClass)¶ testCaseClass 中の全てのメソッド名を含むソート済みシーケンスを返します。 testCaseClass は
TestCaseのサブクラスでなければなりません。
-
discover(start_dir, pattern='test*.py', top_level_dir=None)¶ 指定された開始ディレクトリからサブディレクトリに再帰することですべてのテストモジュールを検索し、それらを含む TestSuite オブジェクトを返します。pattern にマッチしたテストファイルだけがロードの対象になります。(シェルスタイルのパターンマッチングが使われます。)その中で、インポート可能なもジュール(つまりPythonの識別子として有効であるということです)がロードされます。
すべてのテストモジュールはプロジェクトのトップレベルからインポート可能である必要があります。開始ディレクトリがトップレベルディレクトリでない場合は、トップレベルディレクトリが分離できなくてはいけません。
シンタックスエラーなどでモジュールのインポートに失敗した場合、エラーが記録され、ディスカバリ自体は続けられます。 import の失敗が
SkipTest例外が発生したためだった場合は、そのモジュールはエラーではなく skip として記録されます。パッケージ (
__init__.pyという名前のファイルがあるディレクトリ) が見付かった場合、そのパッケージにload_tests関数があるかをチェックします。 関数があった場合、次にpackage.load_tests(loader, tests, pattern)が呼ばれます。 テストの検索の実行では、たとえ load_tests 関数自身がloader.discoverを呼んだとしても、パッケージのチェックは1回のみとなることが保証されています。load_testsが存在して、ディスカバリがパッケージ内を再帰的な検索を続けている途中で ない 場合、load_testsはそのパッケージ内の全てのテストをロードする責務を担います。意図的にパターンはローダの属性として保持されないようになっています。それにより、パッケージが自分自身のディスカバリを続ける事ができます。top_level_dir は保持されるため、
load_testsはこの引数をloader.discover()に渡す必要はありません。start_dir はドット付のモジュール名でもディレクトリでも構いません。
バージョン 3.2 で追加.
バージョン 3.4 で変更: インポート時に
SkipTestを送出するモジュールはエラーではなくスキップとして記録されます。 名前空間パッケージ も検索対象になります。 ファイルシステムの順序がファイル名に従わないとしても実行順序が一定になるように、パスはインポートする前にソートされます。バージョン 3.5 で変更: パッケージ名がデフォルトのパターンに適合するのは不可能なので、パスが pattern に適合するかどうかに関係無く、見付けたパッケージに
load_testsがあるかをチェックするようになりました。
以下の属性は、サブクラス化またはインスタンスの属性値を変更して
TestLoaderをカスタマイズする場合に使用します:-
testMethodPrefix¶ テストメソッドの名前と判断されるメソッド名の接頭語を示す文字列。デフォルト値は
'test'です。この値は
getTestCaseNames()と全てのloadTestsFrom*()メソッドに影響を与えます。
-
sortTestMethodsUsing¶ getTestCaseNames()および全てのloadTestsFrom*()メソッドでメソッド名をソートする際に使用する比較関数。
-
-
class
unittest.TestResult¶ このクラスはどのテストが成功しどのテストが失敗したかという情報を収集するのに使います。
TestResultは、複数のテスト結果を記録します。TestCaseクラスとTestSuiteクラスのテスト結果を正しく記録しますので、テスト開発者が独自にテスト結果を管理する処理を開発する必要はありません。unittestを利用したテストフレームワークでは、TestRunner.run()が返すTestResultインスタンスを参照し、テスト結果をレポートします。TestResultインスタンスの以下の属性は、テストの実行結果を検査する際に使用することができます:-
failures¶ TestCaseと例外のトレースバック情報をフォーマットした文字列の 2 要素タプルからなるリスト。それぞれのタプルはTestCase.assert*()メソッドを使って見つけ出した失敗に対応します。
-
testsRun¶ これまでに実行したテストの総数です。
-
buffer¶ Trueが設定されると、sys.stdoutとsys.stderrは、startTest()からstopTest()が呼ばれるまでの間バッファリングされます。実際に、結果がsys.stdoutとsys.stderrに出力されるのは、テストが失敗するかエラーが発生した時になります。表示の際には、全ての失敗 / エラーメッセージが表示されます。バージョン 3.2 で追加.
-
tb_locals¶ 真の場合、局所変数がトレースバックに表示されます。
バージョン 3.5 で追加.
-
wasSuccessful()¶ これまでに実行したテストが全て成功していれば
Trueを、それ以外ならFalseを返します。バージョン 3.4 で変更:
expectedFailure()デコレ-タでマークされたテストにunexpectedSuccessesがあった場合Falseを返します。
-
stop()¶ このメソッドを呼び出して
TestResultのshouldStop属性にTrueをセットすることで、実行中のテストは中断しなければならないというシグナルを送ることができます。TestRunnerオブジェクトはこのフラグを順守してそれ以上のテストを実行することなく復帰しなければなりません。たとえばこの機能は、ユーザのキーボード割り込みを受け取って
TextTestRunnerクラスがテストフレームワークを停止させるのに使えます。TestRunnerの実装を提供する対話的なツールでも同じように使用することができます。
TestResultクラスの以下のメソッドは内部データ管理用のメソッドですが、対話的にテスト結果をレポートするテストツールを開発する場合などにはサブクラスで拡張することができます。-
startTest(test)¶ test を実行する直前に呼び出されます。
-
stopTest(test)¶ test の実行直後に、テスト結果に関わらず呼び出されます。
-
startTestRun()¶ 全てのテストが実行される前に一度だけ実行されます。
バージョン 3.1 で追加.
-
stopTestRun()¶ 全てのテストが実行された後に一度だけ実行されます。
バージョン 3.1 で追加.
-
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属性に追加します。
-
addSubTest(test, subtest, outcome)¶ サブテストが終了すると呼ばれます。 test はテストメソッドに対応するテストケースです。 subtest はサブテストを記述するカスタムの
TestCaseインスタンスです。outcome が
Noneの場合サブテストは成功です。 それ以外の場合は失敗で、sys.exc_info()が返す形式(type, value, traceback)の outcome を持つ例外を伴います。結果が成功の場合デフォルトの実装では何もせず、サブテストの失敗を通常の失敗として報告します。
バージョン 3.4 で追加.
-
-
class
unittest.TextTestResult(stream, descriptions, verbosity)¶ TextTestRunnerに使用されるTestResultの具象実装です。バージョン 3.2 で追加: このクラスは以前
_TextTestResultという名前でした。以前の名前はエイリアスとして残っていますが非推奨です。
-
unittest.defaultTestLoader¶ TestLoaderのインスタンスで、共用することが目的です。TestLoaderをカスタマイズする必要がなければ、新しいTestLoaderオブジェクトを作らずにこのインスタンスを使用します。
-
class
unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False)¶ 結果をストリームに出力する、基本的なテストランナーの実装です。 stream が
Noneの場合、デフォルトでsys.stderrが出力ストリームとして使われます。 このクラスはいくつかの設定項目があるだけで、基本的に非常に単純です。 グラフィカルなテスト実行アプリケーションでは、独自のテストランナーを実装してください。 テストランナーの実装は、 unittest に新しい機能が追加されランナーを構築するインターフェースが変更されたときに備えて**kwargsを受け取れるようにするべきです。デフォルトで無視 に設定されているとしても、このランナーのデフォルトでは
DeprecationWarning,PendingDeprecationWarning,ResourceWarning,ImportWarningを表示します。 unittest の非推奨メソッド で起きた非推奨警告も特別な場合として扱われ、警告フィルタが'default'もしくは'always'だったとき、対象の警告メッセージが出ないようにモジュールごとに1回だけ表示されます。 Python の-Wdオプションや-Waオプション (警告の制御 を参照してください) を使ったり、 warnings をNoneにしたりしておくと、この動作を上書きできます。バージョン 3.2 で変更:
warnings引数が追加されました。バージョン 3.2 で変更: インポート時でなくインスタンス化時にデフォルトのストリームが
sys.stderrに設定されます。バージョン 3.5 で変更: tb_locals 引数が追加されました。
-
_makeResult()¶ このメソッドは
run()で使われるTestResultのインスタンスを返します。このメソッドは明示的に呼び出す必要はありませんが、サブクラスでTestResultをカスタマイズすることができます。_makeResult()は、TextTestRunnerのコンストラクタでresultclass引数として渡されたクラスもしくはコーラブルオブジェクトをインスタンス化します。resultclassが指定されていない場合には、デフォルトでTextTestResultが使用されます。結果のクラスは以下の引数が渡されインスタンス化されます:stream, descriptions, verbosity
-
run(test)¶ このメソッドは TextTestRunner へのメインの公開インターフェースです。 このメソッドは
TestSuiteインスタンスあるいはTestCaseインスタンスを受け取ります。_makeResult()が呼ばれてTestResultが作成され、テストが実行され、結果が標準出力に表示されます。
-
-
unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None)¶ module から複数のテストを読み込んで実行するためのコマンドラインプログラム。この関数を使えば、簡単に実行可能なテストモジュールを作成する事ができます。一番簡単なこの関数の使い方は、以下の行をテストスクリプトの最後に置くことです:
if __name__ == '__main__': unittest.main()
より詳細な情報は verbosity 引数を指定して実行すると得られます:
if __name__ == '__main__': unittest.main(verbosity=2)
defaultTest 引数は、 argv にテスト名が指定されていない場合に実行する、ある1つのテストの名前もしくはテスト名のイテラブルです。 この引数を指定しないか
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 は、コマンドラインオプション にある同名のオプションと同じ効果のあるパラメータです。
warnings 引数では、テストの実行中に使うべき 警告フィルタ を指定します。 この引数が指定されない場合には、
-Wオプションが python に渡されていなければNoneのまま (警告の制御 を参照してください) で、そうでなければ'default'が設定されます。mainを呼び出すと、TestProgramのインスタンスが返されます。このインスタンスは、result属性にテスト結果を保持します。バージョン 3.1 で変更: exit パラメータが追加されました。
バージョン 3.2 で変更: verbosity、failfast、catchbreak、buffer、warnings 引数が追加されました。
バージョン 3.4 で変更: defaultTest 引数がテスト名のイテラブルも受け取るようになりました。
26.4.8.3.1. load_tests プロトコル¶
バージョン 3.2 で追加.
モジュールやパッケージには、load_tests と呼ばれる関数を実装できます。これにより、通常のテスト実行時やテストディスカバリ時のテストのロードされ方をカスタマイズできます。
テストモジュールが load_tests を定義していると、それが TestLoader.loadTestsFromModule() から呼ばれます。引数は以下です:
load_tests(loader, standard_tests, pattern)
pattern は loadTestsFromModule からそのまま渡されます。デフォルトは 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 を探します。
その関数が存在しない場合、他のディレクトリであるかのようにパッケージの中を再帰的に検索します。
その関数が存在した場合、パッケージのテストの検索をそちらに任せ、 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
バージョン 3.5 で変更: パッケージ名がデフォルトのパターンに適合するのが不可能なため、検索ではパッケージ名が pattern に適合するかのチェックは行われなくなりました。
26.4.9. クラスとモジュールのフィクスチャ¶
クラスレベルとモジュールレベルのフィクスチャが TestSuite に実装されました。
テストスイートが新しいクラスのテストを始める時、以前のクラス (あれば)の tearDownClass() を呼び出し、その後に新しいクラスの setUpClass() を呼び出します。
同様に、今回のテストのモジュールが前回のテストとは異なる場合、以前のモジュールの tearDownModule を実行し、次に新しいモジュールの setUpModule を実行します。
すべてのテストが実行された後、最後の tearDownClass と tearDownModule が実行されます。
なお、共有フィクスチャは、テストの並列化などの [潜在的な] 機能と同時にはうまくいかず、テストの分離を壊すので、気をつけて使うべきです。
unittest テストローダによるテスト作成のデフォルトの順序では、同じモジュールやクラスからのテストはすべて同じグループにまとめられます。これにより、setUpClass / setUpModule (など) は、一つのクラスやモジュールにつき一度だけ呼ばれます。この順序をバラバラにし、異なるモジュールやクラスのテストが並ぶようにすると、共有フィクスチャ関数は、一度のテストで複数回呼ばれるようにもなります。
共有フィクスチャは標準でない順序で実行されることを意図していません。
共有フィクスチャをサポートしたくないフレームワークのために、BaseTestSuite がまだ存在しています。
共有フィクスチャ関数のいずれかで例外が発生した場合、そのテストはエラーとして報告されます。
そのとき、対応するテストインスタンスが無いので(TestCase と同じインタフェースの) _ErrorHolder オブジェクトが生成され、エラーを表します。
標準 unittest テストランナーを使っている場合はこの詳細は問題になりませんが、あなたがフレームワークの作者である場合は注意してください。
26.4.9.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 例外であれば、そのクラスはエラーではなくスキップされたものとして報告されます。
26.4.10. シグナルハンドリング¶
バージョン 3.2 で追加.
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()が呼び出されます。
-
unittest.registerResult(result)¶ control-c 処理のために
TestResultを登録します。結果を登録するとそれに対する弱参照が格納されるので、結果がガベージコレクトされるのを妨げません。control-c 処理が有効でなければ、
TestResultオブジェクトの登録には副作用がありません。ですからテストフレームワークは、処理が有効か無効かにかかわらず、作成する全ての結果を無条件に登録できます。
-
unittest.removeResult(result)¶ 登録された結果を削除します。一旦結果が削除されると、control-c が押された際にその結果オブジェクトに対して
stop()が呼び出されなくなります。
-
unittest.removeHandler(function=None)¶ 引数なしで呼び出されたとき、control-c ハンドラがインストールされていると、この関数はそれを取り除きます。この関数は、テストが実行されている間だけ一時的にハンドラを取り除くテストデコレータとしても使えます:
@unittest.removeHandler def test_signal_handling(self): ...
