框架特有的约定
py.test 和 nose 框架都提供特殊的例程,这些例程可以简化测试的编写。可以认为它们分别提供一种方便的测试 “方言”,可以用这些 “方言” 编写测试。这会简化测试的编写并减少错误,还会使测试更简短、可读性更好。但是,使用这些例程还会导致一个重要的后果:您的测试与提供函数的框架捆绑在一起了,丧失了兼容性。
因此,要权衡考虑方便性和兼容性。如果只使用笨拙的标准 Python unittest 模块从头编写所有测试,那么它们能够在任何测试框架中运行。更进一步,如果采用简单的做法编写测试函数(如上所述),那么测试至少能够在 py.test 和 nose 中运行。但是,如果开始使用某个测试框架特有的特性,那么如果以后另一个框架开发出了新的重要特性,您决定进行框架迁移,就必须重写测试。
py.test 和 nose 都为 TestCase 的 assertRaises() 方法提供了替代品。py.test 提供的版本比较新颖,它也可以接受要执行的字符串,这更强大,因为可以测试引发异常的表达式,而不只是函数调用:
# conveniences.py
import math
import py.test
py.test.raises(OverflowError, math.log, 0)
py.test.raises(ValueError, math.sqrt, -1)
py.test.raises(ZeroDivisionError, "1 / 0")
import nose.tools
nose.tools.assert_raises(OverflowError, math.log, 0)
nose.tools.assert_raises(ValueError, math.sqrt, -1)
# No equivalent for third example!
import math
import py.test
py.test.raises(OverflowError, math.log, 0)
py.test.raises(ValueError, math.sqrt, -1)
py.test.raises(ZeroDivisionError, "1 / 0")
import nose.tools
nose.tools.assert_raises(OverflowError, math.log, 0)
nose.tools.assert_raises(ValueError, math.sqrt, -1)
# No equivalent for third example!
但是,除了都能够测试异常之外,这两种框架的差异就比较大了。py.test 只提供一个简便函数,它用来判断特定调用是否会触发 DeprecationWarning:
py.test.deprecated_call(my.old.function, arg1, arg2)
另一方面,nose 提供非常丰富的断言函数,适用于希望避免 assert 语句和需要进行比较复杂的测试的情况。详细信息请参考它的文档,下面列出 nose 提供的断言函数:
# nose.tools support functions for writing tests
assert_almost_equal(first, second, places=7, msg=None)
assert_almost_equals(first, second, places=7, msg=None)
assert_equal(first, second, msg=None)
assert_equals(first, second, msg=None)
assert_false(expr, msg=None)
assert_not_almost_equal(first, second, places=7, msg=None)
assert_not_almost_equals(first, second, places=7, msg=None)
assert_not_equal(first, second, msg=None)
assert_not_equals(first, second, msg=None)
assert_true(expr, msg=None)
eq_(a, b, msg=None)
ok_(expr, msg=None)
assert_almost_equal(first, second, places=7, msg=None)
assert_almost_equals(first, second, places=7, msg=None)
assert_equal(first, second, msg=None)
assert_equals(first, second, msg=None)
assert_false(expr, msg=None)
assert_not_almost_equal(first, second, places=7, msg=None)
assert_not_almost_equals(first, second, places=7, msg=None)
assert_not_equal(first, second, msg=None)
assert_not_equals(first, second, msg=None)
assert_true(expr, msg=None)
eq_(a, b, msg=None)
ok_(expr, msg=None)
在处理浮点数时,如果希望测试能够灵活地对待 Python 实现,允许对浮点数的处理有细小的误差,那么上面检查近似值的例程尤其有意义。