Unittest - 数据驱动的对象边缘案例测试?

Unittest - data driven edge-case tests with objects?

考虑以下因素:

import unittest

class MyClass:
    def __init__(self, dict: {}):
        try:
            if self.validate_dict(dict):
                self.data = dict
        except Exception as e:
            raise Exception('Unable to create MyClass: {}'.format(str(e)))

    def validate_dict(self, dict: {}):
        if 'special_key' not in dict:
            raise Exception('Missing Key: special_key')

        # ... perhaps more complicated validation code...
        return True

class MyTests(unittest.TestCase):
    def test_bad_validation(self):
        with self.assertRaises(Exception) as context:
            test_dict = {}
            test_class = MyClass(test_dict)

        self.assertTrue('Unable to create' in str(context.exception))

...假设这不是一个糟糕的单元测试方法,除了 {} 之外,我如何向单元测试添加更多测试用例?

我觉得一目了然地查看特定测试的所有测试用例的漂亮列表并快速添加新的测试用例会很有用。

我找到了一个库 DDT 来解决这个问题,但似乎没有任何方法可以在不解包的情况下将整个对象(如 dict)作为测试参数传递它。在这种情况下,我想测试密钥的存在(并且可能有很多),因此将它们拆解成像 DDT 这样的单独论点似乎是一个糟糕的解决方案。

unittest支持这样的东西吗?我知道 pytest 可以,但我想先看看 unittest 有什么可能。

也欢迎使用其他方法对该代码进行单元测试。

我相信您正在寻找 subTest 方法(在 3.4 中添加)。

import unittest

class MyClass:
    def __init__(self, dic: {}):
        try:
            if self.validate_dict(dic):
                self.data = dic
        except KeyError as e:
            raise ValueError('Unable to create MyClass: {}'.format(e))

    def validate_dict(self, dic):
        if 'special_key' not in dic:
            raise KeyError('Missing Key: special_key')

        # ... perhaps more complicated validation code...
        return True

class MyTests(unittest.TestCase):
    def test_bad_validation(self):
        for test_dict in (
                {},
                {'a':1},
                {'b':2, 'else':3},
                {'special_key':4},
                ):
            with self.subTest(test_dict=test_dict):
                with self.assertRaises(Exception) as context:
                    MyClass(test_dict)
                self.assertTrue('Unable to create' in str(context.exception))

unittest.main()

在 3.6 中,对于通过验证检查失败的情况打印:

======================================================================
FAIL: test_bad_validation (__main__.MyTests) (test_dict={'special_key': 4})
----------------------------------------------------------------------
Traceback (most recent call last):
  File "F:\Python\mypy\tem2.py", line 23, in test_bad_validation
    MyClass(test_dict)
AssertionError: Exception not raised

----------------------------------------------------------------------
Ran 1 test in 0.014s

FAILED (failures=1)