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() メソッドを持つオブジェクトです。このメソッドは引数として TestCaseTestSuite オブジェクトを受け取り、テスト結果を TestResult オブジェクトで戻します。 unittest ではデフォルトでテスト結果を標準エラーに出力する TextTestRunner をサンプルとして実装しています。これ以外のランナー (グラフィックインターフェース用など) を実装する場合でも、特別なクラスから派生させて実装する必要はありません。

参考

Module doctest
もうひとつのテストをサポートするモジュールで、本モジュールと趣きが異なっています。
unittest2: ユニットテストの新機能の Python 2.4-2.6 向けバックポート
Python 2.7 になり多くの機能が unittest に追加されました。特に、テストディスカバリが追加されました。 unittest2 を導入する事で以前のバージョンの Python でもこれらの機能を使えます。
Simple Smalltalk Testing: With Patterns
Kent Beck のテスティングフレームワークに関する原論文で、ここに記載されたパターンを unittest が使用しています。
Nosepy.test
サードパーティのユニットテストフレームワークで軽量な文法でテストを書くことができます。例えば、 assert func(10) == 42 のように書きます。
The Python Testing Tools Taxonomy
多くの Python のテストツールが一覧で紹介されています。ファンクショナルテストのフレームワークやモックライブラリも掲載されています。
Testing in Python Mailing List
Python でテストやテストツールについての議論に特化したグループです。

25.3.1. 基礎的な例

unittest モジュールには、テストの開発や実行の為の優れたツールが用意されており、この節では、その一部を紹介します。ほとんどのユーザとっては、ここで紹介するツールだけで十分でしょう。

以下は、 random モジュールの三つの関数をテストするスクリプトです。:

import random
import unittest

class TestSequenceFunctions(unittest.TestCase):

    def setUp(self):
        self.seq = range(10)

    def test_shuffle(self):
        # make sure the shuffled sequence does not lose any elements
        random.shuffle(self.seq)
        self.seq.sort()
        self.assertEqual(self.seq, range(10))

        # should raise an exception for an immutable sequence
        self.assertRaises(TypeError, random.shuffle, (1,2,3))

    def test_choice(self):
        element = random.choice(self.seq)
        self.assertTrue(element in self.seq)

    def test_sample(self):
        with self.assertRaises(ValueError):
            random.sample(self.seq, 20)
        for element in random.sample(self.seq, 5):
            self.assertTrue(element in self.seq)

if __name__ == '__main__':
    unittest.main()

テストケースは、 unittest.TestCase のサブクラスとして作成します。メソッド名が test で始まる三つのメソッドがテストです。テストランナーはこの命名規約によってテストを行うメソッドを検索します。

これらのテスト内では、予定の結果が得られていることを確かめるために assertEqual() を、条件のチェックに assertTrue() を、例外が発生する事を確認するために assertRaises() をそれぞれ呼び出しています。 assert 文の代わりにこれらのメソッドを使用すると、テストランナーでテスト結果を集計してレポートを作成する事ができます。

setUp() メソッドが定義されている場合、テストランナーは各テストを実行する前に setUp() メソッドを呼び出します。同様に、 tearDown() メソッドが定義されている場合は各テストの実行後に呼び出します。上のサンプルでは、それぞれのテスト用に新しいシーケンスを作成するために setUp() を使用しています。

サンプルの末尾が、簡単なテストの実行方法です。 unittest.main() は、テストスクリプトのコマンドライン用インターフェースです。コマンドラインから起動された場合、上記のスクリプトから以下のような結果が出力されます:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

簡略化した結果を出力したり、コマンドライン以外からも起動する等のより細かい制御が必要であれば、 unittest.main() を使用せずに別の方法でテストを実行します。例えば、上記サンプルの最後の2行は以下のように書くことができます:

suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
unittest.TextTestRunner(verbosity=2).run(suite)

変更後のスクリプトをインタープリタや別のスクリプトから実行すると、以下の出力が得られます:

test_choice (__main__.TestSequenceFunctions) ... ok
test_sample (__main__.TestSequenceFunctions) ... ok
test_shuffle (__main__.TestSequenceFunctions) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.110s

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

引数として渡す事ができるのは、テストが定義されたモジュール名、もしくはクラス、メソッドのフルパス名です。

テスト実行時に(冗長な)詳細を表示するには -f フラグを渡します。:

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 directory

ディスカバリを開始するディレクトリ (デフォルトは ‘.’)

