四.unittest接口自动化框架介绍
#首先导入unittest import unittest class testUnittestOne(unittest.TestCase): #编写测试用例,方法名必须以test开头 def test_equals(self): self.assertEquals(1,1,msg="相等") #执行测试用例 if __name__ == '__main__': unittest.main()
2.testCase多个之间的执行顺序,按照测试用例的方法名字母进行排序执行的;每条用例执行前都会执行一下setUp方法,用例执行后都还会在执行一遍tearDown方法
import unittest class testUnittestTwo(unittest.TestCase): #测试用例初始化方法setUp def setUp(self): print("开始执行测试用例") #测试用例后置方法tearDown def tearDown(self): print("执行完测试用例") def test_case1(self): print("执行case1") self.assertEqual(1,1,msg="1等于1") def test_aase2(self): print("执行case2") self.assertEqual(1, 2, msg="1不等于2") if __name__ == '__main__': unittest.main()

import unittest class testUnittestTwo(unittest.TestCase): #测试用例初始化方法setUp @classmethod def setUpClass(self): print("开始执行测试用例") #测试用例后置方法tearDown @classmethod def tearDownClass(self): print("执行完测试用例") def test_case1(self): print("执行case1") self.assertEqual(1,1,msg="1等于1") def test_aase2(self): print("执行test_aase2") self.assertEqual(1, 2, msg="1不等于2") if __name__ == '__main__': unittest.main()
执行结果:

3.unittest模板常用校验方法


二. unittest接口参数化及用例集介绍
import unittest import requests import parameterized # 数据参数化需要导入该模块 import HTMLTestRunner class LoginTest(unittest.TestCase): url = "http://api.nnzhp.cn/api/user/login" # 测试数据进行参数化 @parameterized.parameterized.expand([ ["niuhanyang", "aA123456"], ["niuhanyang", "aA1234567"], ["niuhanyang", "aA1234568"] ]) def test_login(self, username, password): data = {"username": username, "passwd": password} re = requests.post(self.url, data).text self.assertIn("userId", re, "包含userId") if __name__ == '__main__': # 把测试用例放在测试集合中 suite = unittest.makeSuite(LoginTest) f = open("report.html", "wb") # 生成测试报告,需要先导入HTMLTestRunner模板,放在当前目录下或python第三方模板安装的site_package文件夹下 runner = HTMLTestRunner.HTMLTestRunner(f, description="baogao", title="") runner.run(suite) f.close()
执行结果:

2.unittest通过读取文件内容进行参数化

import unittest import parameterized import requests import HTMLTestRunner class TestParameFile(unittest.TestCase): url = 'http://api.nnzhp.cn/api/user/login' """ 通过文件进行参数化 """ def getDataForFile(fileName): data = [] with open(fileName, encoding="utf-8") as fw: for line in fw: line = line.strip() if line: data.append(line.split(",")) return data @parameterized.parameterized.expand(getDataForFile("users.txt")) def test_login(self, username, password, check): # 发送接口请求 re = requests.post(self.url, {"username": username, "passwd": password}).text self.assertIn(check, re, "没有返回%s" % check) if __name__ == "__main__": # 生成测试用例套件 testSuit = unittest.makeSuite(TestParameFile) f = open("testParameFile.html", "wb") Runner = HTMLTestRunner.HTMLTestRunner(f, title="测试报告", description="测试报告详情") Runner.run(testSuit) f.close()
执行结果:


