是否有适当的方法来组织涉及每个测试用例的数据文件的测试用例?

时间:2011-08-16 23:22:54

标签: python unit-testing testing

我正在编写一个模块,该模块涉及解析数据的html并从中创建对象。基本上,我想创建一组测试用例,其中每个案例都是一个html文件,与黄金/预期的pickle对象文件配对。

当我对解析器进行更改时,我想运行此测试套件以确保每个html页面都被解析为等于“黄金”文件(基本上是回归套件)

我可以看到如何将其编码为单个测试用例,我将从某个目录加载所有文件对,然后遍历它们。但我相信这最终会被报告为单个测试用例,通过或失败。但我想要一份报告说,例如,45/47页成功解析。

我该如何安排?

2 个答案:

答案 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()