-p pattern

テストファイル名を識別するパターン (デフォルトは ‘test*.py’)

-t 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.pyfoo.bar.baz としてインポートされます。

もしパッケージをグローバルにインストールしていて、インストールしたのとは異なるパッケージのコピーをディスカバリしようとすると、間違った場所からインポートして しまうかもしれません 。このような状態になるとテストディスカバリは警告を出し、停止します。

スタートディレクトリとしてディレクトリのパスではなくパッケージ名を指定した場合は、いずれかの場所からインポートされます。この場合は警告が表示されません。

テストモジュールとテストパッケージは、テストのロードとディスカバリをカスタマイズすることができます。そのために load_tests プロトコル を使用します。

25.3.4. テストの構成

ユニットテストの基礎となる構築要素は、 test case — セットアップと正しさのチェックを行う、独立したシナリオ — です。 unittest では、テストケースは unittest モジュールの TestCase クラスのインスタンスで示します。テストケースを作成するには TestCase のサブクラスを記述するか、または FunctionTestCase を使用します。

TestCase から派生したクラスのインスタンスは、このオブジェクトだけで一件のテストと初期設定・終了処理を行います。

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')

何らかのテストを行う場合、ベースクラス TestCaseassert*() メソッドを使用してください。テストが失敗すると例外が送出され、 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 と呼びます。

JUnit では、多数の小さなテストケースを同じテスト環境で実行する場合、全てのテストについて DefaultWidgetSizeTestCase のような SimpleWidgetTestCase のサブクラスを作成する必要があります。これは時間のかかる、うんざりする作業ですので、 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 は、 unittestTestSuite クラスで作成します。:

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 インスタンスには TestSuite と同じように 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)

既存のテストスイートからの移行を容易にするため、 unittestAssertionError の送出でテストの失敗を示すような書き方もサポートしています。しかしながら、 TestCase.fail*() および TestCase.assert*() メソッドを使って明確に書くことが推奨されています。 unittest の将来のバージョンでは、 AssertionError は別の目的に使用される可能性が有ります。

注釈

FunctionTestCase を使って既存のテストを unittest ベースのテスト体系に変換することができますが、この方法は推奨されません。時間を掛けて TestCase のサブクラスに書き直した方が将来的なテストのリファクタリングが限りなく易しくなります。

既存のテストが doctest を使って書かれている場合もあるでしょう。その場合、 doctestDocTestSuite クラスを提供します。このクラスは、既存の doctestベースのテストから、自動的に unittest.TestSuite のインスタンスを作成します。

25.3.6. テストのスキップと意図的な失敗

バージョン 2.7 で追加.

unittest は特定のテストメソッドやテストクラス全体をスキップする仕組みを備えています。さらに、この機能はテスト結果を「意図的な失敗」とすることができ、テストが失敗しても 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)

テストクラスは以下のようにメソッドをスキップすることができます。

@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("{0!r} doesn't have {1!r}".format(obj, attr))

以下のデコレータはテストのスキップと意図的な失敗を実装しています。

unittest.skip(reason)

デコレートしたテストを無条件でスキップします。 reason にはテストをスキップした理由を記載します。

unittest.skipIf(condition, reason)

condition が真の場合に、デコレートしたテストをスキップします。

unittest.skipUnless(condition, reason)

condition が偽の場合に、デコレートしたテストをスキップします。

unittest.expectedFailure()

テストの失敗が意図的であることを表します。該当のテストが失敗しても、そのテストは失敗にカウントされません。

スキップしたテストの前後では、 setUp() および tearDown() は実行されません。同様に、スキップしたテストクラスの前後では、 setUpClass() および tearDownClass() は実行されません。

25.3.7. クラスと関数

この節では、 unittest モジュールのAPIの詳細について説明します。

25.3.7.1. テストクラス

class unittest.TestCase([methodName])

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()

テストフィクスチャの準備のために呼び出されるメソッドです。テストメソッドの直前に呼び出されます。このメソッドを実行中に例外が発生した場合、テストの失敗ではなくエラーとされます。デフォルトの実装では何も行いません。

tearDown()

テストメソッドが実行され、結果が記録された直後に呼び出されるメソッドです。このメソッドはテストメソッドで例外が投げられても呼び出されます。そのため、サブクラスでこのメソッドを実装する場合は、内部状態を確認することが必要になるでしょう。メソッドを実行中に例外が発生した場合、テストの失敗ではなくエラーとみなされます。このメソッドは、テストの結果に関わらず 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 クラスには、条件の確認と失敗のレポートのために以下のメソッドが定義されています。

