我正在编写一个模块,该模块涉及解析数据的html并从中创建对象。基本上,我想创建一组测试用例,其中每个案例都是一个html文件,与黄金/预期的pickle对象文件配对。
当我对解析器进行更改时,我想运行此测试套件以确保每个html页面都被解析为等于“黄金”文件(基本上是回归套件)
我可以看到如何将其编码为单个测试用例,我将从某个目录加载所有文件对,然后遍历它们。但我相信这最终会被报告为单个测试用例,通过或失败。但我想要一份报告说,例如,45/47页成功解析。
我该如何安排?
答案 0 :(得分:4)
我通过编写一个创建并返回测试类的函数,对unittest
框架做了类似的事情。然后,此函数可以接收您想要的任何参数,并相应地自定义测试类。您还可以自定义测试功能的__doc__
属性,以便在运行测试时获得自定义消息。
我很快就敲了下面的示例代码来说明这一点。它不使用任何实际测试,而是使用random
模块来进行某些测试以进行演示。创建时,会将类插入到全局命名空间中,以便调用unittest.main()
来获取它们。根据您运行测试的方式,您可能希望对生成的类执行不同的操作。
import os
import unittest
# Generate a test class for an individual file.
def make_test(filename):
class TestClass(unittest.TestCase):
def test_file(self):
# Do the actual testing here.
# parsed = do_my_parsing(filename)
# golden = load_golden(filename)
# self.assertEquals(parsed, golden, 'Parsing failed.')
# Randomly fail some tests.
import random
if not random.randint(0, 10):
self.assertEquals(0, 1, 'Parsing failed.')
# Set the docstring so we get nice test messages.
test_file.__doc__ = 'Test parsing of %s' % filename
return TestClass
# Create a single file test.
Test1 = make_test('file1.html')
# Create several tests from a list.
for i in range(2, 5):
globals()['Test%d' % i] = make_test('file%d.html' % i)
# Create them from a directory listing.
for dirname, subdirs, filenames in os.walk('tests'):
for f in filenames:
globals()['Test%s' % f] = make_test('%s/%s' % (dirname, f))
# If this file is being run, run all the tests.
if __name__ == '__main__':
unittest.main()
示例运行:
$ python tests.py -v
Test parsing of file1.html ... ok
Test parsing of file2.html ... ok
Test parsing of file3.html ... ok
Test parsing of file4.html ... ok
Test parsing of tests/file5.html ... ok
Test parsing of tests/file6.html ... FAIL
Test parsing of tests/file7.html ... ok
Test parsing of tests/file8.html ... ok
======================================================================
FAIL: Test parsing of tests/file6.html
----------------------------------------------------------------------
Traceback (most recent call last):
File "generic.py", line 16, in test_file
self.assertEquals(0, 1, 'Parsing failed.')
AssertionError: Parsing failed.
----------------------------------------------------------------------
Ran 8 tests in 0.004s
FAILED (failures=1)
答案 1 :(得分:3)
鼻子测试框架支持这一点。 http://www.somethingaboutorange.com/mrl/projects/nose/
另见:How to generate dynamic (parametrized) unit tests in python?
这是我要做的(未经测试):
files = os.listdir("/path/to/dir")
class SomeTests(unittest.TestCase):
def _compare_files(self, file_name):
with open('/path/to/dir/%s-golden' % file_name, 'r') as golden:
with open('/path/to/dir/%s-trial' % file_name, 'r') as trial:
assert golden.read() == trial.read()
def test_generator(file_name):
def test(self):
self._compare_files(file_name):
return test
if __name__ == '__main__':
for file_name in files:
test_name = 'test_%s' % file_name
test = test_generator(file_name)
setattr(SomeTests, test_name, test)
unittest.main()