import unittest import HTMLTestRunner import time import BeautifulReport class RunManyTestCase(unittest.TestCase): def runTestCase(self): # 将测试用例加载到caseSuite中 caseSuite = unittest.defaultTestLoader.discover("case", "*") f = open("manyReport%s.html" % (time.strftime("%y%m%d")), "wb") runCase = HTMLTestRunner.HTMLTestRunner(f, title="用例集报告", description="xxx系统测试报告") runCase.run(caseSuite) f.close() def runTestCaseReport(self): # 将测试用例加载到caseSuite中 caseSuite = unittest.defaultTestLoader.discover("case", "*") bf = BeautifulReport.BeautifulReport(caseSuite) bf.report(description='查找测试用例的', filename='discover%s.html' % (time.time())) if __name__=="__main__": c = RunManyTestCase() c.runTestCase() c.runTestCaseReport()
4.unittest通过HTMLTestRunner进行生成报告
import unittest import HTMLTestRunner import time import BeautifulReport class RunManyTestCase(unittest.TestCase): def runTestCase(self): # 将测试用例加载到caseSuite中 caseSuite = unittest.defaultTestLoader.discover("case", "*") f = open("manyReport%s.html" % (time.strftime("%y%m%d")), "wb") runCase = HTMLTestRunner.HTMLTestRunner(f, title="用例集报告", description="xxx系统测试报告") runCase.run(caseSuite) f.close() def runTestCaseReport(self): # 将测试用例加载到caseSuite中 caseSuite = unittest.defaultTestLoader.discover("case", "*") bf = BeautifulReport.BeautifulReport(caseSuite) bf.report(description='查找测试用例的', filename='discover%s.html' % (time.time())) if __name__=="__main__": c = RunManyTestCase() c.runTestCase()
执行结果:

5.unittest通过BeautifulReport进行生成报告
import unittest import HTMLTestRunner import time import BeautifulReport class RunManyTestCase(unittest.TestCase): def runTestCase(self): # 将测试用例加载到caseSuite中 caseSuite = unittest.defaultTestLoader.discover("case", "*") f = open("manyReport%s.html" % (time.strftime("%y%m%d")), "wb") runCase = HTMLTestRunner.HTMLTestRunner(f, title="用例集报告", description="xxx系统测试报告") runCase.run(caseSuite) f.close() def runTestCaseReport(self): # 将测试用例加载到caseSuite中 caseSuite = unittest.defaultTestLoader.discover("case", "*") # 生成测试报告,需要先导入BeautifulReport模板,放在当前目录下或python第三方模板安装的site_package文件夹下 bf = BeautifulReport.BeautifulReport(caseSuite) bf.report(description='查找测试用例的', filename='discover%s.html' % (time.time())) if __name__=="__main__": c = RunManyTestCase() c.runTestCaseReport()
执行结果:

附件:HTMLTestRunner.py文件和BeautifulReport.zip压缩吧

import unittest import parameterized class Case(unittest.TestCase): def login(self,userid): return userid @parameterized.parameterized.expand([ [222], [333] ]) def test_login(self,userid): "ss" userid=self.login(userid) return self.assertEqual(userid,222,'成功') suite=unittest.makeSuite(Case) import BeautifulReport.BeautifulReport bf=BeautifulReport.BeautifulReport(suite) bf.report(description="测试报告",filename='关联关系的.html')