メソッド 確認事項 初出
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)

firstsecond が等しいことをテストします。両者が比較出来ない場合は、テストが失敗します。

さらに、 firstsecond が厳密に同じ型であり、その型が、list, tuple, dict, set, frozenset もしくは unicode のいずれか、または addTypeEqualityFunc() で比較関数が登録されている型の場合には、デフォルトのエラーメッセージを生成するために、その型特有の比較関数が呼ばれます。( list of type-specific methods も参照してください。)

バージョン 2.7 で変更: 型特有の比較関数の自動呼び出しを追加。

assertNotEqual(first, second, msg=None)

firstsecond が等しくないことをテストします。両者が比較出来ない場合は、テストが失敗します。

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)

firstsecond が同じオブジェクトであること(そうでないこと)をテストします。

バージョン 2.7 で追加.

assertIsNone(expr, msg=None)
assertIsNotNone(expr, msg=None)

expr が None であること(そうでないこと)をテストします。

バージョン 2.7 で追加.

assertIn(first, second, msg=None)
assertNotIn(first, second, msg=None)

firstsecond に含まれること(そうでないこと)をテストします。

バージョン 2.7 で追加.

assertIsInstance(obj, cls, msg=None)
assertNotIsInstance(obj, cls, msg=None)

objcls のインスタンスであること(そうでないこと)をテストします。(この cls は、 isinstance() が扱うことのできる、クラスもしくはクラスのタプルである必要があります。)

バージョン 2.7 で追加.

例外と例外発生時の警告を確認するために以下のメソッドを使用することができます。

メソッド 確認事項 初出
assertRaises(exc, fun, *args, **kwds) fun(*args, **kwds) raises exc  
assertRaisesRegexp(exc, re, fun, *args, **kwds) fun(*args, **kwds) raises exc and the message matches re 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 は正規表現オブジェクトか、 re.search() が扱える正規表現が書かれた文字列である必要があります。例えば以下のようになります。

self.assertRaisesRegexp(ValueError, 'invalid literal for.*XYZ$',
                        int, 'XYZ')

もしくは

with self.assertRaisesRegexp(ValueError, 'literal'):
   int('XYZ')

バージョン 2.7 で追加.

さらに特有の確認を行うために以下のメソッドが用意されています。

メソッド 確認項目 初出
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, re) regex.search(s) 2.7
assertNotRegexpMatches(s, re) not regex.search(s) 2.7
assertItemsEqual(a, b)

意味的に sorted(a) == sorted(b) ですが、ハッシュ不能オブジェクトでも動作

2.7
assertDictContainsSubset(a, b) all the key/value pairs in a exist in b 2.7
assertAlmostEqual(first, second, places=7, msg=None, delta=None)
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)

firstsecond が近似的に等しい(等しくない)ことをテストします。この比較は、places (デフォルト7)で指定した小数位で丸めた差分をゼロと比べることでおこないます。これらのメソッドは、( round() と同様に) 小数位 を指定するのであって、有効桁数 を指定するのではないことに注意してください。

places の代わりに delta が渡された場合には、 firstsecond の差分が delta より大きい(小さい)ことをテストします。

deltaplaces の両方が指定された場合は 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)

firstsecond と比べて、メソッド名に対応して >, >=, < もしくは <= であることをテストします。そうでない場合はテストが失敗します。

>>> 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)

シーケンス expectedactual と同じ要素を含んでいることをテストします。要素の順序はテスト結果に影響しません。要素が含まれていない場合には、シーケンスの差分がエラーメッセージとして表示されます。

actualexpected の比較では、重複した要素は無視 されません 。両者に同じ数の要素が含まれていることを検証します。このメソッドは assertEqual(sorted(expected), sorted(actual)) と同等に振る舞うことに加えて、ハッシュ化できないオブジェクトのシーケンスでも動作します。

バージョン 2.7 で追加.

assertDictContainsSubset(expected, actual, msg=None)

辞書 actual のキー/バリューペアが expected のスーパーセットになっているかどうかをテストします。そうなっていない場合には、足りないキーとバリューの一覧がエラーメッセージに表示されます。

バージョン 2.7 で追加.

バージョン 3.2 で撤廃.

