6

前世で Java 開発にかなり携わったことがあり、JUnit Theoriesが非常に役立つことがわかりました。Pythonに同様のメカニズムはありますか?

現在、私は次のようなことをしています:

def some_test(self):
    cases = [('some sample input', 'some expected value'),
            ('some other input', 'some other expected value')]

    for value, expected in cases:
        result = method_under_test(value)
        self.assertEqual(expected, result)

しかし、これはかなり厄介です。最初の「ケース」が失敗すると、他のすべてのケースが実行されなくなります。

4

3 に答える 3

2

pytest は次のようなことができるようです: https://docs.pytest.org/en/latest/parametrize.html

私はそれを自分で試していません。

于 2015-05-28T21:39:16.010 に答える
0

一般的なテスト フレームワークでは、このためのビルトインを認識していません。ソリューションの唯一の問題は、反復がテスト内にあることです。むしろそれは外側にあり、テストを生成する必要があります。おそらくこのようなものです

import unittest


def _apply(func, args):
    """Return a function with args applied after first argument"""
    def wrapped(self):
        return func(self, *args)
    return wrapped


class TheoryMeta(type):
    """Metaclass that replaces test methods with multiple methods for each test case"""
    def __new__(meta, name, bases, attrs):
        newattrs = {}
        cases = attrs.pop('cases', [])

        for name, value in attrs.items():
            if not name.startswith('test') or not callable(value):
                newattrs[name] = value
                continue

            for n, args in enumerate(cases):
                test_name = '%s_%d' % (name, n)
                newattrs[test_name] = _apply(value, args)

        return super().__new__(meta, name, bases, newattrs)


class TestCase(unittest.TestCase, metaclass=TheoryMeta):
    pass

それを使用するには、テスト ケースの各テスト メソッドに適用する引数のリストでTestCaseある属性を持つサブクラスを作成します。cases

class TestAdd(TestCase):
    cases = [
        # (a, b)
        (1, 1),
        (2, 0),
        (3, 0),
    ]

    def test_add(self, a, b):
        self.assertEqual(a + b, 2)

======================================================================
FAIL: test_add_2 (__main__.__qualname__)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test.py", line 7, in wrapped
    return func(self, *args)
  File "test.py", line 41, in test_add
    self.assertEqual(a + b, 2)
AssertionError: 3 != 2

----------------------------------------------------------------------
Ran 3 tests in 0.001s

ニーズとテストの設定によっては、メタクラスを使用するよりも、TestCase で生成されたテスト メソッドにモンキー パッチを適用する方がよい場合があります。または、オーバーライドされたloadTestsFrom...でそれらを生成することもできますTestLoader。いずれの場合も、サンプル データを使用してテスト メソッドを生成します。

于 2015-05-28T07:31:35.173 に答える