Python で動的 (パラメータ化された) ユニットテストを生成するにはどうすればよいでしょうか? 質問する

Python で動的 (パラメータ化された) ユニットテストを生成するにはどうすればよいでしょうか? 質問する

何らかのテスト データがあり、各項目の単体テストを作成したいと考えています。最初のアイデアは次のようにすることでした。

import unittest

l = [["foo", "a", "a",], ["bar", "a", "b"], ["lee", "b", "b"]]

class TestSequence(unittest.TestCase):
    def testsample(self):
        for name, a,b in l:
            print "test", name
            self.assertEqual(a,b)

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

この方法の欠点は、すべてのデータを 1 つのテストで処理することです。各項目に対して 1 つのテストをその場で生成したいと思います。何か提案はありますか?

ベストアンサー1

これを「パラメータ化」と呼びます。

このアプローチをサポートするツールはいくつかあります。例:

結果のコードは次のようになります。

from parameterized import parameterized

class TestSequence(unittest.TestCase):
    @parameterized.expand([
        ["foo", "a", "a",],
        ["bar", "a", "b"],
        ["lee", "b", "b"],
    ])
    def test_sequence(self, name, a, b):
        self.assertEqual(a,b)

次のテストが生成されます:

test_sequence_0_foo (__main__.TestSequence) ... ok
test_sequence_1_bar (__main__.TestSequence) ... FAIL
test_sequence_2_lee (__main__.TestSequence) ... ok

======================================================================
FAIL: test_sequence_1_bar (__main__.TestSequence)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/parameterized/parameterized.py", line 233, in <lambda>
    standalone_func = lambda *a: func(*(a + p.args), **p.kwargs)
  File "x.py", line 12, in test_sequence
    self.assertEqual(a,b)
AssertionError: 'a' != 'b'

歴史的な理由から、2008 年頃の元の回答を残しておきます:

私は次のようなものを使います:

import unittest

l = [["foo", "a", "a",], ["bar", "a", "b"], ["lee", "b", "b"]]

class TestSequense(unittest.TestCase):
    pass

def test_generator(a, b):
    def test(self):
        self.assertEqual(a,b)
    return test

if __name__ == '__main__':
    for t in l:
        test_name = 'test_%s' % t[0]
        test = test_generator(t[1], t[2])
        setattr(TestSequense, test_name, test)
    unittest.main()

おすすめ記事