assertEqual() メソッドは、同じ型のオブジェクトの等価性確認のために、型ごとに特有のメソッドにディスパッチします。これらのメソッドは、ほとんどの組み込み型用のメソッドは既に実装されています。さらに、 addTypeEqualityFunc() を使う事で新たなメソッドを登録することができます。

addTypeEqualityFunc(typeobj, function)

assertEqual() で呼び出される型特有のメソッドを登録します。登録するメソッドは、 比較する2つのオブジェクトの型がが厳密に typeobj と同じ(サブクラスでもいけません)の場合に等価性を確認します。 functionassertEqual() と同様に、2つの位置固定引数と、3番目に msg=None のキーワード引数を取れる必要があります。このメソッドは、始めの2つに指定したパラメータ間の差分を検出した時に self.failureException(msg) の例外を投げる必要があります。この例外を投げる際は、出来る限り、エラーの内容が分かる有用な情報と差分の詳細をエラーメッセージに含めてください。

バージョン 2.7 で追加.

assertEqual() が自動的に呼び出す型特有のメソッドの概要を以下の表示に記載しています。これらのメソッドは通常は直接呼び出す必要がないことに注意が必要です。

メソッド 比較の対象 初出
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)

複数行の文字列 first が文字列 second と等しいことをテストします。等しくない場合には、両者の差分がハイライトされてエラーメッセージに表示されます。このメソッドは、デフォルトで、 assertEqual() が string を比較するときに自動的に使用します。

バージョン 2.7 で追加.

assertSequenceEqual(seq1, seq2, msg=None, seq_type=None)

2つのシーケンスが等しいことをテストします。 seq_type が指定された場合、 seq1seq2seq_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() です。

maxDiffNone を指定すると差分表示の上限がなくなります。

バージョン 2.7 で追加.

テストフレームワークは、テスト情報を収集するために以下のメソッドを使用します。

countTestCases()

テストオブジェクトに含まれるテストの数を返します。 TestCase インスタンスは常に 1 を返します。

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 で撤廃: 表の第2列のエイリアスを廃止予定

25.3.7.2. テストのグルーピング

class unittest.TestSuite(tests=())

このクラスは、個々のテストケースやテストスイートの集約を示します。通常のテストケースと同じようにテストランナーで実行するためのインタフェースを備えています。 TestSuite インスタンスを実行することはスイートの繰り返しを使って個々のテストを実行することと同じです。

引数 tests が指定された場合、それはテストケースに亘る繰り返し可能オブジェクトまたは内部でスイートを組み立てるための他のテストスイートでなければなりません。後からテストケースやスイートをコレクションに付け加えるためのメソッドも提供されています。

TestSuiteTestCase オブジェクトのように振る舞います。違いは、スイートにはテストを実装しない点にあります。代わりに、テストをまとめてグループ化して、同時に実行します。 TestSuite のインスタンスにテスト追加するためのメソッドが用意されています。

addTest(test)

TestCase 又は TestSuite のインスタンスをスイートに追加します。

addTests(tests)

イテラブル tests に含まれる全ての TestCase 又は TestSuite のインスタンスをスイートに追加します。

このメソッドは test 上のイテレーションをしながらそれぞれの要素に addTest() を呼び出すのと等価です。

TestSuite クラスは TestCase と以下のメソッドを共有します。

run(result)

スイート内のテストを実行し、結果を result で指定した結果オブジェクトに収集します。 TestCase.run() と異なり、 TestSuite.run() では必ず結果オブジェクトを指定する必要があります。

debug()
このスイートに関連づけられたテストを結果を収集せずに実行します。これによりテストで送出された例外は呼び出し元に伝わるようになり、デバッガの下でのテスト実行をサポートできるようになります。
countTestCases()

このテストオブジェクトによって表現されるテストの数を返します。これには個別のテストと下位のスイートも含まれます。

__iter__()

TestSuite でグループ化されたテストはイテレータでアクセスできます。サブクラスは __iter__() をオーバーライドすることで、テストへのアクセスを定義します。1つのメソッド内でこのメソッドは何度も呼ばれる可能性があることに注意してください(例えば、テスト数のカウントと等価性の比較)。そのため、イテレーションを繰り返しても同じテストを返すように実装してください。

バージョン 2.7 で変更: 以前のバージョンでは TestSuite はイテレータではなく、直接テストにアクセスしていました。そのため、 __iter__() をオーバーラードしてもテストにアクセスできませんでした。

