ようへいの日々精進XP

よかろうもん

Python の unittest で任意の関数 "だけ" テストしたい

以下のような...

環境において...

$ python --version
Python 3.6.4

コードは...

def foo():
   return True
   
def bar():
   return True

そして, テストを...

import unittest
import sample

class SampleTest(unittest.TestCase):

    def test_foo(self):
        self.assertTrue(sample.foo())

    def test_bar(self):
        self.assertTrue(sample.bar())

上記のように書きましたとさ.

これらのファイルを以下のように配置しました.

$ tree .
.
├── sample.py
└── tests
    └── test_sample.py

1 directory, 2 files

普通にテストを実行する場合

以下のように.

$ python -m unittest tests.test_sample
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

LGTM ですね.

では, 任意の関数だけテストしたい場合

に, どのように実行すれば良いのかというと, 以下のように クラス名.テスト関数 を指定すれば良いことが解った.

$ python -m unittest tests.test_sample.SampleTest.test_foo
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

詳細は 26.4.2. コマンドラインインターフェイス が参考なった.

逆に任意の関数だけスキップしたい場合にどうするのかというと...

テストコード内には, 以下のようにデコレータに unittest.skip を付けてあげれば良い.

import unittest
import sample

class SampleTest(unittest.TestCase):

    @unittest.skip('ごめんくさい')
    def test_foo(self):
        self.assertTrue(sample.foo())

    def test_bar(self):
        self.assertTrue(sample.bar())

実行すると, 以下のように s が出力される.

$ python -m unittest tests.test_sample
.s
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK (skipped=1)

コマンドラインからスキップを指定することはドキュメントを確認する限りだと出来無さそうなので諦めた.

尚, スキップする際に付与するデコレータには以下のような種類がある (ことをドキュメントを読んで知った).

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

上記, ドキュメントより引用させて頂いた.

その他の unittest 起動方法

指定した複数の関数だけテストしたい

以下のようなファイル構成だった場合...

$ tree .
.
├── sample.py
└── tests
    ├── test_sample1.py
    ├── test_sample2.py
    └── test_sample3.py

1 directory, 4 files

この中から test_sample1.py と test_sample2.py だけテストしたい.

$ python -m unittest tests.test_sample1 tests.test_sample2
..F.
======================================================================
FAIL: test_bar (tests.test_sample2.SampleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/path/to/tests/test_sample2.py", line 10, in test_bar
    self.assertFalse(sample.bar())
AssertionError: True is not false

----------------------------------------------------------------------
Ran 4 tests in 0.001s

FAILED (failures=1)

tests.${テストモジュール名} tests.${テストモジュール名} という感じでテストモジュールをスペースで区切れば良い.

指定したパスのテストモジュール (テストファイル) 全てのテストをしたい

上記と同様のファイル構成の場合...

$ python -m unittest discover --start-directory tests
..F...
======================================================================
FAIL: test_bar (test_sample2.SampleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/path/to/tests/test_sample2.py", line 10, in test_bar
    self.assertFalse(sample.bar())
AssertionError: True is not false

----------------------------------------------------------------------
Ran 6 tests in 0.001s

FAILED (failures=1)

discover サブコマンドを利用することで, --start-directory で指定したディレクトリ以下のファイルをテストモジュール対象としてテストが実行される.

以上

メモでした.

ふむふむ.