一、定义
1)什么是单元测试?
单元:函数或者是类
单元测试:测试类或者函数
2)为什么做单元测试?
投入小、收益大,能够精准的、更早的发现问题
3)单元测试和我有什么关系?
python语言是很难测试java的单元,关键是单元测试一般是开发或者测开做的。
二、unittest-TestCase
单元测试框架:
Python内置的单元测试框架:unittest
unittest的注意事项:
1.模块名称:test_开头
2.类名:Test····
3.测试用例方法名称:test·····开头
4.TestLogin(unittest.TestCase),不要忘了继承unittest.TestCase
#导入单元测试框架unittest import unittest """测试登录功能(函数)""" def login(username = None,password = None): if username != None and password != None: if username == "zjx111" and password == "123456": return {"code":0,"msg":"登录成功!"} else: return {"code":1,"msg":"登录失败,用户名或密码错误!"} else: return {"code":1,"msg":"登录失败,用户名或密码为空!"} #设计登录测试用例类 class TestLogin(unittest.TestCase):#继承unittest.TestCase def test_login_success(self): '''登录成功''' username = "zjx111" password = "123456" expected_reponse = {"code":0,"msg":"登录成功!"} #实际结果:调用login函数 actual_reponse = login(username,password) #判断预期结果跟实际结果是否一样 断言 self.assertTrue(expected_reponse == actual_reponse) def test_login_error(self): '''登录失败''' username = '' password = '' expected_reponse = {"code":1,"msg":"登录失败,用户名或密码错误!"} actual_reponse = login(username, password) self.assertTrue(expected_reponse == actual_reponse) |
三、unittest-Fixture:测试环境的搭建和销毁(前置、后置条件)
# 前置、后置条件是固定的名称,不改,执行一个用例执行一次前置后置条件 def setUp(self): '''前置条件''' pass def tearDown(self): '''后置条件''' pass |
在用例执行之前执行setUp(),在用例执行之后执行tearDown()
有多少条用例,就执行多少遍setUp()和tearDown()
#导入单元测试框架unittest import unittest """测试登录功能(函数)""" def login(username = None,password = None): if username != None and password != None: if username == "zjx111" and password == "123456": return {"code":0,"msg":"登录成功!"} else: return {"code":1,"msg":"登录失败,用户名或密码错误!"} else: return {"code":1,"msg":"登录失败,用户名或密码为空!"} #设计登录测试用例类 class TestLogin(unittest.TestCase):#继承unittest.TestCase def setUp(self): '''前置条件''' print('连接数据库') def tearDown(self): '''后置条件''' print('断开数据库') def test_login_success(self): '''登录成功''' username = "zjx111" password = "123456" expected_reponse = {"code":0,"msg":"登录成功!"} #实际结果:调用login函数 actual_reponse = login(username,password) #判断预期结果跟实际结果是否一样 断言 self.assertTrue(expected_reponse == actual_reponse) def test_login_error(self): '''登录失败''' username = '' password = '' expected_reponse = {"code":1,"msg":"登录失败,用户名或密码错误!"} actual_reponse = login(username, password) self.assertTrue(expected_reponse == actual_reponse) ''' 结果: 连接数据库 断开数据库 连接数据库 断开数据库 ''' |
如果想在一个测试类当中,只执行一次的话前置和后置,需要用到类方法:setUpClass(cls)和tearDownClass(cls)
#导入单元测试框架unittest import unittest """测试登录功能(函数)""" def login(username = None,password = None): if username != None and password != None: if username == "zjx111" and password == "123456": return {"code":0,"msg":"登录成功!"} else: return {"code":1,"msg":"登录失败,用户名或密码错误!"} else: return {"code":1,"msg":"登录失败,用户名或密码为空!"} #设计登录测试用例类 class TestLogin(unittest.TestCase):#继承unittest.TestCase @classmethod def setUpClass(cls): print('一个测试类中只会执行一次的前置条件') @classmethod def tearDownClass(cls): print('一个测试类中只会执行一次的后置条件') def setUp(self): '''前置条件''' print('连接数据库') def tearDown(self): '''后置条件''' print('断开数据库') def test_login_success(self): '''登录成功''' username = "zjx111" password = "123456" expected_reponse = {"code":0,"msg":"登录成功!"} #实际结果:调用login函数 actual_reponse = login(username,password) #判断预期结果跟实际结果是否一样 断言 self.assertTrue(expected_reponse == actual_reponse) def test_login_error(self): '''登录失败''' username = '' password = '' expected_reponse = {"code":1,"msg":"登录失败,用户名或密码错误!"} actual_reponse = login(username, password) self.assertTrue(expected_reponse == actual_reponse) ''' 结果: 一个测试类中只会执行一次的前置条件 连接数据库 断开数据库 连接数据库 断开数据库 一个测试类中只会执行一次的后置条件 ''' |
四、unittest-TestSuite/TextTestRunner:测试套件/运行测试用例
unittest测试用例的执行顺序:
不是从上到下
根据测试用例的名称:ASCII码
如果想自己调整测试用例的顺序,就可以在测试用例的方法名称上加数字,比如:test_login_01_success(self)
我们会把测试用例的代码放到一个统一的文件夹当中,目录当中:tests/testcases
if __name__=='__main__': #使用Python运行这个模块里面的测试用例 unittest.main() |
测试用例收集步骤:
1)将所有待测的测试用例放在,项目目录下new 一个directory,命名为tests / testcases里
2)在run_test.py中,运行收集用例的代码
a). import unittest
b).初始化一个加载器 loader = unittest.TestLoader()
c).加载器去收集所有的测试用例(testcases里的所有用例),放在testsuite里面 test_suite = loader.discover(case_path)
import unittest import os #初始化一个加载器 test_loadder loader = unittest.TestLoader() #获取测试用例目录的路径,测试用例都放在tesetcases文件夹里 dir_path = os.path.dirname(os.path.abspath(__file__)) case_path = os.path.join(dir_path,'testcases') #使用loader获取所有的测试用例 test_suite = loader.discover(case_path) #在case_path里面发现所有的测试用例 print(test_suite)#就是返回一个testSuite对象,列表存储的 |
执行测试用例:
1).初始化一个执行器runner
2).runner.run(test_suite)
import os import unittest #初始化一个加载器 test_loadder loader = unittest.TestLoader() #获取测试用例目录的路径,测试用例都放在tesetcases文件夹里 dir_path = os.path.dirname(os.path.abspath(__file__)) case_path = os.path.join(dir_path,'testcases') #使用loader获取所有的测试用例 test_suite = loader.discover(case_path) #在case_path里面发现所有的测试用例 print(test_suite)#就是返回一个testSuite对象,列表存储的 #执行测试用例 #先初始化一个执行器runner runner = unittest.TextTestRunner() runner.run(test_suite) |
五、生成测试报告
1)生成txt报告
但是在实际中,不会使用txt形式的报告,比较low,会换用HTML的报告.
import unittest import os #初始化一个加载器 test_loadder loader = unittest.TestLoader() #获取测试用例目录的路径,测试用例都放在tesetcases文件夹里 dir_path = os.path.dirname(os.path.abspath(__file__)) case_path = os.path.join(dir_path,'testcases') #使用loader获取所有的测试用例 test_suite = loader.discover(case_path) #在case_path里面发现所有的测试用例 print(test_suite)#就是返回一个testSuite对象,列表存储的 #执行 并生成text测试报告 with open('test_report.txt','a',encoding='utf-8') as f: runner = unittest.TextTestRunner(f) #f作为参数传入 runner.run(test_suite) |
2)生成HTML测试报告
HTML报告不是内置的,需要自己去下载HTML的测试报告的运行器和模板(HTMLTestRunnerNew.py),导入到pycharm的seite_package 或者直接导入项目目录下
#执行 并生成html测试报告 with open('test_report.html','wb') as f: runner = HTMLTestRunner( f, title='自动化测试报告', description='测试报告的描述', tester='zjx' ) runner.run(test_suite) |
六、断点调试
1)断点
调试的时候使用debug模式,
打断点 在可能出错的地方打断点,如果不知道哪行会出错,就打在最开始的位置,一行一行调试
2)打断点如何运行?
step over:单步执行,运行到下一行
step into:执行到函数的内部
step into my code:进入自己写的代码,别人写的进不去
step out:退出函数
run to cursor:运行到指定的行
evaluate:查找值并可对查找到的值进行其他运算
rerun:重新运行
resume program:运行到下一个断点
stop:停止
view breakpoints:显示所有的断点
mute breakpoints:关闭所有的断点
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理