通常、 TestSuiterun() メソッドは TestRunner が起動するため、ユーザが直接実行する必要はありません。

25.3.7.3. テストのロードと起動

class unittest.TestLoader

TestLoader クラスはクラスとモジュールからテストスイートを生成します。通常、このクラスのインスタンスを明示的に生成する必要はありません。 unittest モジュールの unittest.defaultTestLoader を共用インスタンスとして使用することができます。しかし、このクラスのサブクラスやインスタンスで、属性をカスタマイズすることができます。

TestLoader のオブジェクトには以下のメソッドがあります。

loadTestsFromTestCase(testCaseClass)

TestCase の派生クラス testCaseClass に含まれる全テストケースのスイートを返します。

loadTestsFromModule(module)

指定したモジュールに含まれる全テストケースのスイートを返します。このメソッドは module 内の TestCase 派生クラスを検索し、見つかったクラスのテストメソッドごとにクラスのインスタンスを作成します。

注釈

TestCase クラスを基底クラスとしてクラス階層を構築すると fixture や補助的な関数をうまく共用することができますが、基底クラスに直接インスタンス化できないテストメソッドがあると、この loadTestsFromModule() を使うことができません。この場合でも、 fixture が全て別々で定義がサブクラスにある場合は使用することができます。

モジュールが load_tests 関数を用意している場合、この関数がテストのロードに使われます。これによりテストのロードをカスタマイズできます。これが load_tests プロトコル です。

バージョン 2.7 で変更: load_tests をサポートしました。

loadTestsFromName(name, module=None)

文字列で指定される全テストケースを含むスイートを返します。

name には “ドット修飾名” でモジュールかテストケースクラス、テストケースクラス内のメソッド、 TestSuite インスタンスまたは TestCaseTestSuite のインスタンスを返す呼び出し可能オブジェクトを指定します。このチェックはここで挙げた順番に行なわれます。すなわち、候補テストケースクラス内のメソッドは「呼び出し可能オブジェクト」としてではなく「テストケースクラス内のメソッド」として拾い出されます。

例えば 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 中の全てのメソッド名を含むソート済みシーケンスを返します。 testCaseClassTestCase のサブクラスでなければなりません。

discover(start_dir, pattern='test*.py', top_level_dir=None)

すべてのテストモジュールを指定された開始ディレクトリから検索して返します。再帰的にサブディレクトリも検索します。 pattern にマッチしたテストファイルだけがロードの対象になります。(シェルスタイルのパターンマッチングが使われます。)その中で、インポート可能なもジュール(つまりPythonの識別子として有効であるということです)がロードされます。

すべてのテストモジュールはプロジェクトのトップレベルからインポート可能である必要があります。開始ディレクトリがトップレベルディレクトリでない場合は、トップレベルディレクトリが分離できなくてはいけません。

例えば、シンタックスエラーなどで、モジュールのインポートに失敗した場合、エラーが記録され、ディスカバリ自体は続けられます。

テストパッケージ名( __init__.py の置かれたディレクトリ名) がパターンにマッチした場合、 load_tests 関数がチェックされます。この関数が存在している場合、この関数に loader, tests, pattern が渡され呼び出されます。

load_tests が存在して、ディスカバリがパッケージ内を再帰的な検索を続けている途中で ない 場合、 load_tests はそのパッケージ内の全てのテストをロードする責務を担います。

意図的にパターンはローダの属性として保持されないようになっています。それにより、パッケージが自分自身のディスカバリを続ける事ができます。 top_level_dir は保持されるため、 loader.discover() に引数として渡す必要はありません。

バージョン 2.7 で追加.

以下の属性は、サブクラス化またはインスタンスの属性値を変更して TestLoader をカスタマイズする場合に使用します。

testMethodPrefix

テストメソッドの名前と判断されるメソッド名の接頭語を示す文字列。デフォルト値は 'test' です。

この値は getTestCaseNames() と全ての loadTestsFrom*() メソッドに影響を与えます。

sortTestMethodsUsing

getTestCaseNames() および全ての loadTestsFrom*() メソッドでメソッド名をソートする際に使用する比較関数。デフォルト値は組み込み関数 cmp() です。ソートを行なわないようにこの属性に None を指定することもできます。

suiteClass

テストのリストからテストスイートを構築する呼び出し可能オブジェクト。メソッドを持つ必要はありません。デフォルト値は TestSuite です。

