接口测试和单元测试详解 点击文末小卡片免费获取软件测试全套资料资料在手涨薪更快接口测试的本质就是通过数据驱动测试类里面的函数。单元测试的本质通过代码级别测试函数。单元测试的框架unitest接口pytestWEB-----接口pytestjenkinsallure。requests 模块讲解和应用基础知识url:请求的地址 http://xxx:portparam:传递的参数 非必填参数 字典的格式传递参数method:请求方式 支持get 以及post 字符串形式的参数cookie:请求的时候传递的cookie值利用requests模块写代码做接口测试。利用request封装get请求和post请求做接口测试。以下文件都在request文件夹下。#文件http_request_get.py import requests urlhttp://120.78.128.25:8765/Index/login.html resrequests.get(url) print(res) print(响应头,res.headers) print(响应状态码,res.status_code) print(响应正文,res.text)#html#文件http_request_post.py import requests urlhttp://httpbin.org/post data{name:qinghan,age:18} resrequests.post(url,data)#消息实体 print(响应头,res.headers) print(响应状态码,res.status_code) print(响应正文,res.text,type(res.text))#html print(响应正文2,res.json(),type(res.json()))伪装请求头 User-Agent#文件http_request_post_chongzhi.py import requests urlhttp://v.juhe.cn/laohuangli/d data{key:abf91475fc19f66c2f1fe567edd75257,date:2014-09-09} resrequests.post(url,data)#响应结果的消息实体 http response包含响应头响应状态码响应正文Cookie print(响应头,res.headers) print(响应状态码,res.status_code) print(**cookies**:,res.cookies)#从消息实体中拿到cookies print(**cookies value**:,res.cookies[aliyungf_tc])#类字典形式 Key取值 print(响应正文,res.text,type(res.text))#html print(响应正文2,res.json(),type(res.json())) recharge_urlhttp://v.juhe.cn/laohuangli/d recharge_data{key:abf91475fc19f66c2f1fe567edd75257,date:2014-09-09} header{User-Agent:Mozilla/5.0 }#伪装充值的请求头 recharge_resrequests.get(recharge_url,recharge_data,headersheader,cookiesres.cookies) print(充值结果,recharge_res.json()) print(状态码,recharge_res.status_code) print(代理userAgent,recharge_res.request.headers)#获取请求头 request #伪装请求头骗服务器可以用来爬虫如果别人有更高级的反爬虫那就不行了。哈哈复制消息实体中拿到cookie#文件http_request_post_cookies.py import requests urlhttp://v.juhe.cn/laohuangli/d data{key:abf91475fc19f66c2f1fe567edd75257,date:2014-09-09} resrequests.post(url,data)#消息实体 print(响应头,res.headers) print(响应状态码,res.status_code) print(**cookies**:,res.cookies)#从消息实体中拿到cookies print(**cookies value**:,res.cookies[aliyungf_tc])#类字典形式 Key取值 print(响应正文,res.text,type(res.text))#html print(响应正文2,res.json(),type(res.json())) 响应头 {Date: Sun, 02 Feb 2020 13:39:07 GMT, Content-Type: application/json;charsetutf-8, Transfer-Encoding: chunked, Connection: keep-alive, Set-Cookie: aliyungf_tcAQAAAC3SDE8KIAYAonD0eNi5kz0Qf9BA; Path/; HttpOnly, Etag: 063d270dc44003f39cf480b7ec6ff843} 响应状态码 200 **cookies**: RequestsCookieJar[Cookie aliyungf_tcAQAAAC3SDE8KIAYAonD0eNi5kz0Qf9BA for v.juhe.cn/] **cookies value**: AQAAAC3SDE8KIAYAonD0eNi5kz0Qf9BA 响应正文 {reason:successed,result:{id:1666,yangli:2014-09-09,yinli:甲午(马)年八月十六,wuxing:杨柳木 开执位,chongsha:冲牛(丁丑)煞西,baiji:癸不词讼理弱敌强 未不服药毒气入肠,jishen:天恩 母仓 月德 不将 四相 阴德 金堂 时阳 生气 天仓,yi:祭祀 立碑 修坟 启钻 除服 成服 馀事勿取,xiongshen:五虚 土符 触水龙,ji:馀事勿取},error_code:0} class str 响应正文2 {reason: successed, result: {id: 1666, yangli: 2014-09-09, yinli: 甲午(马)年八月十六, wuxing: 杨柳 登录-充值了解cookie是先登录的时候会产生然后在这个网站充值的时候直接就有cookie了。以下代码来自文件夹Tools。#清菡没有找到登录和充值的接口所以用的老黄历的接口模拟测试的。以下代码除了接口地址不对代码可以用。 #来自文件http_request_1.py。 import requests class Httprequest: 利用requests封装get请求和post请求 def http_request(self,url,data,method,cookieNone): url:请求的地址 http://xxx:port param:传递的参数 非必填参数 字典的格式传递参数 method:请求方式支持get以及post 字符串形式的参数 cookie:请求的时候传递的cookie值 if method.lower()get: res requests.get(url, data, cookiescookie) else: resrequests.post(url,data,cookiescookie)#响应结果的消息实体 http response包含响应头响应状态码响应正文Cookie return res#返回一个消息实体 if __name__ __main__: url http://v.juhe.cn/laohuangli/d data {key: abf91475fc19f66c2f1fe567edd75257, date: 2014-09-09} resHttprequest().http_request(url,data,post) print(登录结果是, res.json()) #充值 recharge_urlhttp://v.juhe.cn/laohuangli/d recharge_data{key:abf91475fc19f66c2f1fe567edd75257,date:2014-09-09} recharges_resHttprequest().http_request(recharge_url,recharge_data,get,res.cookies) print(充值结果是,recharges_res.json())#来自request_danyuanceshi.py文件 #这个项目是没有cookies的啊你们测试找个有cookie的接口来测试user_password我没写可以自己找个接口来测。 import requests class HttpRequest: 利用request封装get请求和post请求 def http_request(self,url,data,method,cookieNone): url:请求的地址 http://xxx:port param:传递的参数 非必填参数 字典的格式传递参数 method:请求方式支持get以及post 字符串形式的参数 cookie:请求的时候传递的cookie值 if method.lower()get: res requests.get(url, data, cookiescookie) else: resrequests.post(url,data,cookiescookie,verifyFalse)#响应结果的消息实体 http response包含响应头响应状态码响应正文Cookie return res#返回一个消息实体 if __name__ __main__: url http://a.buka.tv/buka/api/user/login.do data{user_phone_num:18210033224,user_password:保密,user_device:b9a0c082-e133-f0d5-e7d1-aff61f8e2cf8} resHttpRequest().http_request(url,data,post) print(布卡项目登录接口查询结果是{0}.format(res.text)) print(布卡项目登录接口cookies是{0}.format(res.cookies)) url_1 http://a.buka.tv/buka/api/usercenterauth/userstate.do data {user_token:1234,user_device:b9a0c082-e133-f0d5-e7d1-aff61f8e2cf8} res_2 HttpRequest().http_request((url_1),data,post,res.cookies) print(布卡项目搜索接口查询结果是{0}.format(res_2.text)) print(布卡项目搜索接口接口cookies是{0}.format(res.cookies))python 单元测试-unittest功能测试1.写用例: TestCase2.执行用例:TestSuite 存储用例。TestLoader 找用例找到TestSuite的用例加载出来。3.对比实际结果、期望结果判断用例是否通过对比结果是否通过叫做断言。断言Assert4.出具测试报告TextTestRunnerunittest里面的TestCase专门来写用例写一个测试类对我们自己写的math method模块里面的类进行单元测试。以下文件都在unittest36文件夹下。首先创建一个文件math_method.py。class MathMethod: def __init__(self,a,b): self.aa self.bb def add(self): return self.aself.b def multi(self): return self.a*self.b#来自文件case1.py import unittest from math_method import MathMethod class TestMathMethod(unittest.TestCase):#继承了unittest里面的TestCase专门来写用例 #编写测试用例 #一个用例就是一个函数不能传参。只有self关键字 #所有的用例所有的函数都是test开头test_) def test_add_two_positive(self):#两个正数相加 11 resMathMethod(1,1).add()#实际发起请求的结果值 print(11的结果值是,res) def test_add_two_zero(self):#两个0相加 00 resMathMethod(0,0).add() print(00的结果值是,res) def test_add_two_negative(self):#两个负数相加 -1-2 resMathMethod(-1,-2).add() print(00的结果是,res) if __name__ __main__: unittest.main()方法1创建实例。可以只执行1条也可以执行多条。#来自文件TestSuite_fanfa1.py import unittest from unittest36.case1 import TestMathMethod suiteunittest.TestSuite()#存储用例的容器 #方法一 #只执行一条 两个正数相加 #创建实例 suite.addTest(TestMathMethod(test_add_two_zero)) #再创建一条实例 suite.addTest(TestMathMethod(test_add_two_positive)) #执行 runnerunittest.TextTestRunner() runner.run(suite)文件case1.py和TestSuite_fanfa1.py为1组run文件TestSuite_fanfa1.py。方法2到测试类里面去找用例根据这个测试类去加载到所有的用例。loader是一个加载器 它去帮你寻找用例寻找完直接用addTest这个方法加到容器TestSuite里面去执行。#来自文件TestSuite_fanfa2_1.py import unittest from unittest36.case1 import TestMathMethod suiteunittest.TestSuite()#存储用例的容器 #TestLoader 找用例加载用例 loaderunittest.TestLoader()#创建一个加载器 #是到测试类里去找 suite.addTest(loader.loadTestsFromTestCase(TestMathMethod)) #执行 runnerunittest.TextTestRunner() runner.run(suite)文件case1.py和TestSuite_fanfa2_1.py为1组run文件TTestSuite_fanfa2_1.py。#来自文件case2 import unittest from math_method import MathMethod class TestMathMethod(unittest.TestCase):#继承了unittest里面的TestCase专门来写用例 #编写测试用例 #一个用例就是一个函数不能传参。只有self关键字 #所有的用例所有的函数都是test开头test_) def test_add_two_positive(self):#两个正数相加 11 resMathMethod(1,1).add()#实际发起请求的结果值 print(11的结果值是,res) def test_add_two_zero(self):#两个0相加 00 resMathMethod(0,0).add()# print(00的结果值是,res) def test_add_two_negative(self):#两个负数相加 -1-2 resMathMethod(-1,-2).add()# print(00的结果是,res) class TestMulti(unittest.TestCase):#继承了unittest里面的TestCase专门来写用例 # #编写测试用例 # 一个用例就是一个函数不能传参。只有self关键字 # 所有的用例所有的函数都是test开头test_) def test_multi_two_positive(self):#两个正数相乘 1*1 resMathMethod(1,1).multi()# print(unittest36*1的结果值是,res) def test_multi_two_zero(self):#两个0相乘 0*0 resMathMethod(0,0).multi()# print(0*0的结果值是,res) def test_multi_two_negative(self):#两个负数相乘 -1*-2 resMathMethod(-1,-2).multi()# print(-unittest36*-2的结果值是,res) if __name__ __main__: unittest.main()方法3从模块里去加载用例加载该模块所有的用例。#来自文件TestSuite_fanfa2_2.py import unittest from unittest36.case2 import TestMathMethod suiteunittest.TestSuite()#存储用例的容器 #TestLoader 找用例加载用例 loaderunittest.TestLoader()#创建一个加载器 from unittest36 import case1#具体到模块 #会到case2里面去找所有的用例从模块里加载测试用例 suite.addTest(loader.loadTestsFromModule(case2)) #执行 runnerunittest.TextTestRunner() runner.run(suite)文件case2.py和TestSuite_fanfa2_2.py为1组run文件TestSuite_fanfa2_2.py。常见的断言需要掌握的断言断言 assertEqual#来自文件Assert.py # 断言 assertEqual import unittest from unittest36.math_method import MathMethod#测试的目标类 class TestMathMethod(unittest.TestCase):#继承了unittest里面的TestCase专门来写用例 def test_add_two_positive(self):#两个正数相加 resMathMethod(1,1).add()#实际发起请求的结果值 print(11的结果值是,res) #加个断言判断期望值与实际值的对比结果一致计算通过。不一致就算失败。 self.assertEqual(2,res)#assertEqual()来自父类TestCase def test_add_two_zero(self):#两个0相加 00 resMathMethod(0,0).add()# print(00的结果值是,res) self.assertEqual(1, res,两个0相加出错了)#断言里面msg是用例执行失败的时候才会显示 def test_add_two_negative(self):#两个负数相加 -1-2 resMathMethod(-1,-2).add()# print(-1-2的结果值是,res) self.assertEqual(-3,res) class TestMulti(unittest.TestCase): # 继承了unittest里面的TestCase专门来写用例 def test_multi_two_positive(self): # 两个正数相乘 1*1 res MathMethod(1, 1).multi() # print(1*1的结果值是, res) def test_multi_two_zero(self): # 两个0相乘 0*0 res MathMethod(0, 0).multi() # print(0*0的结果值是, res) def test_multi_two_negative(self): # 两个负数相乘 -1*-2 res MathMethod(-1, -2).multi() # print(-1*-2的结果值是, res) if __name__ __main__: unittest.main() # Assert.py TestSuite_fanfa2_2.py执行#来自文件TestSuite_fanfa2_2.py import unittest from unittest36.Assert import TestMathMethod suiteunittest.TestSuite()#存储用例的容器 #TestLoader 找用例加载用例 loaderunittest.TestLoader()#创建一个加载器 from unittest36 import Assert#具体到模块 #会到Assert里面去找所有的用例从模块里加载测试用例 suite.addTest(loader.loadTestsFromModule(Assert)) #执行 runnerunittest.TextTestRunner() runner.run(suite)文件Assert.py和TestSuite_fanfa2_2.py为1组run文件TestSuite_fanfa2_2.py。测试报告#来自文件ceshibaogao_txt.py import unittest from unittest36.Assert import TestMathMethod suiteunittest.TestSuite()#存储用例的容器 #TestLoader 找用例加载用例 loaderunittest.TestLoader()#创建一个加载器 #是到测试类里去找 suite.addTest(loader.loadTestsFromTestCase(TestMathMethod)) #执行 fileopen(test.txt,w,encodingUTF-8) runnerunittest.TextTestRunner(streamfile,verbosity0)#verbosity0verbosity1verbosity2 显示不一样2最详细 runner.run(suite) 根据ASCII编码按照字母排序的。 posive#2 zero#3 negative#1 执行结果 -1-2的结果值是 -3 11的结果值是 2 00的结果值是 0 文件Assert.py和文件ceshibaogao_txt.py为1组run文件Tceshibaogao_txt.py。必须加encodingUTF-8,否则输出的txt显示乱码。加了之后正确显示。上下文管理器如果不关闭文件会占用资源影响性能。#shangxiawenguanliqi.py import unittest from unittest36.Assert import TestMathMethod suiteunittest.TestSuite()#存储用例的容器 #TestLoader 找用例加载用例 loaderunittest.TestLoader()#创建一个加载器 #是到测试类里去找 suite.addTest(loader.loadTestsFromTestCase(TestMathMethod)) #执行 上下文管理器 with open(test.txt,w,encodingUTF-8)as file:#执行完代码file会自动关闭掉。 runnerunittest.TextTestRunner(streamfile, verbosity2)#0 1 2 2是最详细的 runner.run(suite) print(file.closed)文件Assert.py和文件shangxiawenguanliqi.py为1组run文件shangxiawenguanliqi.py。异常处理异常处理就是加raise e#来自文件yichangchuli.py #异常处理就是加raise e # 异常处理完了之后记得要抛出去 #如果不加raise e用例就会全部通过 import unittest from unittest36.math_method import MathMethod#测试的目标类 class TestMathMethod(unittest.TestCase):#继承了unittest里面的TestCase专门来写用例 def test_add_two_positive(self):#两个正数相加 unittest36unittest36 resMathMethod(1,1).add()#实际发起请求的结果值 print(11的结果值是,res) try: self.assertEqual(2,res)#assertEqual()来自父类 except AssertionError as e: print(出错了断言错误是{0}.format(e)) raise e # 异常处理完了之后记得要抛出去 def test_add_two_zero(self):#两个0相加 00 resMathMethod(0,0).add()# print(00的结果值是,res) try: self.assertEqual(1, res,两个0相加出错了)#断言里面msg是用例执行失败的时候才会显示 except AssertionError as e: print(出错了断言错误是{0}.format(e)) raise e # 异常处理完了之后记得要抛出去 def test_add_two_negative(self):#两个负数相加 -1-2 resMathMethod(-1,-2).add()# print(-1-2的结果值是, res) try: self.assertEqual(-3, res) except AssertionError as e: print(出错了断言错误是{0}.format(e)) raise e # 异常处理完了之后记得要抛出去 class TestMulti(unittest.TestCase):#继承了unittest里面的TestCase专门来写用例 # #编写测试用例 # #一个用例就是一个函数不能传参。只有self关键字 # #所有的用例所有的函数都是test开头test_) def test_multi_two_positive(self):#两个正数相乘 1*1 resMathMethod(1,1).multi()# print(unittest36*1的结果值是,res) def test_multi_two_zero(self):#两个0相乘 0*0 resMathMethod(0,0).multi()# print(0*0的结果值是,res) def test_multi_two_negative(self):#两个负数相乘 -1*-2 resMathMethod(-1,-2).multi()# print(-unittest36*-2的结果值是,res) if __name__ __main__: unittest.main()#来自文件test_report.py import unittest import HTMLTestRunner#别人写好的一个模块你可以直接调用 from unittest36.set_upandtear_down import TestMathMethod suiteunittest.TestSuite()#存储用例的容器 #TestLoader 找用例加载用例 loaderunittest.TestLoader()#创建一个加载器 #是到测试类里去找 suite.addTest(loader.loadTestsFromTestCase(TestMathMethod)) #新鲜 html with open(test_report.html,wb) as file: runnerHTMLTestRunner.HTMLTestRunner(streamfile, verbosity2, title学python自动化 单元测试报告, description第一次报告,tester清菡 ) runner.run(suite)文件yichangchuli.py和文件test_report.py为1组run文件test_report.py。setUp和tearDown根据用例名进行识别每条用例执行前都会执行setUp每条用例执行完毕后都会执行tearDown这就是夹心饼干。如果有操作必须在执行用例之前准备好那就放在setUp里面例如连接数据库放在setUp里面有操作必须在执行用例后要清除掉那就放在tearDown里面例如操作完毕关闭操作数据库放在tearDown里面。#来自文件set_upandtear_down.py import unittest from unittest36.math_method import MathMethod#测试的目标类 class TestMathMethod(unittest.TestCase):#继承了unittest里面的TestCase专门来写用例 def setUp(self): print(我要开始执行用例了) def tearDown(self): print(我已经执行完用例了) def test_add_two_positive(self):#两个正数相加 unittest36unittest36 resMathMethod(1,1).add()#实际发起请求的结果值 print(11的结果值是,res) try: self.assertEqual(2,res)#assertEqual()来自父类 except AssertionError as e: print(出错了断言错误是{0}.format(e)) raise e # 异常处理完了之后记得要抛出去 def test_add_two_zero(self):#两个0相加 00 resMathMethod(0,0).add()# print(00的结果值是,res) try: self.assertEqual(1, res,两个0相加出错了)#断言里面msg是用例执行失败的时候才会显示 except AssertionError as e: print(出错了断言错误是{0}.format(e)) raise e def test_add_two_negative(self):#两个负数相加 -1-2 resMathMethod(-1,-2).add()# print(-1-2的结果值是, res) try: self.assertEqual(-3, res) except AssertionError as e: print(出错了断言错误是{0}.format(e)) raise e#异常处理完了之后记得要抛出去 class TestMulti(unittest.TestCase):#继承了unittest里面的TestCase专门来写用例 # #编写测试用例 # #一个用例就是一个函数不能传参。只有self关键字 # #所有的用例所有的函数都是test开头test_) def test_multi_two_positive(self):#两个正数相乘 1*1 resMathMethod(1,1).multi()# print(1*1的结果值是,res) def test_multi_two_zero(self):#两个0相乘 0*0 resMathMethod(0,0).multi()# print(0*0的结果值是,res) def test_multi_two_negative(self):#两个负数相乘 -1*-2 resMathMethod(-1,-2).multi()# print(-1-2的结果值是,res) if __name__ __main__: unittest.main()#来自文件test_report.py import unittest import HTMLTestRunner#别人写好的一个模块你可以直接调用 from unittest36.set_upandtear_down import TestMathMethod suiteunittest.TestSuite()#存储用例的容器 #TestLoader 找用例加载用例 loaderunittest.TestLoader()#创建一个加载器 #是到测试类里去找 suite.addTest(loader.loadTestsFromTestCase(TestMathMethod)) #新鲜 html with open(test_report.html,wb) as file: runnerHTMLTestRunner.HTMLTestRunner(streamfile, verbosity2, title学python自动化 单元测试报告, description第一次报告,tester清菡 ) runner.run(suite)文件set_upandtear_down.py和test_report.py为1组run文件test_report.py。常识1.开发写接口的时候定义好的get还是post请求这些是写死的。并不是所有的请求都支持get和post有时候都支持有时候只支持get,有时候只支持post根据接口文档来看。接口抓不到的原因人家是get请求你非要post去抓2.为什么有些接口抓不到别的接口包括接口地址参数未必都可以抓到例如腾讯的数据会加密或者是根本抓不到。3.抓到接口了哪个才是我想要的东西呢找关键字。 例如/User/Api/login 这就是个登录的接口有Api啊Api就是关键字。4.登录的时候有cookie是保存登录信息例如账户用户名密码。不是所有的东西都有cookie这个是开发定义的看软件的需求呢。第一次登录生成cookie下次登录就会根据用户名密码这些信息对比校验是不是同一个人。这就是cookie。例如考勤就没有cookie因为考勤是每天都得打卡得所以不需要cookie。5.注意鼠标放哪就执行哪条用例如果鼠标放在全部用例的后面点击run就会执行所有的用例。最后感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走这些资料对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你凡事要趁早特别是技术行业一定要提升技术功底。