我有一个测试文件,其中包含花费大量时间的测试(它们将计算发送到集群并等待结果)。所有这些都在特定的 TestCase 类中。

由于它们需要时间而且不太可能中断,所以我希望能够选择这个测试子集是否运行(最好的方法是使用命令行参数,即“./tests.py --offline“或类似的东西),这样我就可以经常、快速地运行大部分测试,并且当我有时间时,偶尔运行整个测试集。

目前,我只使用 unittest.main() 开始测试。

谢谢。

有帮助吗?

解决方案

默认 unittest.main() 使用默认的测试加载器从运行 main 的模块中创建一个 TestSuite。

您不必使用此默认行为。

例如,您可以制作三个 单元测试.TestSuite 实例。

  1. “快速”子集。

    fast = TestSuite()
    fast.addTests( TestFastThis )
    fast.addTests( TestFastThat )
    
  2. “慢”子集。

    slow = TestSuite()
    slow.addTests( TestSlowAnother )
    slow.addTests( TestSlowSomeMore )
    
  3. “整套”。

    alltests = unittest.TestSuite([fast, slow])
    

请注意,我已经调整了测试用例名称以指示“快速”与“快速”。慢的。您可以unittest.testloader子类别来解析类的名称并创建多个加载程序。

然后你的主程序可以解析命令行参数 优化分析 或者 arg解析 (自 2.7 或 3.2 起可用)选择您想要运行的套件,快速、慢速或全部。

或者,你可以相信 sys.argv[1] 是三个值之一并使用像这样简单的东西

if __name__ == "__main__":
    suite = eval(sys.argv[1])  # Be careful with this line!
    unittest.TextTestRunner().run(suite)

其他提示

要只运行单一特定测试可以使用:

$ python -m unittest test_module.TestClass.test_method

更多信息这里

实际上,可以通过测试情况下sys.argv中的名称和仅那些情况将被测试。

例如,假设有

class TestAccount(unittest.TestCase):
    ...

class TestCustomer(unittest.TestCase):
    ...

class TestShipping(unittest.TestCase):
    ...

account = TestAccount
customer = TestCustomer
shipping = TestShipping

可以调用

python test.py account

仅具有帐户的测试中,或甚至

$ python test.py account customer

要具有这两种情况下测试

我使用一个简单的skipIf这样:

import os

SLOW_TESTS = int(os.getenv('SLOW_TESTS', '0'))

@unittest.skipIf(not SLOW_TESTS, "slow")
class CheckMyFeature(unittest.TestCase):
    def runTest(self):
        …

这样,我只需要装饰一个已经存在的测试用例这一条线上(无需创建测试套件或类似的,只是在我的单元测试文件的开头是一个os.getenv()电话线),并作为默认这个测试被跳过。

如果我想尽管是缓慢的去执行它,我只是把我的脚本是这样的:

SLOW_TESTS=1 python -m unittest …

基本上你有两种方法可以做到这一点:

  1. 为班级定义您自己的测试套件
  2. 创建将返回实际数据的集群连接的模拟类。

我是第二种方法的坚定支持者;单元测试 应该 仅测试代码的特定单元,而不测试复杂的系统(例如数据库或集群)。但我明白这并不总是可能的;有时,创建模型的成本太高,或者测试的目标确实是在复杂的系统中。

回到选项(1),你可以这样进行:

suite = unittest.TestSuite()
suite.addTest(MyUnitTestClass('quickRunningTest'))
suite.addTest(MyUnitTestClass('otherTest'))

然后将套件传递给测试运行程序:

unittest.TextTestRunner().run(suite)

有关 python 文档的更多信息: http://docs.python.org/library/unittest.html#testsuite-objects

由于您使用unittest.main()你可以运行python tests.py --help得到的文档:

Usage: tests.py [options] [test] [...]

Options:
  -h, --help       Show this message
  -v, --verbose    Verbose output
  -q, --quiet      Minimal output
  -f, --failfast   Stop on first failure
  -c, --catch      Catch control-C and display results
  -b, --buffer     Buffer stdout and stderr during test runs

Examples:
  tests.py                               - run default set of tests
  tests.py MyTestSuite                   - run suite 'MyTestSuite'
  tests.py MyTestCase.testSomething      - run MyTestCase.testSomething
  tests.py MyTestCase                    - run all 'test*' test methods
                                               in MyTestCase

这是,你可以简单地做

python tests.py TestClass.test_method

或者你也可以利用unittest.SkipTest()功能。例如,添加skipOrRunTest方法来测试类是这样的:

def skipOrRunTest(self,testType):
    #testsToRun = 'ALL'
    #testsToRun = 'testType1, testType2, testType3, testType4,...etc'
    #testsToRun = 'testType1'
    #testsToRun = 'testType2'
    #testsToRun = 'testType3'
    testsToRun = 'testType4'              
    if ((testsToRun == 'ALL') or (testType in testsToRun)):
        return True 
    else:
        print "SKIPPED TEST because:\n\t testSuite '" + testType  + "' NOT IN testsToRun['" + testsToRun + "']" 
        self.skipTest("skipppy!!!")