この値は全ての loadTestsFrom*() メソッドに影響を与えます。

class unittest.TestResult

このクラスはどのテストが成功しどのテストが失敗したかという情報を収集するのに使います。

TestResult は、複数のテスト結果を記録します。 TestCase クラスと TestSuite クラスのテスト結果を正しく記録しますので、テスト開発者が独自にテスト結果を管理する処理を開発する必要はありません。

unittest を利用したテストフレームワークでは、 TestRunner.run() が返す TestResult インスタンスを参照し、テスト結果をレポートします。

以下の属性は、テストの実行結果を検査する際に使用することができます。

errors

TestCase と例外のトレースバック情報をフォーマットした文字列の 2 要素タプルからなるリスト。それぞれのタプルは予想外の例外を送出したテストに対応します。

バージョン 2.2 で変更: sys.exc_info() の結果ではなく、フォーマットしたトレースバックを保存します。

failures

TestCase と例外のトレースバック情報をフォーマットした文字列の 2 要素タプルからなるリスト。それぞれのタプルは TestCase.fail*()TestCase.assert*() メソッドを使って見つけ出した失敗に対応します。

バージョン 2.2 で変更: sys.exc_info() の結果ではなく、フォーマットしたトレースバックを保存します。

skipped

TestCase インスタンスと理由の文字列の2要素タプルからなるリストを保持します。

バージョン 2.7 で追加.

expectedFailures

TestCase と例外のトレースバック情報をフォーマットした文字列の 2 要素タプルからなるリスト。それぞれのタプルは意図した失敗に対応します。

unexpectedSuccesses

意図した失敗のマークが付いていながら成功してしまった TestCase のインスタンスのリスト。

shouldStop

True が設定されると stop() によりテストの実行が停止します。

testsRun

これまでに実行したテストの総数です。

buffer

True が設定されると、 sys.stdoutsys.stderr は、 startTest() から stopTest() が呼ばれるまでの間バッファリングされます。実際に、結果が sys.stdoutsys.stderr に出力されるのは、テストが失敗するかエラーが発生した時になります。表示の際には、全ての失敗 / エラーメッセージが表示されます。

バージョン 2.7 で追加.

failfast

True が設定されると、 stop() が始めの失敗もしくはエラーの時に呼び出され、テストの実行が終了します。

バージョン 2.7 で追加.

wasSuccessful()

これまでに実行したテストが全て成功していれば True を、それ以外なら False を返します。

stop()

このメソッドを呼び出して TestResultshouldStop 属性に True をセットすることで、実行中のテストは中断しなければならないというシグナルを送ることができます。 TestRunner オブジェクトはこのフラグを尊重してそれ以上のテストを実行することなく復帰しなければなりません。

たとえばこの機能は、ユーザのキーボード割り込みを受け取って TextTestRunner クラスがテストフレームワークを停止させるのに使えます。 TestRunner の実装を提供する対話的なツールでも同じように使用することができます。

以下のメソッドは内部データ管理用のメソッドですが、対話的にテスト結果をレポートするテストツールを開発する場合などにはサブクラスで拡張することができます。

startTest(test)

test を実行する直前に呼び出されます。

stopTest(test)

test の実行直後に、テスト結果に関わらず呼び出されます。

startTestRun(test)

全てのテストが実行される前に一度だけ実行されます。

バージョン 2.7 で追加.

stopTestRun(test)

全てのテストが実行された後に一度だけ実行されます。

バージョン 2.7 で追加.

addError(test, err)

テスト test 実行中に、想定外の例外が発生した場合に呼び出されます。 errsys.exc_info() が返すタプル (type, value, traceback) です。

デフォルトの実装では、タプル、 (test, formatted_err) をインスタンスの errors 属性に追加します。ここで、 formatted_err は、 err から導出される、整形されたトレースバックです。

addFailure(test, err)

テストが失敗した場合に呼び出されます。 errsys.exc_info() が返すタプル (type, value, traceback) です。

デフォルトの実装では、タプル、 (test, formatted_err) をインスタンスの errors 属性に追加します。ここで、 formatted_err は、 err から導出される、整形されたトレースバックです。

addSuccess(test)

テストケース test が成功した場合に呼び出されます。

デフォルトの実装では何もしません。

addSkip(test, reason)

test がスキップされた時に呼び出されます。 reason はスキップの際に渡された理由の文字列です。

デフォルトの実装では、 (test, reason) のタプルをインスタンスの skipped 属性に追加します。

