如何使用nosetest的LazySuite?

时间:2016-11-28 12:24:07

标签: python generator nose

根据nosetest's API documentation,有一个LazySuite()

class nose.suite.LazySuite(tests=())
A suite that may use a generator as its list of tests

但是,我找不到这个测试生成器应该是什么样子的任何示例。我尝试用一​​种方法编写一种方法,将测试用例交给nosetest的测试发现并将其传递给LazySuite构造函数,如下所示:

import nose
import nose.suite

data = [
        ['a', 'b', 'c'],
        ['1', '2', '3']
]

def check_data_list(data_list):
    assert data_list[0] == 'a'


def test_generator():
    for data_list in data:
        yield check_data_list, data_list


if __name__ == '__main__':

    suite = nose.suite.LazySuite(tests=test_generator())
    nose.run(suite=suite)

然而,

失败了
Traceback (most recent call last):
  File "test-with-nose.py", line 43, in <module>
    nose.run(suite=suite)
  File "/usr/local/lib/python3.5/dist-packages/nose/core.py", line 301, in run
    return TestProgram(*arg, **kw).success
  File "/usr/local/lib/python3.5/dist-packages/nose/core.py", line 121, in __init__
    **extra_args)
  File "/usr/lib/python3.5/unittest/main.py", line 94, in __init__
    self.runTests()
  File "/usr/local/lib/python3.5/dist-packages/nose/core.py", line 207, in runTests
    result = self.testRunner.run(self.test)
  File "/usr/local/lib/python3.5/dist-packages/nose/core.py", line 62, in run
    test(result)
  File "/usr/local/lib/python3.5/dist-packages/nose/suite.py", line 178, in __call__
    return self.run(*arg, **kw)
  File "/usr/local/lib/python3.5/dist-packages/nose/suite.py", line 225, in run
    test(orig)
  File "/usr/lib/python3.5/unittest/suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "/usr/local/lib/python3.5/dist-packages/nose/suite.py", line 76, in run
    test(result)
TypeError: 'tuple' object is not callable

用于创建LazySuite类的实例的生成器应该是什么样的?

1 个答案:

答案 0 :(得分:0)

好吧,我不确定这是否是唯一正确的方法,因为我没有看到它在任何地方正式记录,但它在涉及the TestLoader class及其loadTestsFromGenerator()方法时有效。这个方法传递了一个生成器函数,它产生了一个或多个(test_function, other_args, ...)元组,我在问题中已经提到过。

完整示例(打印语句仅用于更容易地了解正在发生的事情):

import nose
import nose.suite
import itertools
from nose.loader import TestLoader


data = [
        ['a', 'b', 'c'],
        ['1', '2', '3']
]

def first_check(row):
    print('Running first check on row: {0}'.format(row))
    assert row[0] is not None


def second_check(row):
    print('Running second check on row: {0}'.format(row))
    assert row[1] is not None

def test_generator():
    for row in data:
        yield first_check, row
        yield second_check, row

if __name__ == '__main__':
    all_tests = TestLoader().loadTestsFromGenerator(test_generator, 'test-with-nose')
    suite = nose.suite.LazySuite(all_tests)
    nose.main(suite=suite)

使用--nocapture选项运行它(否则打印将被隐藏)给出:

Running first check on row: ['a', 'b', 'c']
.Running second check on row: ['a', 'b', 'c']
.Running first check on row: ['1', '2', '3']
.Running second check on row: ['1', '2', '3']
.
----------------------------------------------------------------------
Ran 4 tests in 0.002s

OK

对大量要测试的行执行此操作(例如,通过从csv读取器而不是嵌套列表中生成它们)并不是很快,但是,它将内存消耗保持在较低水平,因为只有一个组合在行之外test应该同时加载到内存中。

编辑:当我为一个非常大的生成器(例如包含数百万行的csv文件)执行脚本时,这仍然会继续占用我宝贵的内存。可能是因为测试结果仍然存储在内部某处,直到所有测试都已运行?