unittest

unittest支持测试自动化,共享测试的设置和关闭代码,将测试集合到集合中,以及测试独立于报告框架。 unittest模块提供的类可以很容易地支持这些质量的一组测试。

为了达到这个目的,unittest支持一些重要的概念:

测试夹具
测试夹具代表执行一个或多个测试所需的准备以及任何关联的清理操作。这可能涉及到,例如,创建临时或代理数据库,目录或启动服务器进程。
测试用例
测试用例是最小的测试单位。它检查对特定输入集合的特定响应。 unittest提供了一个基类TestCase,它可以用来创建新的测试用例。
测试套件
测试套件是测试用例,测试套件或两者的集合。它被用来聚合应该一起执行的测试。
测试赛跑者
测试运行器是一个组件,它协调测试的执行并将结果提供给用户。跑步者可以使用图形界面,文本界面,或返回一个特殊的值来表示执行测试的结果。

测试用例和测试夹具的概念通过TestCase和FunctionTestCase类来支持;前者应在创建新测试时使用,后者可在将现有测试代码与单元测试驱动框架集成时使用。当使用TestCase构建测试装置时,setUp()和tearDown()方法可以被覆盖,以提供夹具的初始化和清理。使用FunctionTestCase,现有的函数可以传递给构造函数用于这些目的。当测试运行时,夹具初始化首先运行;如果成功,则在执行测试之后运行清理方法,而不管测试的结果如何。 TestCase的每个实例将只用于运行一个测试方法,所以每个测试都会创建一个新的fixture。

测试套件由TestSuite类实现。这个类允许单独的测试和测试套件被汇总;当套件执行时,所有直接添加到套件和“子”测试套件的测试都会运行。

测试运行器是一个对象,它提供了一个方法run(),它接受一个TestCase或TestSuite对象作为参数,并返回一个结果对象。提供TestResult类作为结果对象。 unittest提供了TextTestRunner作为示例测试运行器,默认情况下在标准错误流上报告测试结果。替代跑步者可以实现其他环境(如图形环境),而不需要从特定的类派生。

一个TestCase是通过继承创建unittest.TestCase生成。 三个单独的测试用名称以'test'开始的方法来定义。 这个命名约定通知测试运行者哪些方法代表测试。

每个测试的关键是调用assertEqual()来检查预期的结果; assertTrue()或assertFalse()来验证一个条件; 或assertRaises()来验证是否引发了一个特定的异常。 这些方法被用来代替assert语句,所以测试运行器可以累积所有的测试结果并产生一个报告。

setUp()和tearDown()方法允许您定义在每个测试方法之前和之后执行的指令。 在“组织测试代码”一节中详细介绍了它们。

最后一个块显示了一个简单的方法来运行测试。 unittest.main()为测试脚本提供了一个命令行界面。 当从命令行运行时,上面的脚本产生如下所示的输出:

将-v选项传递给测试脚本将指示unittest.main()启用更高级别的详细程度,并生成以下输出:

以上示例显示了最常用的单元测试功能,足以满足许多日常测试需求。 文档的其余部分从最基本的原则中探索完整的功能集。

26.4.4. 组织测试代码


单元测试的基本构件是测试用例 - 必须设置和检查正确性的单个场景。 在unittest中,测试用例由unittest.TestCase实例表示。 要创建自己的测试用例,您必须编写TestCase的子类或使用FunctionTestCase。

TestCase实例的测试代码应该是完全独立的,这样它可以独立运行,也可以与任意数量的其他测试用例组合运行。

最简单的TestCase子类将简单地实现一个测试方法(即一个名字以test开始的方法),以执行特定的测试代码:

请注意,为了测试某些东西,我们使用了TestCase基类提供的一个assert *()方法。 如果测试失败,将会引发异常,单元测试将把测试用例标识为失败。 任何其他异常将被视为错误。

测试可以是很多的,他们的设置可以重复。 幸运的是,我们可以通过实现一个名为setUp()的方法来分解设置的代码,测试框架会自动调用我们运行的每一个测试:

注意:各种测试的运行顺序是通过对测试方法名称和字符串的内置排序进行排序来确定的。

如果setUp()方法在测试运行时产生异常,则框架将认为测试发生了错误,测试方法将不会执行。

同样的,我们可以提供一个tearDown()方法,在测试方法运行完后,

如果setUp()成功,则无论测试方法是否成功,tearDown()都将运行。

这种测试代码的工作环境被称为夹具。

测试用例实例根据它们测试的功能分组在一起。 unittest为此提供了一个机制:由unittest的TestSuite类表示的测试套件。 在大多数情况下,调用unittest.main()会做正确的事情,并为你收集所有模块的测试用例,然后执行它们。

但是,如果您想要自定义测试套件的构建,则可以自行完成:

您可以将测试用例和测试套件的定义放置在与测试代码相同的模块中(如widget.py)。
但将测试代码放置在单独的模块(如test_widget.py)中有几个优点:

测试模块可以从命令行单独运行。
测试代码可以更容易地从提供的代码中分离出来。
没有一个很好的理由,改变测试代码来适应测试代码的诱惑就会少一些。
测试代码应该比它测试的代码少得多。
测试的代码可以更容易地重构。
用C编写的模块测试必须在不同的模块中,为什么不一致呢?
如果测试策略发生变化,则不需要更改源代码。

个人实例

# isodd.py
def isOdd(a):
    if a & 1:
        return True
    else:
        return False

# isoddTest.py
import unittest
from pack_1 import isodd

class isoddTestCase(unittest.TestCase):

    def test_isodd(self):
        self.assertEqual(isodd.isOdd(1), True)

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

# add.py
def Add(a, b):
    return a + b

# addTest.py
import unittest
from pack_2 import add

class addTestCase(unittest.TestCase):

    def test_add(self):
        self.assertEqual(add.Add(1, 2), 3)

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

# testAll.py
import unittest
from pack_2 import addTest
from pack_1 import isoddTest

if __name__ == '__main__':
    # 加入一个测试类里的所有test*()
    suite1 = unittest.TestLoader().loadTestsFromModule(isoddTest)
    suite2 = unittest.TestLoader().loadTestsFromModule(addTest)
    suite = unittest.TestSuite([suite1, suite2])
    # suite.addTest(addTest.addTestCase('test_add'))
    unittest.TextTestRunner(verbosity=2).run(suite)
原文地址:https://www.cnblogs.com/liwenchi/p/7827591.html