addExpectedFailure(test, err)

expectedFailure() のデコレータでマークされた test が失敗した時に呼び出されます。

デフォルトの実装では (test, formatted_err) のタプルをインスタンスの expectedFailures に追加します。ここで formatted_errerr から派生した整形されたトレースバックです。

addUnexpectedSuccess(test)

expectedFailure() のデコレータでマークされた test が成功した時に呼び出されます。

デフォルトの実装ではテストをインスタンスの unexpectedSuccesses 属性に追加します。

unittest.defaultTestLoader

TestLoader のインスタンスで、共用することが目的です。 TestLoader をカスタマイズする必要がなければ、新しい TestLoader オブジェクトを作らずにこのインスタンスを使用します。

class unittest.TextTestRunner(stream=sys.stderr, descriptions=True, verbosity=1)

実行結果を標準エラーに出力する、単純なテストランナー。いくつかの設定項目がありますが、非常に単純です。グラフィカルなテスト実行アプリケーションでは、独自のテストランナーを作成してください。

_makeResult()

このメソッドは run() で使われる TestResult のインスタンスを返します。このメソッドは明示的に呼び出す必要はありませんが、サブクラスで TestResult をカスタマイズすることができます。

_makeResult() は、 TextTestRunner のコンストラクタで resultclass 引数として渡されたクラスもしくはコーラブルオブジェクトをインスタンス化します。 resultclass が指定されていない場合には、デフォルトで TextTestResult が使用されます。結果のクラスは以下の引数が渡されインスタンス化されます。

stream, descriptions, verbosity
unittest.main([module[, defaultTest[, argv[, testRunner[, testLoader[, exit[, verbosity[, failfast[, catchbreak[, buffer]]]]]]]]]])

テストを実行するためのコマンドラインプログラム。この関数を使えば、簡単に実行可能なテストモジュールを作成する事ができます。一番簡単なこの関数の使い方は、以下の行をテストスクリプトの最後に置くことです。

if __name__ == '__main__':
    unittest.main()

より詳細な情報は verbosity 引数を指定して実行すると得られます。

if __name__ == '__main__':
    unittest.main(verbosity=2)

引数、 testRunner は、test runner class、あるいは、そのインスタンスのどちらでも構いません。でフォルトでは main はテストが成功したか失敗したかに対応した終了コードと共に sys.exit() を呼び出します。

main は、 exit=False を指定する事で対話的なインタプリタから使用することもできます。この引数を指定すると、 sys.exit() を呼ばずに、結果のみを出力します。

>>> from unittest import main
>>> main(module='test_module', exit=False)

failfast, catchbreakbuffer は、 コマンドラインオプション にある同名のオプションと同じ効果のあるパラメータです。

main を呼び出すと、 TestProgram のインスタンスが返されます。このインスタンスは、 result 属性にテスト結果を保持します。

バージョン 2.7 で変更: exit, verbosity, failfast, catchbreakbuffer パラメータが追加されました。

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__.pyload_tests があるか調べられます。

注釈

デフォルトのパターンは ‘test*.py’ です。これは、 ‘test’ で始まる全ての Python ファイルにマッチしますが、テストディレクトリには絶対にマッチ しません

‘test*’ のようなパターンは、モジュールだけでなくテストパッケージにもマッチします。

パッケージ __init__.pyload_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 が実行されます。

すべてのテストが実行された後、最後の tearDownClasstearDownModule が実行されます。

なお、共通の修正は、テストの並列化などの [潜在的な] 機能と同時にはうまくいかず、テストの分離を中断します。気をつけて使うべきです。

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 も実行されません。スキップされたクラスは setUpClasstearDownClass も実行されません。例外が SkipTest 例外であると、そのクラスはエラーとしてではなくスキップされたものとして報告されます。

25.3.8.2. setUpModule と tearDownModule

これらは、関数として実装されなければなりません:

def setUpModule():
    createConnection()

def tearDownModule():
    closeConnection()

setUpModule の中で例外が送出されたら、モジュール内のテストは実行されず、 tearDownModule も実行されません。例外が 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)

引数なしで呼び出されたとき、control-c ハンドラがインストールされていると、この関数はそれを取り除きます。この関数は、テストが実行されている間だけ一時的にハンドラを取り除くテストデコレータとしても使えます。

@unittest.removeHandler
def test_signal_handling(self):
    ...

バージョン 2.7 で追加.