b.libs文件夹下定义toos.py
import os import jsonpath from configs.Settings import T0,CC,EMAIL_INFO,LOG,DATAS_PATH import traceback,time,yagmail def get_value(d,k): # 通过jsonpath.jsonpath来取字典中key所对应的值 result=jsonpath.jsonpath(d,'$..%s'%k) # 如果取到了返回第一个值,否则返回空字符串 if result: return result[0] return '' def send_email(pass_count,fail_count,file_name): LOG.debug("开始发送报告了,文件名是%s"%file_name) content=''' 各位好: 本次接口自动化测试结果如下,总共运行%s条用例,通过%s条,失败【%s】条。 详情请查看附件。 '''%((pass_count+fail_count),pass_count,fail_count) subject='%s-接口测试报告'%time.strftime("%Y-%m-%d %H%M%S") email=yagmail.SMTP(**EMAIL_INFO,encoding="GBK") try: email.send(to=T0,cc=CC,subject=subject,contents=content,attachments=file_name) except Exception as e: LOG.error("发送报告失败,具体失败原因是%s"%traceback.format_exc()) else: LOG.debug("报告发送成功") def get_data_from_text(file_name): """获取参数化数据""" data=[] file_name=os.path.join(DATAS_PATH,file_name) with open(file_name,encoding='utf-8') as fr: for line in fr: line=line.strip() if line: data.append(line.split(",")) return data def get_data_from_excel(file_name): """获取参数化数据""" pass def get_data_from_db(file_name): """获取参数化数据""" pass def get_data_from_redis(file_name): """获取参数化数据""" pass
c.configs文件夹下定义Settings.py文件
import os # 发送邮件 EMAIL_INFO={ "user":"13424210282@163.com", "password":"HLXWWGTUWGNAAAEA", "host":"smtp.163.com", } # 邮件接收人 T0=["974219141@qq.com"] # 邮件抄送人 CC=['751462075@qq.com'] # 接口请求url地址配置 host_map={ "fat":"http://127.0.0.1:8787", "uat":"", "pro":"" } default="fat" HOST=host_map.get(default) # 自动化项目父目录 BASE_PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 测试用例目录 CASE_PATH=os.path.join(BASE_PATH,'cases') # 日志文件目录 LOG_PATH=os.path.join(BASE_PATH,"logs",'utp.log') import nnlog LOG=nnlog.Logger(LOG_PATH) # 测试报告目录 REPORT_PATH=os.path.join(BASE_PATH,'reports') # 查询用例 DATAS_PATH=os.path.join(BASE_PATH,'datas')
import unittest import parameterized from libs.tools import get_data_from_text import requests from configs.Settings import HOST from urllib.parse import urljoin class CaseTestLogin(unittest.TestCase): # 拼接接口请求url url=urljoin(HOST,"/login") # 进行参数,通过get_data_from _text获取login.txt文件 @parameterized.parameterized.expand(get_data_from_text("login.txt")) def test_login(self,user,password,check): data={"username":user,"password":password} headers={"Content-Type":"application/json"} # 发送接口请求 r=requests.post(self.url,json=data,headers=headers).text # 校验check参数的值是否在接口返回的字符串中 self.assertIn(check,r,"%s在%s中"%(check,r))
2.有关联关系的接口,先在BaseCase.py文件中定义基类Base_Case
import unittest import requests from configs.Settings import HOST from urllib.parse import urljoin from libs.tools import get_value class Base_Case(unittest.TestCase): def login(self,user,password,check): data = {"username": user, "password": password} headers = {"Content-Type": "application/json"} # 发送接口请求 r = requests.post(urljoin(HOST,"/login"), json=data, headers=headers) # 校验 self.assertIn(check, r.text, "%s在%s中" % (check, r.text)) # 获取接口请求返回的tokenId并进行返回 tokenId=get_value(r.json(),'tokenId') return tokenId
在定义case_pay.py文件中Case_Pay类继承Base_Case类
import unittest import requests from cases import BaseCase from configs.Settings import HOST from urllib.parse import urljoin from parameterized import parameterized from libs.tools import get_data_from_text class Case_Pay(BaseCase.Base_Case): @parameterized.expand(get_data_from_text("pay.txt")) def test_pay(self,user,password,check,money): """支付成功""" tokenId=self.login(user,password,check) data={"username":user,"money":money} headers={"tokenId":tokenId} r=requests.post(urljoin(HOST,"/pay"),json=data,headers=headers) self.assertIn("支付成功",r.text,)
e.datas文件夹下定义login.txt和pay.txt文件

f.bin目录下定义程序运行start.py文件
import sys,os import time BASE_PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0,BASE_PATH) import unittest import BeautifulReport from libs.tools import send_email from configs.Settings import REPORT_PATH,CASE_PATH def run(): suite=unittest.defaultTestLoader.discover(CASE_PATH,"case*.py") bf=BeautifulReport.BeautifulReport(suite) filename="utp报告%s.html"%(time.strftime("%Y%m%d%H%M%S")) report_path=os.path.join(REPORT_PATH,filename) bf.report(description="utp测试报告",filename=filename,log_path=REPORT_PATH) send_email(bf.success_count,bf.failure_count,report_path) if __name__ == '__main__': run()
最后运行bin目录下的start.py文件,可以正常看到测试报告