然后,调用此方法skipOrRunTest添加到每个的单元测试像这样的最开始:

def testType4(self):
    self.skipOrRunTest('testType4')

我找到了另一个解决方案,基于 unittest.skip 装饰工作品。通过设置 __unittest_skip____unittest_skip_why__.

基于标签

我想应用一个标签系统,将一些测试标记为 quick, slow, glacier, memoryhog, cpuhog, core, , 等等。

然后运行 all 'quick' tests, , 或者 run everything except 'memoryhog' tests, ,您的基本白名单/黑名单设置

执行

我分两部分实现:

  1. 首先向测试添加标签(通过自定义 @testlabel 类装饰器)
  2. 风俗 unittest.TestRunner 确定要跳过哪些测试,并在执行之前修改测试列表内容。

工作实施的要点是:https://gist.github.com/fragmuffin/a245f59bdcd457936c3b51aa2ebb3f6c

(完整的工作示例太长,无法放在这里)

结果是...

$ ./runtests.py --blacklist foo
test_foo (test_things.MyTest2) ... ok
test_bar (test_things.MyTest3) ... ok
test_one (test_things.MyTests1) ... skipped 'label exclusion'
test_two (test_things.MyTests1) ... skipped 'label exclusion'

----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK (skipped=2)

全部 MyTests1 类测试被跳过,因为它有 foo 标签。

--whitelist 也有效

考虑使用专用的TestRunner,像py.test,鼻子或可能甚至zope.testing。它们都具有用于选择测试命令行选项。

查找例如作为鼻: https://pypi.python.org/pypi /nose/1.3.0

我试过@洛特的回答是:

if __name__ == "__main__":
    suite = eval(sys.argv[1])  # Be careful with this line!
    unittest.TextTestRunner().run(suite)

但是,这给了我以下错误:

Traceback (most recent call last):
  File "functional_tests.py", line 178, in <module>
    unittest.TextTestRunner().run(suite)
  File "/usr/lib/python2.7/unittest/runner.py", line 151, in run
    test(result)
  File "/usr/lib/python2.7/unittest/case.py", line 188, in __init__
    testMethod = getattr(self, methodName)
TypeError: getattr(): attribute name must be string

以下为我工作:

if __name__ == "__main__":
    test_class = eval(sys.argv[1])
    suite = unittest.TestLoader().loadTestsFromTestCase(test_class)
    unittest.TextTestRunner().run(suite)

我找到了另一种方法来选择 test_* 方法,我只想通过向它们添加属性来运行它们。您基本上使用元类来装饰 TestCase 类内的可调用对象,这些可调用对象具有带有 unittest.skip 装饰器的 StepDebug 属性。更多信息:

使用装饰器和元类跳过除 Python 中的单元测试之外的所有单元测试

我不知道这是否比上面的解决方案更好,我只是提供它作为一个选项。

还没有找到一个很好的方式前要做到这一点,所以在这里分享。

目标:获取一组测试文件一起,这样他们可以作为一个单元运行, 但我们仍然可以选择单独运行它们中的任何一个。

问题:Discover方法不允许容易地选择单个测试用例来运行

设计:参见下文。此变平的命名空间,以便可以通过TestCase类名来选择,并且离开关闭的“tests1.test_core”前缀:

./run-tests TestCore.test_fmap

代码

  test_module_names = [
    'tests1.test_core',
    'tests2.test_other',
    'tests3.test_foo',
    ]

  loader = unittest.defaultTestLoader
  if args:
    alltests = unittest.TestSuite()
    for a in args:
      for m in test_module_names:
        try:
          alltests.addTest( loader.loadTestsFromName( m+'.'+a ) )
        except AttributeError as e:
          continue
  else:
    alltests = loader.loadTestsFromNames( test_module_names )

  runner = unittest.TextTestRunner( verbosity = opt.verbose )
  runner.run( alltests )

这是只为我工作的事情。

if __name__ == '__main__':
unittest.main( argv=sys.argv, testRunner = unittest.TextTestRunner(verbosity=2))

当我把它叫做虽然我有在类和测试名称的名称来传递。有点不方便,因为我没有做类和测试名称组合记忆。

蟒./tests.py class_Name.test_30311

删除类名和测试名称运行在你的文件中的所有测试。我觉得这是更容易处理,然后内置的方法,因为我真的不改变对我的CLI命令。只需添加参数。

享受, 基思

我创建一个装饰,其允许用于标记测试作为慢测试和使用环境变量跳过他们

from unittest import skip
import os

def slow_test(func):
    return skipIf('SKIP_SLOW_TESTS' in os.environ, 'Skipping slow test')(func)

现在你可以标记你的测试一样慢是这样的:

@slow_test
def test_my_funky_thing():
    perform_test()

和通过设置SKIP_SLOW_TESTS环境变量跳过慢测试:

SKIP_SLOW_TESTS=1 python -m unittest
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top