Python
unittest
Python3

Pythonのunittestでまとめてテストを実行する方法

More than 1 year has passed since last update.

はじめに

Pythonでunittestを実行する(初心者用)でunittestの使い方を説明しました。使っているうちに複数のテストをまとめてテストしたくなり整理しました。つまりTestSuiteの使い方です。
公式ドキュメントと「[Python] unittestモジュールでテストスイートを実現する2つの方法」を参考にしました。
※動作確認は、Python3.5.3で行ってます。

ディレクトリ構成

.
├─sample_a.py
└─tests
  ├─__init__.py
  ├─test_samplea.py
  ├─test_sampleb.py
  ├─samplec.py
  └─sample_suite.py

サンプルソース

※実行結果がわかりやすいようにサンプルソースの中はprintだけです。

sample_a.py
class SampleA():
  def hello(self):
    print('Hello, I am sample of a!')
test_samplea.py
import unittest

from sample_a import SampleA


class TestSampleA(unittest.TestCase):
  def test_a1(self):
    print('Test sample A1')
    a = SampleA()
    a.hello()

  def test_a2(self):
    print('Test sample A2')

  def a3(self):
    print('Test sample A3')
test_sampleb.py
import unittest


class TestSampleB(unittest.TestCase):
  def test_b1(self):
    print('Test sample B1')

  def test_b2(self):
    print('Test sample B2')

  def b3(self):
    print('Test sample B3')
samplec.py
import unittest


class SampleC(unittest.TestCase):
  def test_c1(self):
    print('Test sample C1')

  def test_c2(self):
    print('Test sample C2')

  def c3(self):
    print('Test sample C3')
sample_suite.py
import unittest

from . import test_samplea
from . import test_sampleb
from . import samplec


def suite():
  suite = unittest.TestSuite()
  suite.addTest(test_samplea.TestSampleA('test_a1'))
  suite.addTest(test_samplea.TestSampleA('a3'))
  suite.addTest(unittest.makeSuite(test_sampleb.TestSampleB))
  suite.addTest(samplec.SampleC('test_c1'))
  return suite


if __name__ == '__main__':
  runner = unittest.TextTestRunner()
  test_suite = suite()
  runner.run(test_suite)

1つテストを実行する

python -m unittest tests.test_samplea
実行結果は以下です。

Test sample A1
Hello, I am sample of a!
.Test sample A2
.
----------------------------------------------------------------------
Ran 2 tests in 0.003s

OK

出力結果から、test_a1とtest_a2のテストメソッドが実行されていることがわかります。
a3のメソッドのテストは実行されていません。

まとめてテストを実行する

python -m unittest
実行結果は以下です。

Test sample A1
Hello, I am sample of a!
.Test sample A2
.Test sample B1
.Test sample B2
.
----------------------------------------------------------------------
Ran 4 tests in 0.006s

OK

テスト結果から、test_samplea.pyとtest_sampleb.pyのテストが実行されていることがわかります。
samplec.pyのテストは実行されていません。
testから始まるファイルで、testから始まるメソッドのテストがまとめて実行されています。
※この方法はテストディスカバリを使っていて、以下のコマンドと同じ意味です。
python -m unittest discover
この仕組みを使うと、testsディレクトリのテストを認識するために、__init__.pyが必要です。
Python3では__init__.pyがなくても、パッケージと認識されるので、作成しない場合があると思います。テストディスカバリを使う場合は必要になりますので、注意が必要です。

自分で決めたテストのみ実行する

python -m tests.sample_suite
※python -m unittestでの実行出ないことに注意!
実行結果は以下です。

Test sample A1
Hello, I am sample of a!
.Test sample A3
.Test sample B1
.Test sample B2
.Test sample C1
.
----------------------------------------------------------------------
Ran 5 tests in 0.006s

OK

addTestで追加したテストが実行されています。
testから始まってないテストメソッド(a3)やtestから始まってないテストファイル(samplec.py)も実行されています。
テストの追加方法はメソッドごとの追加
suite.addTest(test_samplea.TestSampleA('test_a1'))

クラスごとの追加
suite.addTest(unittest.makeSuite(test_sampleb.TestSampleB))
があります。

まとめ

テストディスカバリの方法は何も設定せずにテストを実行できるため、とても便利です。
ただしテストの数が多くなってきたり、処理に時間がかかるテストが追加されるとテストを除きたくなるので、自分で決めたテストのみ実行する方法を調べました。
もう少しシンプルに実装して、python -m unittestで実行できるのではないかと、試行錯誤できず今回の形になりました。実行するためのインターフェースに一貫性がないのでイマイチです。。。
もっとシンプルに実装する方法があれば教えてください。