unittest是python内置的单元测试框架,具备编写用例、组织用例、执行用例、输出报告等自动化框架的条件。 使用unittest前需要了解该框架的五个概念: 即test case,test suite,testLoader,test runner,test fixture。
下面针对unittest模块下的几个成员进行简单的介绍:
TestCase:所有测试用例的基本类,给一个测试方法的名字,就会返回一个测试用例实例,用例名称必须以test开头;testq 可以 wtest不可以,test_可以,一个TestCase,就是一个测试用例,什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。通过运行这个测试单元,可以对某一个问题进行验证
unittest.TestSuit()类:多个测试用例集合在一起,就是测试套件或叫测试计划,addTest()方法是将测试用例添加到测试套件中而且TestSuite也可以嵌套
TextTestRunner():是来执行测试用例的,通过该类的run(test)方法执行suite所组装的测试用例,入参为suite测试套件。其中Text的意思是以文本形式显示测试结果。测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息;
unittest.defaultTestLoader(): defaultTestLoader()类,通过该类下面的discover()方法可自动更具测试目录start_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件,因此可以直接通过run()方法执行discover。
TestLoader:用来加载TestCase到TestSuite中的,其中 loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例;
TestLoader(defaultTestLoader)是unittest的测试用例加载器,它包括多个加载测试用例的方 法。它的结果是返回一个测试套件。
Test fixture:一个测试用例的初始化准备及环境还原,主要是setUp() 和 setDown()方法;
这个有什么用呢?
(1)比如说在这个测试用例中需要访问数据库,那么可以在setUp()中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的TestCase留下一个干净的环境。
通过unittest类调用分析,可将框架的工作流程概况如下:
编写TestCase,由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite, 最后将运行的结果保存在TextTestResult中。
测试用例方法是以test开头作为标识,用例的执行结果以assetxxx断言结果
决定,如果断言返回为false,将抛出assetError异常。测试用例代码如下:
从上面的设计的测试用例执行结果及对自动化测试的要求,需要考虑以下4个问题,及给出unitest框架中 的解决方法。
在unittest中,用例是以test开头的方法定义的,默认执行顺序是根据用例名称升序进行,如上面的用例, 实际执行顺序为:
test_a-->test_b-->test_c,而不是用例定义的先后顺序。 在unittest中解决用例执行顺序的问题是使用TestSuite,代码如下:
unittest的setup、teardown会在每个用例执行前后执行一次,如有3个测试用例, 那么每个用例执行前会执行setup,执行后会执行teardown,即setup、teardown总共会调用三次, 但考虑实际自动化测试场景,多个用例只需执行一次setup,全部用例执行完成后,执行一次teardown, 针对该种场景,unittest的处理方法是使用setupclass、teardownclass,注意@classmethod的使用, 如下:
在自动化测试中,经常会遇到挑选用例的情况,在unittest中的解决方法是使用skip装饰器, 其中skip装饰器主要有3种:unittest.skip(reason) 无条件跳过用例,并填写备注信息
unittest.skipIf(condition,reason) 条件为真时,跳过用例 unittest.skipUnless(condition,reason),条件为假时,下跳过该用例, reason用于描述跳过的原因
执行用例:
1、第一种方式
#如果直接运行该文件(__name__值为__main__),则执行以下语句,常用于测试脚本是否能够正常运行
if __name__=='__main__':(鼠标放这行代码上面,右击执行,出来run当前.py文件)
执行测试用例方案一如下:
#unittest.main()方法会搜索该模块下所有以test开头的测试用例方法,并自动执行它们。
#执行顺序是命名顺序:先执行test_case1,再执行test_case2
unittest.main()
2、
#执行测试用例方案二如下:
a,先造测试集
suite=unittest.TestSuite()#实例化测试套件
b,将测试用例加载到测试套件中。
执行顺序是安装加载顺序:先执行test_case2,再执行test_case1
suite.addTest(类名(测试方法名称))# 不用加self和括号
suite.addTest(Test('test_case2'))
suite.addTest(Test('test_case1'))
备注:也可以加其他模块得文件,如B文件里面的类C的用例
suite.addTest(C('test_case1'))
c,执行测试用例
#实例化TextTestRunner类
runner=unittest.TextTestRunner()
#使用run()方法运行测试套件(即运行测试套件中的所有用例)
runner.run(suite)
缺点:每个用例都需要加载到测试套件中,如果有1000个用例,要写1000次重复的代码,很冗余。
3、
构造测试集(简化了方案二中先要创建测试套件然后再依次加载测试用例)
找到指定目录下所有测试用例模块,并递归查询子目录下的测试模块,找到匹配的文件进行加载。
#执行顺序同方案一:执行顺序是命名顺序:先执行test_case1,再执行test_case2
test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')
#匹配查找测试用例文件,以test*.py开头,并将查找到的测试用例组装到测试套件中
#start_dir:需要测试的用例文件目录或是模块
#pattern:用例匹配原则,找以test开头的的py文件
#top_level_dir:测试模块的顶层目录,没有就默认None。
#执行测试用例
#实例化TextTestRunner类
runner=unittest.TextTestRunner()
#使用run()方法运行测试套件discover(即运行测试套件中的所有用例)
runner.run(discover)