Thi*_*Lam 137 python testing unit-testing
我目前有一些单元测试,它们共享一组共同的测试.这是一个例子:
import unittest
class BaseTest(unittest.TestCase):
def testCommon(self):
print 'Calling BaseTest:testCommon'
value = 5
self.assertEquals(value, 5)
class SubTest1(BaseTest):
def testSub1(self):
print 'Calling SubTest1:testSub1'
sub = 3
self.assertEquals(sub, 3)
class SubTest2(BaseTest):
def testSub2(self):
print 'Calling SubTest2:testSub2'
sub = 4
self.assertEquals(sub, 4)
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
以上的输出是:
Calling BaseTest:testCommon
.Calling BaseTest:testCommon
.Calling SubTest1:testSub1
.Calling BaseTest:testCommon
.Calling SubTest2:testSub2
.
----------------------------------------------------------------------
Ran 5 tests in 0.000s
OK
Run Code Online (Sandbox Code Playgroud)
有没有办法重写上面的内容,以便第一个testCommon不被调用?
编辑: 我没有运行上面的5个测试,而是希望它只运行4个测试,2个来自SubTest1,另外2个来自SubTest2.似乎Python unittest自己运行原始的BaseTest,我需要一种机制来防止这种情况发生.
Mat*_*all 147
使用多重继承,因此具有常见测试的类本身不会继承TestCase.
import unittest
class CommonTests(object):
def testCommon(self):
print 'Calling BaseTest:testCommon'
value = 5
self.assertEquals(value, 5)
class SubTest1(unittest.TestCase, CommonTests):
def testSub1(self):
print 'Calling SubTest1:testSub1'
sub = 3
self.assertEquals(sub, 3)
class SubTest2(unittest.TestCase, CommonTests):
def testSub2(self):
print 'Calling SubTest2:testSub2'
sub = 4
self.assertEquals(sub, 4)
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
Vad*_* P. 125
不要使用多重继承,它会在以后咬你.
相反,您可以将基类移动到单独的模块中或使用空白类包装它:
import unittest
class BaseTestCases:
class BaseTest(unittest.TestCase):
def testCommon(self):
print 'Calling BaseTest:testCommon'
value = 5
self.assertEquals(value, 5)
class SubTest1(BaseTestCases.BaseTest):
def testSub1(self):
print 'Calling SubTest1:testSub1'
sub = 3
self.assertEquals(sub, 3)
class SubTest2(BaseTestCases.BaseTest):
def testSub2(self):
print 'Calling SubTest2:testSub2'
sub = 4
self.assertEquals(sub, 4)
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
输出:
Calling BaseTest:testCommon
.Calling SubTest1:testSub1
.Calling BaseTest:testCommon
.Calling SubTest2:testSub2
.
----------------------------------------------------------------------
Ran 4 tests in 0.001s
OK
Run Code Online (Sandbox Code Playgroud)
小智 29
您可以使用一个命令解决此问题:
del(BaseTest)
Run Code Online (Sandbox Code Playgroud)
所以代码看起来像这样:
import unittest
class BaseTest(unittest.TestCase):
def testCommon(self):
print 'Calling BaseTest:testCommon'
value = 5
self.assertEquals(value, 5)
class SubTest1(BaseTest):
def testSub1(self):
print 'Calling SubTest1:testSub1'
sub = 3
self.assertEquals(sub, 3)
class SubTest2(BaseTest):
def testSub2(self):
print 'Calling SubTest2:testSub2'
sub = 4
self.assertEquals(sub, 4)
del(BaseTest)
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
Den*_*zov 24
Matthew Marshall的答案很棒,但它要求你在每个测试用例中继承两个类,这很容易出错.相反,我使用它(python> = 2.7):
class BaseTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
if cls is BaseTest:
raise unittest.SkipTest("Skip BaseTest tests, it's a base class")
super(BaseTest, cls).setUpClass()
Run Code Online (Sandbox Code Playgroud)
您可以添加__test__ = FalseBaseTest 类,但如果添加它,请注意您必须添加__test__ = True派生类才能运行测试。
import unittest
class BaseTest(unittest.TestCase):
__test__ = False
def testCommon(self):
print 'Calling BaseTest:testCommon'
value = 5
self.assertEquals(value, 5)
class SubTest1(BaseTest):
__test__ = True
def testSub1(self):
print 'Calling SubTest1:testSub1'
sub = 3
self.assertEquals(sub, 3)
class SubTest2(BaseTest):
__test__ = True
def testSub2(self):
print 'Calling SubTest2:testSub2'
sub = 4
self.assertEquals(sub, 4)
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
你想要实现什么目标?如果你有通用的测试代码(断言,模板测试等),那么将它们放在没有前缀的方法中,test这样unittest就不会加载它们.
import unittest
class CommonTests(unittest.TestCase):
def common_assertion(self, foo, bar, baz):
# whatever common code
self.assertEqual(foo(bar), baz)
class BaseTest(CommonTests):
def testCommon(self):
print 'Calling BaseTest:testCommon'
value = 5
self.assertEquals(value, 5)
class SubTest1(CommonTests):
def testSub1(self):
print 'Calling SubTest1:testSub1'
sub = 3
self.assertEquals(sub, 3)
class SubTest2(CommonTests):
def testSub2(self):
print 'Calling SubTest2:testSub2'
sub = 4
self.assertEquals(sub, 4)
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
马修的答案是我需要使用的答案,因为我还在2.5.但是从2.7开始,您可以在要跳过的任何测试方法上使用@ unittest.skip()装饰器.
http://docs.python.org/library/unittest.html#skipping-tests-and-expected-failures
您需要实现自己的跳过装饰器来检查基本类型.以前没有使用过这个功能,但是我可以使用BaseTest作为标记类型来调整跳过:
def skipBaseTest(obj):
if type(obj) is BaseTest:
return unittest.skip("BaseTest tests skipped")
return lambda func: func
Run Code Online (Sandbox Code Playgroud)
小智 6
另一种选择是不执行
unittest.main()
Run Code Online (Sandbox Code Playgroud)
而不是你可以使用
suite = unittest.TestLoader().loadTestsFromTestCase(TestClass)
unittest.TextTestRunner(verbosity=2).run(suite)
Run Code Online (Sandbox Code Playgroud)
所以你只在类中执行测试 TestClass
我想解决此问题的一种方法是通过隐藏测试方法(如果使用了基类)。这样就不会跳过测试,因此在许多测试报告工具中,测试结果可以是绿色而不是黄色。
与mixin方法相比,像PyCharm这样的ide不会抱怨基类中缺少单元测试方法。
如果基类从该类继承,则它将需要重写setUpClass和tearDownClass方法。
class BaseTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._test_methods = []
if cls is BaseTest:
for name in dir(cls):
if name.startswith('test') and callable(getattr(cls, name)):
cls._test_methods.append((name, getattr(cls, name)))
setattr(cls, name, lambda self: None)
@classmethod
def tearDownClass(cls):
if cls is BaseTest:
for name, method in cls._test_methods:
setattr(cls, name, method)
cls._test_methods = []
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
47482 次 |
| 最近记录: |