25.3.5重用旧的测试代码
一些用户会发现他们已经有了想要从unittest中运行的现有的测试代码,而不需要将每个旧的测试函数转换为TestCase子类。出于这个原因,unittest提供了一个 FunctionCase类。TestCase的这个子类可以用来包装现有的测试函数。而且也提供了setup和teardown函数。
给定下列测试函数 :
def testSomething():
something = makeSomething()
assert something.name is not None
# ...
可以创建一个等效的测试用例如下:
testcase = unittest.FunctionTestCase(testSomething)
如果也有setup和teardown方法,它们也是测试用例操作的一部分,所以它们也可以这样写测试代码:
testcase = unittest.FunctionTestCase(testSomething,
setUp=makeSomethingDB,
tearDown=deleteSomethingDB)
为了使迁移现有的测试suite更容易,unittest支持抛出AssertError的测试以表明测试失败。
然而,建议你使用显式的TestCase.fail*()和 TestCase.assert*()方法来替代,因为unittest的未来版本可能会以不同的方式对待AssertError。
注意即使函数TestCase可以用来跨素的将现有的测试基础转换为基于单元测试的系统,但是不推荐使用这种方法。花一些时间建立何时的TestCase子类会使未来的测试重构更加便捷。
在某些情况下, 现有的测试可能是使用 doctest 模块编写的。如果是这样的话,doctest提供一个DocTestSuite类,可以从已存在的doctest-based测试中自动构建unittest.TestSuite 实例。
25.3.6 跳过预测和预期的失败
unittest 支持跳过单个测试方法甚至是整个测试类。
此外,它还支持将测试标记为“预期失败”,这种测试将会被破坏,并且会失败,但不应该被当做一个失败的TestResult
跳过测试仅仅是 使用skip()修饰符 或 它的条件变体 的问题。???
基本的跳过如下:
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass
这是在verbose mode下运行上述示例的输出:
test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'
test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'
----------------------------------------------------------------------
Ran 3 tests in 0.005s
OK (skipped=3)
测试类也可以像方法一样的被跳过。
@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
def test_not_run(self):
pass
TestCase.setUp() 也可以跳过测试。这在需要设置的资源不可用时非常有用。
预期的失败可以使用exceptedFailure()装饰器。
class ExpectedFailureTestCase(unittest.TestCase):
@unittest.expectedFailure
def test_fail(self):
self.assertEqual(1, 0, "broken")
通过在测试中使用含有skip()方法的修饰符,你可以轻松地建立自己的跳过修饰符。接下来这个decorater会跳过这个测试 除非测试过程中传递的对象有一个特定的属性 :
def skipUnlessHasattr(obj, attr):
if hasattr(obj, attr):
return lambda func: func
return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))
下面的修饰符实现了跳过测试和预期失败:
unittest.skip(reason)
无条件的跳过被装饰的测试。 原因部分应该描述为什么要跳过测试
unittest.skipIf(condition, reason)
如果 condition成立,跳过被装饰的测试。
unittest.skipUnless(condition, reason)
除非condition成立才跳过被装饰的测试
unittest.expectedFailure()
将测试标记为预期失败。如果测试在运行时失败,不将测试视为失败。
exception unittest.SkipTest(reason)
抛出一个异常来跳过这个测试
通常你可以使用 TestCase.skipTest() 或者跳过修饰符,而不是直接将异常抛出。
跳过测试不会有setUp()和tearDown()运行。跳过类不会有 setUpClass()或tearDownClass() 运行。