在Python中提供测试数据
我该如何对很多不同的数据进行相同的测试呢?
我希望能收到所有失败的报告。
举个例子:
def isEven(number):
return True # Quite buggy implementation
data = [
(2, True),
(3, False),
(4, True),
(5, False),
]
class MyTest:
def evenTest(self, num, expected):
self.assertEquals(expected, isEven(num))
我找到的解决方案只会在第一次失败时抛出错误:在Python单元测试中使用PHPUnit风格的数据提供者
我该如何运行一个测试,以便能收到所有失败的报告呢?
5 个回答
8
一种解决方法是为data
中的每个条目创建不同的测试用例实例:
class MyTest(unittest.TestCase):
def __init__(self, num, expected):
unittest.TestCase.__init__(self, "evenTest")
self.num = num
self.expected = expected
def evenTest(self):
self.assertEqual(self.expected, isEven(self.num))
为了让unittest
知道如何构建这些测试用例,你需要在你的模块中添加一个load_tests()
函数:
def load_tests(loader, tests, pattern):
return unittest.TestSuite(MyTest(num, expected)
for num, expected in data)
12
如果你在使用 pytest,你可以这样做:
import pytest
def is_even(number):
return True # Wuite buggy implementation
@pytest.mark.parametrize("number, expected", [
(2, True),
(3, False),
(4, True),
(5, False)
])
def test_is_even(number, expected):
assert is_even(number) == expected
你会得到类似下面的结果(简化版):
/tmp/test_it.py:13: AssertionError
=========== 2 failed, 2 passed in 0.01 seconds ====================
8
你应该使用 py.test
。我觉得unittest模块是从JUnit抄来的。无论如何,你可以这样来解决问题:
import unittest
data = [
(2, True),
(3, False),
(4, True),
(5, False)]
# This should be imported from a separate module.
def isEven(number):
return True # Quite buggy implementation
def create_test_func(num, expected):
def _test_func(self):
self.assertEqual(expected, isEven(num))
return _test_func
class TestIsEven(unittest.TestCase):
pass
# pyunit isn't Pythonic enough. Use py.test instead
# till then we rely on such hackery
import new
for i, (num, expected) in enumerate(data):
setattr(TestIsEven, 'test_data_%d'%i, create_test_func(num, expected))
if __name__ == "__main__":
unittest.main()
然后输出结果是:
.F.F
======================================================================
FAIL: test_data_1 (__main__.TestIsEven)
----------------------------------------------------------------------
Traceback (most recent call last):
File "untitled-1.py", line 15, in _test_func
self.assertEqual(expected, isEven(num))
AssertionError: False != True
======================================================================
FAIL: test_data_3 (__main__.TestIsEven)
----------------------------------------------------------------------
Traceback (most recent call last):
File "untitled-1.py", line 15, in _test_func
self.assertEqual(expected, isEven(num))
AssertionError: False != True
----------------------------------------------------------------------
Ran 4 tests in 0.000s
FAILED (failures=2)
通过这种方法,你还可以添加一些额外的功能,比如在出错时打印调试信息等等。