我有一个测试文件,其中包含花费大量时间的测试(它们将计算结果发送到集群并等待结果)。所有这些都在特定的TestCase类中。
由于它们需要时间,而且不太可能中断,因此我希望能够选择测试的该子集是否运行(最好的方法是使用命令行参数,即“ ./tests.py --offline
”或其他内容)这样),因此我可以在需要的时候经常且快速地运行大多数测试,并偶尔进行整套测试。
现在,我只是unittest.main()
用来开始测试。
谢谢。
Answers:
默认值unittest.main()
使用默认的测试加载程序从运行main的模块中制作出TestSuite。
您不必使用此默认行为。
例如,您可以制作三个unittest.TestSuite实例。
“快速”子集。
fast = TestSuite()
fast.addTests( TestFastThis )
fast.addTests( TestFastThat )
“慢”子集。
slow = TestSuite()
slow.addTests( TestSlowAnother )
slow.addTests( TestSlowSomeMore )
“整个”设置。
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)
ctypes
针对C / C ++代码编写和运行单元测试。无论如何,这是这个问题的题外话。
test_class = eval(sys.argv[1])
suite = unittest.TestLoader().loadTestsFromTestCase(test_class)
unittest.TextTestRunner().run(suite)
python -m unittest test_module.TestClass.test_method test_module.TestClass.test_method2
。因此,即使您要运行一些相关的测试用例,这仍然非常有用。
我正在使用一个简单的方法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 …
实际上,可以将测试用例的名称作为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
对两个案例进行测试
account = TestAccount
不需要,也可以使用python test.py TestAccount
。
unittest.main()
被调用的情况下有效。EGif __name__ == '__main__': unittest.main()
基本上有两种方法可以做到这一点:
我坚决支持他的第二种方法。单元测试应该只测试非常多的代码单元,而不是复杂的系统(例如数据库或集群)。但是我知道这并不总是可能的。有时,创建实体模型太过昂贵了,或者测试的目标实际上是在复杂的系统中。
返回选项(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.skip
装饰器的工作原理找到了另一个解决方案。通过设置__unittest_skip__
和__unittest_skip_why__
。
基于标签
我想申请一个标签制度,将某些试验为quick
,slow
,glacier
,memoryhog
,cpuhog
,core
,等。
然后运行all 'quick' tests
或run everything except 'memoryhog' tests
基本白名单/黑名单设置
实作
我分两部分实现了这一点:
@testlabel
类装饰器)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
也可以
或者您可以使用该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')
考虑使用专用的测试运行程序,例如py.test,nose甚至可能是zope.testing。它们都有用于选择测试的命令行选项。
我尝试了@slott的答案:
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类中具有StepDebug属性的可调用对象,并使用unittest.skip装饰器。有关更多信息
使用装饰器和元类跳过所有单元测试,但跳过Python中的一个
我不知道这是否是比上述解决方案更好的解决方案,我只是将其作为一种选择。
之前还没有找到执行此操作的好方法,因此请在此处共享。
目标:将一组测试文件放在一起,以便它们可以作为一个单元运行,但是我们仍然可以选择其中的任何一个单独运行。
问题:发现方法无法轻松选择要运行的单个测试用例。
设计:请参见下文。这使名称空间变平,因此可以通过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 )
我创建了一个装饰器,该装饰器允许将测试标记为慢速测试,并使用环境变量跳过它们
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