Python的单元测试:如何运行只是一个测试文件的一部分?(Python unittest: how

2019-06-24 14:55发布

我有一个包含测试采取了相当多的时间测试文件(他们送计算,集群,并等待结果)。 所有这些都是在特定的TestCase类。

因为他们需要时间,而且不容易破裂,我希望能够选择的测试,这个子集是否或不运行(最好的办法是用命令行参数,即“ ./tests.py --offline “或类似的东西),这样我就可以经常和快速运行大部分测试和整个在一段时间设置一次,当我有时间。

现在,我只是用unittest.main()开始测试。

谢谢。

Answer 1:

默认unittest.main()使用默认的测试加载器,使一个TestSuite进行,其中主要是运行的模块。

您没有使用此默认行为。

你可以,例如,提出三点unittest.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]) 

请注意,我已经调整TestCase的名字,表示对快慢。 你也可以继承unittest.TestLoader解析类的名称和创建多个装载机。

然后你的主程序可以解析用命令行参数optparse或argparse (可用自2.7或3.2)来接你想运行,快,慢或全部套件。

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

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


Answer 2:

要运行只有一个特定的测试,你可以使用:

$ python -m unittest test_module.TestClass.test_method

更多信息点击这里



Answer 3:

其实,我们可以通过测试情况下,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

有测试的两种情况



Answer 4:

我使用的是简单的做这个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 …


Answer 5:

主要通过两种方式来做到这一点:

  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



Answer 6:

由于您使用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


Answer 7:

或者你可以使用的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')


Answer 8:

我找到了另一种解决方案的基础上,如何unittest.skip装饰工程。 通过设置__unittest_skip____unittest_skip_why__

基于标签

我想申请一个标签制度,将某些测试, quickslowglaciermemoryhogcpuhogcore ,等等。

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

履行

我在第2个部分中实现这一点:

  1. 首先标签添加到测试(通过自定义@testlabel类装饰)
  2. unittest.TestRunner以确定哪些测试跳过,并在执行前修改testlist内容。

执行工作是在这一要点: 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也适用



Answer 9:

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

请看例如作为鼻: https://pypi.python.org/pypi/nose/1.3.0



Answer 10:

我试图@洛特的回答是:

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)


Answer 11:

我已经找到了另一种方式来选择TEST_ *方法,我只希望通过添加属性将它们运行。 你基本上使用元类装饰是有StepDebug与unittest.skip装饰属性TestCase类内的可调用。 关于更多信息

通过使用装饰器和元类跳过所有的单元测试,但一个在Python

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



Answer 12:

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

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

问题: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 )


Answer 13:

这仅仅是为我工作的事情。

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

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

蟒蛇./tests.py class_Name.test_30311

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

享受,基思



Answer 14:

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

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


文章来源: Python unittest: how to run only part of a test file?