python - 每个输入文件单独的测试用例?

标签 python unit-testing testing

大多数测试框架都假定“1 个测试 = 1 个 Python 方法/函数”, 并在函数执行时认为测试通过 提出断言。

我正在测试一个类似编译器的程序(一个读取 *.foo 的程序 文件并处理它们的内容),为此我想对许多输入(*.foo)文件执行相同的测试。 IOW,我的测试看起来像:

class Test(unittest.TestCase):
    def one_file(self, filename):
        # do the actual test

    def list_testcases(self):
        # essentially os.listdir('tests/') and filter *.foo files.

    def test_all(self):
        for f in self.list_testcases():
            one_file(f)

我当前的代码使用 unittest从 Python 的标准库,即 one_file 使用 self.assert...(...) 检查测试是否通过的语句。

这是可行的,因为我确实得到了一个成功/失败的程序 当我的代码没问题/有问题时,但我失去了很多优点 测试框架:

  • 我没有收到相关报告,例如“Y 项测试失败 X 次”,也没有 通过/失败测试的列表。 (我打算使用这样的系统 不仅要测试自己的开发还要给学生的代码打分 作为一名教师,所以报告对我来说很重要)

  • 我没有测试独立性。第二次测试运行在 第一个留下的环境,依此类推。第一次失败停止 测试套件:失败后出现的测试用例根本不会运行。

  • 我觉得我在滥用我的测试框架:只有 一种测试功能,因此可以自动测试发现 unittest 声音 例如矫枉过正。同样的代码可以(应该?)写成 带有基本 assert 的纯 Python。

一个明显的替代方法是将我的代码更改为类似

class Test(unittest.TestCase):
    def one_file(self, filename):
        # do the actual test

    def test_file1(self):
        one_file("first-testcase.foo")

    def test_file2(self):
        one_file("second-testcase.foo")

然后我得到了 unittest 的所有优点,但是:

  • 还有很多代码要写。

  • “忘记”测试用例很容易,即在 tests/ 忘记将其添加到 Python 测试中。

我可以想象一个解决方案,我会动态地为每个测试用例生成一个方法(沿着 setattr(self, 'test_file' + str(n), ...) 行),以生成无需手动编写第二个解决方案的代码。但对于一个看起来并不复杂的用例来说,这听起来确实有点过分了。

我怎样才能兼顾两者,即 自动测试用例发现(列出 tests/*.foo 文件),测试 独立性和适当的报告?

最佳答案

如果可以使用pytest作为您的测试运行器,那么使用 parametrize decorator 实际上非常简单:

import pytest, glob

all_files = glob.glob('some/path/*.foo')

@pytest.mark.parametrize('filename', all_files)
def test_one_file(filename):
    # do the actual test

这也会以有用的方式自动命名测试,这样您就可以看到哪些文件失败了:

$ py.test
================================== test session starts ===================================
platform darwin -- Python 3.6.1, pytest-3.1.3, py-1.4.34, pluggy-0.4.0
[...]
======================================== FAILURES ========================================
_____________________________ test_one_file[some/path/a.foo] _____________________________

filename = 'some/path/a.foo'

    @pytest.mark.parametrize('filename', all_files)
    def test_one_file(filename):
>      assert False
E      assert False

test_it.py:7: AssertionError
_____________________________ test_one_file[some/path/b.foo] _____________________________

filename = 'some/path/b.foo'

    @pytest.mark.parametrize('filename', all_files)
    def test_one_file(filename):
[...]

关于python - 每个输入文件单独的测试用例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45751607/

相关文章:

python - 在 numpy 中快速找到对称对

python - 如何防止从 celery 任务中重复记录异常

java - SonarQube 不显示单元测试结果

python - console_scripts 入口点被忽略?

python - Asyncio 与 Gevent

angular - Jasmine 监视 Typescript 类的 Get() 或 Set() 函数

ruby-on-rails - rails 3.1 分贝 :test:prepare and "pending migrations" problem

python - Python 3.x 中的单元测试 'pathlib.Path.is_file'

testing - 在 groovy(Spock) 中测试文件结构

docker - Common.py 位于 Kiwi。如何挂载到docker