一、unitest库
1、unitest库的介绍:unittest原名为PyUnit,是由java的JUnit衍生而来。unittest是xUnit系列框架中的一员;
1.1、概念:
test fixture:代表了用例执行前的准备工作和用例执行之后的清理工作。比如在用例执行前创建临时文件和文件夹,又或者启动1个server进程等;一个测试用例的初始化准备及环境还原,主要是setUp() 和 tearDown()方法;
test case: 测试用例,一般检查一组输入的响应(输出)是否符合预期。unittest模块提供了TestCase类来帮助我们创建测试用例;此时运行用例的前置条件和运行用例之后的清理工作就可以交给setUp()和tearDown()来执行;
test suite :测试用例或测试套件的集合,一般先创建一个套件,然后把需要一起执行的用例添加到套件中,然后运行测试套件,即运行所有组合的用例;
test runner: 用来执行测试用例并输出测试结果的组件。可以是图形界面或命令行界面(可以简单运行,也可以生成简单的测试结果;或者可以下载HTMLTestRuneer文件,生成网页版的测试报告)
1.2、unitest的断言
unitest中断言主要由三种:
1.基本的布尔断言,即:要么正确,要么错误的验证
2.比较断言,如,比较两个变量的值(跟布尔断言区别不大,主要通过比较两个变量的值得出布尔值)
3.复杂断言,用的比较少,像断言两个列表、元组等
断言方法 | 意味着 |
---|---|
assertEqual(a,b) | a == b |
assertNotEqual(a,b) | a!= b |
assertTrue(x) | bool(x)是True |
assertFalse(x) | bool(x)为False |
assertIs(a,b) | a是b |
assertIsNot(a,b) | a不是b |
assertIsNone(x) | x为无 |
assertIsNotNone(x) | x不是None |
assertIn(a,b) | a in b |
assertNotIn(a,b) | a不在b中 |
assertIsInstance(a,b) | isinstance(a,b) |
assertNotIsInstance(a,b) | 不是isinstance(a,b) |
assertRaises(exc,fun,args,* kwds) | fun(args,* kwds)引发ex |
assertRaisesRegexp(exc,r,fun,args,* kwds) | fun(args,* kwds)引发ex并且消息匹配egex r |
assertAlmostEqual(a,b) | 回合(ab,7)== 0 |
assertNotAlmostEqual(a,b) | round(ab,7)!= 0 |
assertGreater(a,b) | a> b 2.7 |
assertGreaterEqual(a,b) | a> = b |
assertLess(a,b) | a <b |
assertLessEqual(a,b) | a <= b |
assertRegexpMatches(s,r) | r.search |
assertNotRegexpMatches(s,r) | 不是r.search |
assertItemsEqual(a,b) | sorted(a)== sorted(b)也支持unhashable对象 |
assertDictContainsSubset(a,b) | a里面所有的键值对都在b中存在 |
2、unitest基本用法
# 导入unitest库 import unittest # 创建一个测试用例类,继承与unitest.TestCase class Test_case(unittest.TestCase): def setUp(self): print('执行用例前需要完成的事情') def tearDown(self): print('执行用例后要做的事情') # 用例 def test_1(self): print('第1个测试用例') def test_2(self): print('第2个测试用例') def test_3(self): print('第3个测试用例') # 非测试用例方法 def fff(self): print('我不是测试用例') # 简单运行测试用例 if __name__ == '__main__': unittest.main()
# 或这样运行
# 创建一个测试套件,向其中添加测试用例
suit = unittest.TestLoader().loadTestsFromTestCase(Test_case)
# 显式运行测试用例,并通过verbosity=2设定生成测试结果,运行套件
unittest.TextTestRunner(verbosity=2).run(suit)
关注点:
1、编写测试用例时一般先创建一个测试用例类,继承于unitest.TestCase,一个测试用例类下面可以有多个测试点
2、测试用例中方法名以test开头的方法才是测试方法,如上面的test_1等,非test开头 的不是测试方法,运行时不会执行,如上面的fff
3、setUp和tearDown这两个方法,这两个方法在测试方法执行前后都会被自动调用,主要用作预处理和清理。这两个方法就是前面说的test fixture、
4、调用uniitest.main()的时候,框架自动的调用了Test类,因为Test继承自unittest.TesetCase类,所以会被框架识别为测试用例
5、unitest.main()是最简单的运行用例的方式,另外的方式是添加测试组件运行,或者生成测试结果或报告
3、编写用例(以登录为例)
编写用例时需要先定义一个测试用例类,在测试用例类里的方法就是我们的测试用例,用例名称必须要以 test 开头,否则unitest.TestCase不会识别为测试用例,非test开头的测试用例类里的方法为普通方法,非 测试用例;我们需要在测试用例里添加脚本运行后是否成功的断言,靠断言判断用例是否通过
# 导入unitest框架 import unittest # 导入封装好的登录类模块 from My_case_fuxi.My_Login import Login_1 # 创建一个登录对象 lo = Login_1('Firefox') # 定义一个测试用例类(必须继承于unitest.TestCase) class Test_my(unittest.TestCase): def setUp(self) -> None: pass def tearDown(self) -> None: pass # 输入账号无密码登录 def test_1(self): lo.login('18826473908','') # 获取元素文本内容 a = lo.text_element('id','pwd_err') # 添加断言 self.assertEqual(a,'请输入密码') # 输入密码无账号登录 def test_2(self): lo.login('','8888888') # 获取元素文本内容 a = lo.text_element('id', 'username_err') # 添加断言 self.assertEqual(a, '请输入51Job帐号') # 账号密码为空 def test_3(self): lo.login('','') # 获取元素文本内容 a = lo.text_element('id', 'username_err') b = lo.text_element('id', 'pwd_err') # 添加断言 self.assertEqual(a, '请输入51Job帐号') self.assertEqual(b, '请输入密码') if __name__ == '__main__': # unittest.main() # 创建一个测试套件,并向其中加载测试用例 suit = unittest.TestLoader().loadTestsFromTestCase(Test_my) # 显式运行测试没并且通过设置verbosity设定对每一个测试方法产生测试结果 unittest.TextTestRunner(verbosity=2).run(suit)
4、测试用例的运行
4.1、简单的运行:unitest.main(),执行本.py文件里的所有代码,若有多个用例类,全部执行
如上面 3 的代码,运行结果只显示运行了多少条用例,多少条通过多少条不通过(只有文字显示和总结果,若有不通过的会报错)
4.2、创建测试套件,显式运行用例,并通过verbosity设定每个测试方法产生测试结果,是否OK,如图
此方法只执行测试套件里的用例类
4.3、生成网页版测试报告
如下代码:
# 导入unitest import unittest # 导入我们需要测试的用例模块 from My_case_fuxi.My_login_case.My_login_case import Test_my # 导入生成网页版测试报告的依赖文件HTMLTestRunner from My_case_fuxi.HTMLTestRunner.HTMLTestRunner import HTMLTestRunner # 创建一个测试套件类 class Test_suite(unittest.TestCase): # 定义一个测试套件类 def test_My_suite(self): # 创建一个测试套件 my_suite = unittest.TestSuite() # 测试用例列表 my_case = ['test_1','test_2','test_3'] # 遍历列表,套件里添加用例 for case in my_case: my_suite.addTest(Test_my(case)) with open('My_login_case.html','wb') as f: HTMLTestRunner( # 这里相当于f.write写入文件 stream=f, # 测试报告标题 title='登录用例测试报告', # 测试报告详情 description='登录测试用例的报告', # 生成测试报告 verbosity=2 ).run(my_suite) if __name__ == '__main__': unittest.main()
这里是专门创建一个套件的用例类,可以把这些代码放到要执行的文件下面的if __name__ == '__main__':下面去执行