unittest工作原理简化一下就是:
先写好TestCase然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,整个过程集成在unittest.main模块中,main会调用TextTestRunner中的run来执行,或者我们可以直接通过TextTestRunner来执行用例。在Runner运行的时候,我们的测试结果会被输出到控制台,可以清晰的看到,我们还可以输出到文件,运用HTMLTestRunner生成一个漂亮的报告。
unittest中有4个重要的概念:test fixture, test case, test suite, test runner再外加一个测试报告Test Report
- Test Fixture(测试夹具):通过使用测试夹具,可以定义在单个或者多个测试执行之前的准备工作和测试执行后的清理工作。
比如你要测试一个接口(但该接口依赖于用户的登录状态),那么你需要先进行登录操作,这个登录活动就相当于准备工作。
- Test Case(测试用例):一个测试用例是在unittest中执行测试的最小单元。它通过unittest提供的assert方法来验证一组特定的操作或输入以后得到的具体响应。unittest提供了一个名为TestCase的基础类,可以用来创建测试用例。
- Test Suite(测试套件):一个测试套件是多个测试用例的集合,是针对被测程序的对应功能和模块创建的一组测试,一个测试套件内的测试将一起执行。
- Test Runner(测试执行器):测试执行器负责测试执行调试并且生成测试结果给用户。测试执行器可以使用图形界面、文本界面或者特定的返回值来展示测试执行结果。
- Test Report(测试报告):测试报告用来展示所有执行用例的成功或者失败状态的汇总,执行失败的测试步骤的预期结果与实际结果,还有整体运行状况及运行时间的汇总。注意,unittest本身是没有相应的内置模块来生成友好的报告,但我们可以借用unittest的扩展库HTMLTestRunner来实现,需要单独下载并放到python安装目录下lib/site-packages
unittest.TestCase:TestCase类,所有测试用例类继承的基本类。
class BaiduTest(unittest.TestCase):
unittest.main():使用她可以方便的将一个单元测试模块变为可直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中以“test”命名开头的测试方法,并自动执行他们。执行方法的默认顺序是:根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以以A开头的测试用例方法会优先执行,以a开头会后执行。
unittest.TestSuite():TestSuite类是用来创建测试套件的。因为执行测试用例的是通过调用unittest.mian()函数,它会将模块的测试用例收集起来并执行,然而当我们的测试用例增多了以后,这样的执行非常不灵活而且没有效率,此时unittest框架的TestSuite()类的优点就出现了。
TestLoader是用来加载TestCase到TestSuite,其中有几个loadTestFrom__( )方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,在返回一个TestSuite实例
1.先创建测试套件:
suite=unittest.TestSuite()
2.加载测试用例TestLoader类:它用于加载测试用例,然后返回一个测试用例集和有4个运行方式比较好:
unittest.TestLoader().loadTestsFromTestCase(类名)
unittest.TestLoader().loadTestsFromMoudule(模块名)但是我看源码提示是说在3.5已经移除使用,那就不用这个了
unittest.TestLoader().loadTestsFromName(方法名)
unittest.TestLoader().loadTestsFromNames(方法名,复数形式)
2.1.1创建一个.py文件,使用unittest.TestLoader().discover(“路径”,“匹配文件名”)也可以加载测试用例
3.再向测试套件里面添加case:addTest()方法是将测试用例添加到测试套件中
suite.addTests(unittest.TestLoader().loadTestsFromTestCase("LoginEvent"))
4.运行:TextTestRunner是用来执行测试用例的,其中的run(test)会执行TestCase中的run(result)方法。
unittest.TextTestRunner().run(suite)
如下代码是run_main.py
def run_case():
# 用例读取路径
case_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "case")
suite = unittest.TestLoader().discover(case_path)
# 测试报告存放路径
report_path = os.path.join(os.path.dirname(os.path.realpath(__file__)) + "/report/result_report.html")
with open(report_path, "wb") as f:
runner = HTMLTestRunner_PY3.HTMLTestRunner(stream=f,
title="Test Report",
description="Test Result",
verbosity=2)
runner.run(suite)
run_case()
setup就是前置条件,tearDown就是后置条件,在我们执行完case之后,tearDown最好要写,做数据的还原,清理测试环境,比如退出浏览器、返回到手机的Home页面,保证后面的case不会执行失败。
这里有个坑,就是比如我们做测试打开百度页面的操作,每次执行用例就重新打开一次,这样就非常的浪费时间,我的本意是打开了百度的页面,我想做完所有的操作,然后再去关闭百度页面,这个时候就用到了装饰器(@classmethod)
- 装饰器
用setUp与setUpClass区别
setup():每个测试case运行前运行
teardown():每个测试case运行完后执行
setUpClass():必须使用@classmethod 装饰器,所有case运行前只运行一次
tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次