技术开发 频道

Python测试框架: 用Python测试框架简化测试

  测试演化

  py.test 框架接受普通的 Python 函数作为测试,而不要求把测试放在更大更重型的测试类中,这开启了 Python 测试的新时代。因为 nose 框架支持相同的习惯做法,所以这些模式很可能越来越流行。

  假设希望检查 Python 真假值 True 和 False 是否真的等于布尔数字 1 和 0。py.test 或 nose 接受并运行以下代码行,作为回答此问题的有效测试:

# test_new.py - simple tests functions

def testTrue(self):
    assert
True == 1

def testFalse(self):
assert
False == 0

  为了体会以上示例的简单性,可以对比过去的 Python 测试文档中复杂的示例测试,比如:

# test_old.py - The old way of doing things

import unittest

class TruthTest(unittest.TestCase):
    def testTrue(self):
        assert
True == 1

    def testFalse(self):
        assert
False == 0

if __name__ == '__main__':
unittest.main()

  看到了吗?这么多代码只是为了支持两行测试代码!首先,代码需要一个 import 语句,这与要测试的代码完全无关,因为测试本身简单地忽略模块,只使用内置的 Python 值,比如 True 和 False。另外,要创建一个类,但是它不支持或增强测试,因为测试实际上没有使用它们的 self 参数做任何事情。最后,需要两行固定不变的代码,这样才能从命令行运行这个测试。

  有使用 unittest 经验的用户可能认为,上面的示例应该使用 TruthTest 类从 TestCase 类继承的测试方法。例如,他们会建议使用 assertEqual(),而不是手工测试是否相等的 assert 语句,在这种情况下测试会使用 self 而不是忽略它:

# alternate version of the TestTrue method
    ...
    def testTrue(self):
        self.assertEqual(
True, 1)
        ...

  对这个建议有三条反对意见。

  首先,调用方法会影响可读性。尽管 assertEqual() 方法名能够表明要测试两个值是否相等,但是代码看起来仍然不像是比较,对于熟悉 Python 语言的开发人员,不如 Python == 操作符那么明确。

  第二,正如在本系列的第三篇文章中将看到的,新的测试框架现在知道如何检查 assert 语句,从而查明造成测试失败的条件,这意味着简单的 assert 语句现在能够产生有意义的测试失败消息,它提供的信息与调用 assertEqual() 等老方法的结果差不多。

  最后,即使 assertEqual() 仍然是必要的,但是从测试模块导入这个函数(而不是通过类继承让函数可用)肯定更简单,更符合 Python 的风格。实际上,在下面会看到,当 py.test 和 nose 要提供更多用来支持测试的例程时,它们只需把这些例程定义为函数,然后用户可以把这些函数导入自己的代码。

  当然,如果作者确实需要通过例程缓存状态,以便以后在测试用例中使用,unittest 子类仍然是有意义的,py.test 和 nose 完全支持它们。另外,目前许多 Python 测试编写为 Python 标准库支持的 doctest,它们不需要使用函数或类:

Doctest For The Above Example
-----------------------------

The truth values in Python, named
"True" and "False",
are equivalent
to the Boolean numbers one and zero.

>>> True == 1
True
>>> False == 0
True

  但是,如果程序员希望编写简单的测试代码,不愿意考虑 doctest 涉及的乱七八糟的东西,那么测试函数是很好的方法。总之,测试函数可以极大地增强编写测试的简便性。程序员不需要记住、重写或复制以前编写的测试代码,新的约定让 Python 程序员能够像编写一般 Python 代码一样编写测试:只需打开一个空文件,然后输入!

0
相关文章