测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

时间:2023-11-28 21:17:26

单元测试
单元测试(unit testing)是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的
被测功能模块。
单元测试框架
在单元测试框架出现之前,开发人员在创建可执行测试时饱受折磨。最初的做法是在应用程序中创建一个窗口,配有"测试控制工具(harness)"。它只是一个窗口,每个测试对应一个按钮。这些测试的结果要么是一个消息框,要么是直接在窗体本身给出某种显示结果。由于每个测试都需要一个按钮,所以这些窗口很快就会变得拥挤、不可管理。
单元测试框架提供了一种统一的编程模型,可以将测试定义为一些简单的类,这些类中的方法可以调用希望测试的应用程序代码。开发人员不需要编写自己的测试控制工具;单元测试框架提供了测试运行程序(runner),只需要单击按钮就可以执行所有测试。利用单元测试框架,可以很轻松地插入、设置和分解有关测试的功能。测试失败时,测试运行程序可以提供有关失败的信息,包含任何可供利用的异常信息和堆栈跟踪。 不同编程语言有不同的单元测试框架,如Java 的Junit, TestNg, c#的 Nunit,Python的unittest,Pyunit,testtools, subunit....

一个TestCase的实例就是一个测试用例。
什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。
元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
而多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。
TestLoader是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。
测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
那什么是test fixture呢?
Test authors should subclass TestCase for their own tests. Construction and deconstruction of the test's environment ('fixture') can be implemented by overriding the 'setUp' and 'tearDown' methods respectively.
可见,对一个测试用例环境的搭建和销毁,是一个fixture,通过覆盖TestCase的setUp()和tearDown()方法来实现。
这个有什么用呢?
(1)比如说在这个测试用例中需要访问数据库,那么可以在setUp()中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的TestCase留下一个干净的环境。
(2)关于fixture,还有一个专门的库函数叫做fixtures,功能更加强大,以后会介绍到。
unittest运行原理

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

那一个测试类里面,如果写了多个方法,最终算是多个测试用例呢?还是一个测试用例呢?
(1)对每一个以test开头的方法,系统都为其构建了一个TestCase对象,系统也只执行TestCast对象的方法。
(2)如果没有定义test开头的方法,而是将测试代码写到了一个名为runTest的方法中,那么会为该runTest方法构建TestCase对象,如果定义了test开头的方法,就会忽略runTest方法。
(3)至此,基本就清楚了,每一个以test开头的方法,都会为其构建TestCase对象,也就是说TestSequenceFunctions类中其实定义了三个TestCase,之所以写成这样,是为了方便,因为这几个测试用例的fixture是相同的,如果每一个测试用例单独写成一个TestCase的话,会有很多的冗余代码。
(4)上图中,assertTrue_test这个是断言方法,最终程序如果按照Unittests方式去运行,断言方法是不会被执行的

有关TestCase构造的详细方法,可以参考源码解析,参考网址为:
http://blog.csdn.net/hackerain/article/details/24095117

3.unittest常用的断言方法

assertEqual(a, b)           判断a==b
assertNotEqual(a, b)      判断a!=b
assertTrue(x)                 bool(x) is True
assertFalse(x)                bool(x) is False
assertIs(a, b)                  a is b
assertIsNot(a, b)            a is not b
assertIsNone(x)             x is None
assertIsNotNone(x)        x is not None
assertIn(a, b)                  a in b
assertNotIn(a, b)            a not in b
assertIsInstance(a, b)          isinstance(a, b)
assertNotIsInstance(a, b)        not isinstance(a, b)

(1)使用unittests方式去执行程序,最终显示断言方法没有被执行,因为系统默认去执行test开头的方法
(2)一般,在自动化单元测试中,一般把断言放在测试用例方法中,去判断结果,而不是单独写一个断言方法

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法
4.Unittests中如果定义了多个类,每个类中也有多个方法,那么执行的顺序是怎样的?

 

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

总结:
(1)最终主程序先执行哪个类、是按照这个类的名字字母、以及数据排序的
(2)最终,先运行哪个方法,是按照某类中,方法的名字、数字排序的
(3)主程序中先加载哪个方法,或者后加载哪个方法,在unittests运行的模式下,没有任何作用
(4)只有当使用普通模式下运行这个程序,才会按照顺序去执行。

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

5.如何才能简化如上的程序?

以下程序是上如程序的类似简化版本

测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法

原文:https://blog.csdn.net/chenmozhe22/article/details/80042218
版权声明:本文为博主原创文章,转载请附上博文链接!