Python的优势:语法简洁优美, 功能强大, 标准库跟第三方库灰常强大,建议大家事先了解一下Python的基础;
unittest是python的标准测试库,相比于其他测试框架是python目前使用最广的测试框架。
Requests 是用Python语言编写,基于urllib,采用Apache2 Licensed开源协议的HTTP 库。它比urllib 更加方便,可以节约我们大量的工作,完全满足HTTP 测试需求。
话不多说,直接上代码,例子是一个登录接口的请求。
#coding=utf-8 import requests #pip安装requests第三方库,然后引入 import json #引入json标准库,美化json输出 url = 'http://account/login' data = { "username":"01", "password":"password", } result = requests.post(url,data).json() print result
调用requests库中的post方法,会给出所需要的参数,传入上面定义的url和data参数,运行.py文件就执行了post请求。
但是问题来了,这样做,代码的复用性基本不存在,所有这里我们就需要封装一下post请求的方法。执行程序时调用和这个方法就可以了。
# coding=utf-8 import requests # pip安装requests第三方库,然后引入 import json # 引入json标准库,美化json输出 # 定义一个方法,传入需要的参数url和data def send_post(url=None,data=None ): # 参数必须按照url、data顺序传入 # 因为这里要封装post方法,所以这里的url和data值不能写死 result = requests.post(url=url,data=data).json() res = json.dumps(result,ensure_ascii=False,sort_keys=True,indent=2) print res if __name__ == '__main__': url = 'http://***/account/login' data = { "username":"***01", "password":"password", } # 实例化send_post方法,并传入url和data值 post = send_post(url=url,data=data)
当然http请求不止有post一种,那么常见的请求方式还有get,那么同理可以写出get请求的方法,这里就不给大家贴代码了。
思考一下,如果我们要测试一个接口,是不是要考虑他的请求方式呢?那么以后我们要做接口自动化的时候是不是也可以根据接口的请求方式让程序选择我们之前封装好的请求方法呢,答案是肯定的。所以我们这里要把所有的请求方式都封装起来,根据接口的请求方式来调用请求方法;
# coding=utf-8 import requests import json class RunMain: def send_post(self, url, data): # 定义一个方法,传入需要的参数url和data # 参数必须按照url、data顺序传入 result = requests.post(url=url, data=data).json() # 因为这里要封装post方法,所以这里的url和data值不能写死 res = json.dumps(result,ensure_ascii=False,sort_keys=True,indent=2) return res # print res def send_get(self, url, data): result = requests.get(url=url, data=data) res = json.dumps(result,ensure_ascii=False,sort_keys=True,indent=2) return res def run_main(self, method, url=None, data=None): result = None if method == 'post': result = self.send_post(url, data) elif method == 'get': result = self.send_get(url, data) else: print "错误" return result if __name__ == '__main__': url = 'http://***/account/login' data = { "username": "***01", "password": "password" }
至此我们的请求方式就封装好了,可以根据不同的请求方式调用方法来得到相应的返回值了。
现在我们得到结果了,那我们怎么去验证得到的结果是否正确呢,这就用到了Python中比较主流的测试框架unittest,下边通过代码简单的写一下unittest的工作原理。
#coding=utf-8 import unittest class TestDemo(unittest.TestCase): def test_01(self): print "这是第一个测试用例" def test_02(self): print "这是第二个测试用例" if __name__ == '__main__': # unittest.main # unittest框架的TestSuite()类是用来创建测试套件的。 suite = unittest.TestSuite() # addTest()方法是将测试用例添加到测试套件中 suite.addTest(TestDemo('test_01')) suite.addTest(TestDemo('test_02')) #run()方法是运行测试套件的测试用例,入参为suite测试套件。 unittest.TextTestRunner().run(suite)
现在请求方法封装好了,unittest也有了,我们是不是写case然后利用unittest的TestCase执行用例就可以了。
# coding=utf-8 import unittest import json from requests_demo.demo04 import RunMain class TestRun(unittest.TestCase): def setUp(self): self.run_main1 = RunMain() # 测试用例必须以test开头 def test_01(self): url = 'http://***/account/login' data = { "username": "***01", "password": "password", } res = self.run_main1.run_main('post', url, data) #打印得到的结果 print res #看返回值的类型,必须是字典dict才能取到报文中的字段值 print type(res) #调试的时候看下得到的字段是是否正确 print res['status'] #unittest的断言方式,判断a,b是否一致 #assertEqual(a,b,msg) self.assertEqual(res['status'], 0, "测试通过") if __name__ == '__main__': #实例化TestSuite创建测试套件 suite = unittest.TestSuite #把用例test_01添加到测试套件中 suite.addTest(TestRun('test_01')) #run()方法是运行测试套件的测试用例,入参为suite测试套件。 unittest.TextTestRunner().run(suite)
我们还可以利用HTMLTestRunner输出测试报告,HTMLTestRunner是Python 标准库的unittest 模块的一个扩展,它可以生成HTML的测试报告。
# coding=utf-8 import unittest import HTMLTestRunner from requests_demo.demo04 import RunMain class TestRun(unittest.TestCase): def setUp(self): self.run_main1 = RunMain() # 测试用例必须以test开头 def test_01(self): url = 'http://***/account/login' data = { "username": "***01", "password": "password", } res = self.run_main1.run_main('post', url, data) # 打印得到的结果 print(res) # 看返回值的类型,必须是字典dict才能取到报文中的字段值 print(type(res)) # 调试的时候看下得到的字段是是否正确 print(res['status']) # unittest的断言方式,判断a,b是否一致 # assertEqual(a,b,msg) self.assertEqual(res['status'], 0, "测试通过") if __name__ == '__main__': # 实例化TestSuite创建测试套件 suite = unittest.TestSuite # 把用例test_01添加到测试套件中 suite.addTest(TestRun('test_01')) # run()方法是运行测试套件的测试用例,入参为suite测试套件。 # unittest.TextTestRunner().run(suite) file_path = "../report/test_report.html" fp = file(file_path, 'wb') reportRunner = HTMLTestRunner.HTMLTestRunner(stream=fp, title='***系统', description='测试报告') reportRunner.run(suite) fp.close()
至此一个简单的利用Python+request+unittest的接口测试示例就结束了。留给大家一个问题,如果这样维护用例每次都要改代码是不是违背了做自动化的初衷呢?那我们如何利用这套框架来实现接口测试自动化呢?