request库,unittest框架
一、设置 http 请求语法
resp = requests.请求方法(url='URL地址', params={k:v}, headers={k:v}, data={k:v}, json={k:v}, cookies='cookie数据'(如:令牌)) 请求方法: get请求 - get() post请求 - post() put请求 - put() delete请求 - delete() url: 待请求的url - string类型 params:查询参数 - 字典 headers:请求头 - 字典 data:表单格式的 请求体 - 字典 json:json格式的 请求体 - 字典 cookies:cookie数据 - string类型 resp:响应结果
二、cookie
1、cookie:工程师 针对 http协议是无连接、无状态特性,设计的 一种技术。 可以在浏览器端 存储用户的信息。
2、特性:
cookie 用于存储 用户临时的不敏感信息。
cookie 位于浏览器(客户端)端。默认大小 4k(可以调整)
cookie 中的数据,可以随意被访问,没有安全性可言。
cookie 中存储的数据类型, 受浏览器限制。
3、Cookie+Session认证方式
在计算机中,认证用户身份的方式有多种!课程中接触 2种:
ihrm项目:token认证。
tpshop项目:cookie+Session认证。
4、案例
完整实现 TPshop商城登录,并获取 “我的订单” 页面数据。
获取验证码:http://tpshop-test.itheima.net/index.php?m=Home&c=User&a=verify
登录:http://tpshop-test.itheima.net/index.php?m=Home&c=User&a=do_login
我的订单:http://tpshop-test.itheima.net/Home/Order/order_list.html
import requests # 发送 获取验证码请求 resp_v = requests.get(url="http://tpshop-test.itheima.net/index.php? m=Home&c=User&a=verify&r=0.21519623710645064") # 从 获取验证码 的响应结果,提取 cookie my_cookie = resp_v.cookies # 发送 post 登录请求 url、请求头、请求体。 携带 cookie。 得响应结果 resp = requests.post(url="http://tpshop-test.itheima.net/index.php? m=Home&c=User&a=do_login&t=0.7094195931397276", headers={"Content-Type": "application/x-www-form-urlencoded"}, data={"username": "13012345678", "password": "12345678", "verify_code": "8888"}, cookies=my_cookie) # 打印响应结果 print(resp.json()) # 发送 查看我的订单 请求 resp_o = requests.get(url="http://tpshop-test.itheima.net/Home/Order/order_list.html", cookies=my_cookie) print(resp_o.text)
三、session
1、介绍:也叫 会话。通常出现在网络通信中,从客户端借助访问终端登录上服务器,直到 退出登录 所产生的通信数据,保存在 会话中。
2、特性:
Session 用于存储 用户的信息。
Session 位于服务端。大小直接使用服务器存储空间
Session 中的数据,不能随意被访问,安全性较高。
Session 中存储的数据类型,受服务器影响,几乎能支持所有的数据类型。
3、Session自动管理Cookie
因为 Cookie 中的 数据,都是 Session 传递的。因此,Session 可以直接 自动管理 cookie
4、案例:
借助session重新实现 上述 TPshop商城登录,并获取 “我的订单” 页面数据。
1. 创建一个 Session 实例。
2. 使用 Session 实例,调 get方法,发送 获取验证码请求。(不需要获取cookie)
3. 使用 同一个 Session 实例,调用 post方法,发送 登录请求。(不需要携带 cookie)
4. 使用 同一个 Session 实例,调用 get方法,发送 查看我的订单请求。(不需要携带 cookie)
import requests # 1. 创建一个 Session 实例。 session = requests.Session() # 2. 使用 Session 实例,调 get方法,发送 获取验证码请求。(不需要获取cookie) resp_v = session.get(url="http://tpshop-test.itheima.net/index.php? m=Home&c=User&a=verify&r=0.21519623710645064") # 3. 使用 同一个 Session 实例,调用 post方法,发送 登录请求。(不需要携带 cookie) resp = session.post(url="http://tpshop-test.itheima.net/index.php? m=Home&c=User&a=do_login&t=0.7094195931397276", data={"username": "13012345678", "password": "12345678", "verify_code": "8888"}) print(resp.json()) # 4. 使用 同一个 Session 实例,调用 get 方法,发送 查看我的订单请求。(不需要携带 cookie) resp_o = session.get(url="http://tpshop-test.itheima.net/Home/Order/order_list.html") print(resp_o.text)
四、获取指定响应数据
1、常用
获取 URL:resp.url
获取 响应状态码:resp.status_code
获取 Cookie:resp.cookies
获取 响应头:resp.headers
获取 响应体:
文本格式:resp.text
json格式:resp.json()
import requests resp = requests.get(url="http://www.baidu.com") # - 获取 URL:resp.url print("url =", resp.url) # - 获取 响应状态码:resp.status_code print("status_code =", resp.status_code) # - 获取 Cookie:resp.cookies print("cookies =", resp.cookies) # - 获取 响应头:resp.headers print("headers =", resp.headers) # - 获取 响应体: # - 文本格式:resp.text print("body_text =", resp.text) # - json格式:resp.json() #当显示 JSONDecodeError 错误时,说明 resp 不能转换为 json格式数据。 print("body_json =", resp.json())
五、unittest 框架(重点:TestCase、Fixture、TestSuite、TestRunner)
UnitTest 是开发人员用来实现 “单元测试” 的框架。测试工程师,可以在自动化 “测试执行” 时使用。
使用 UnitTest 的好处:
1. 方便管理、维护测试用例。
2. 提供丰富的断言方法。
3. 生成测试报告。(需要插件 HTMLTestReport)
注意点:
1、测试方法必须以 test 开头,建议添加编号:def test001_xxx(self):
例子:
import unittest import requests #自定义测试类 class TestIhrmLogin(unittest.TestCase): #添加测试方法 def test01_login_ok(self): # 发送 post 登录请求,指定 url、请求头、请求体,获取响应结果 resp = requests.post(url="http://ihrm-test.itheima.net/api/sys/login", json={"mobile": "13800000002", "password": "123456"}) print(resp.json()) # 断言- 响应状态码为 200 self.assertEqual(200, resp.status_code) # 断言 success 的值为 true self.assertEqual(True, resp.json().get("success")) # 断言 code 的值为 10000 self.assertEqual(10000, resp.json().get("code")) # 断言 message 的值为 操作成功! self.assertIn("操作成功", resp.json().get("message")) #手机号不存在 def test01_tel_not_exist(self): # 发送 post 登录请求,指定 url、请求头、请求体,获取响应结果 resp = requests.post(url="http://ihrm-test.itheima.net/api/sys/login", json={"mobile": "13800000702", "password": "123456"}) print(resp.json()) # 断言- 响应状态码为 200 self.assertEqual(200, resp.status_code) # 断言 success 的值为 true self.assertEqual(True, resp.json().get("success")) # 断言 code 的值为 10000 self.assertEqual(10000, resp.json().get("code")) # 断言 message 的值为 操作成功! self.assertIn("操作成功", resp.json().get("message")) #密码错误 def test01_password_fail(self): # 发送 post 登录请求,指定 url、请求头、请求体,获取响应结果 resp = requests.post(url="http://ihrm-test.itheima.net/api/sys/login", json={"mobile": "13800000002", "password": "123457"}) print(resp.json()) # 断言- 响应状态码为 200 self.assertEqual(200, resp.status_code) # 断言 success 的值为 true self.assertEqual(True, resp.json().get("success")) # 断言 code 的值为 10000 self.assertEqual(10000, resp.json().get("code")) # 断言 message 的值为 操作成功! self.assertIn("操作成功", resp.json().get("message"))
提示:使用unittest里面的参数化parameterized(上面代码冗余,进行优化)
import json import unittest from parameterized import parameterized from get_base_dir import BASE_DIR # 拿到项目目录 # 待测函数 def login(username, password): if username == 'admin' and password == '123456': return '登录成功' else: return '登录失败' # 读取json文件数据 def build_data(): with open(BASE_DIR + '/data/login_data.json', 'r', encoding='utf8') as f: json_data = json.load(f) # [{}, {}, {}] ---> [(), (), ()] new_list = [] # 创建一个空列表 for data in json_data: # data 为字典 数据 a = tuple(data.values()) # 取 字典的 values 部分,组成元组 new_list.append(a[1:]) # 剔除 desc 这个 key 对应的 value,将剩余内容,存入空列表 return new_list # 循环结束,将 装满 元组的列表 [(), (), ()] 返回 class TestLogin(unittest.TestCase): @parameterized.expand(build_data()) def test_login(self, username, pwd, code, expect): ret = login(username, pwd) self.assertEqual(expect, ret) # def test01_username_pwd_right(self): # """正确用户名和密码""" # ret = login('admin', '123456') # self.assertEqual('登录成功', ret) # # def test02_username_error(self): # """错误用户名""" # ret = login('root', '123456') # self.assertEqual('登录失败', ret) # # def test03_pwd_error(self): # """错误密码""" # ret = login('admin', '123123') # self.assertEqual('登录失败', ret) # # def test04_username_pwd_error(self): # """错误用户名和错误密码""" # ret = login('aaa', '1231123') # self.assertEqual('登录失败', ret)
data数据格式
[ { "desc": "正确的⽤户名和密码", "username": "admin", "password": "123456", "code": "8888", "expect": "登录成功" }, { "desc": "不存在的⽤户名", "username": "root", "password": "123456", "code": "8888", "expect": "登录失败" }, { "desc": "错误的密码", "username": "admin", "password": "123123", "code": "8888", "expect": "登录失败" }, { "desc": "错误的验证码", "username": "admin", "password": "123456", "code": "9999", "expect": "登录失败" } ]
设置绝对路径
""" 获取项目目录,提供给其他模块使用 """ import os BASE_DIR = os.path.dirname(__file__)
执行用例run suite
import unittest from htmltestreport import HTMLTestReport # 小写的是包名,大写的是类名 from case.test_login import TestLogin # 导入测试用例类 from get_base_dir import BASE_DIR # 获取项目目录 # 2. 创建 测试套件实例 suite = unittest.TestSuite() # () 不能丢!千万不能丢! # 3. 测试套件实例,调用 addTest() ,组装测试用例。 suite.addTest(unittest.makeSuite(TestLogin)) # 4. 指定 生成的测试报告的 路径 和 名称 report_path = BASE_DIR + '/report/login测试报告.html' # 指定目录,如果目录不存在,会报错。 报告的后缀名,必须是 html # 5. 创建 HTMLTestReport 类的实例,同时,使用上面指定好的报告名、标题(可选)、描述(可选) ht_report = HTMLTestReport(report_path, title='登录测试报告', description='没有使用验证码,对登录进行测试') # 6. 运行测试套件组装的测试用例,生成报告 ht_report.run(suite)
生成测试报告
import unittest #导入unittest 模块 suite = unittest.defaultTestLoader.discover(r'填写用例路径') # 1、创建一个测试执行器 runner = unittest.TextTestRunner() # 2、执行测试套件中的所有用例 runner.run(suite) # 方法1不会自动生成网页测试报告 只是在控制台输出我们的测试用例执行通过与否
案例 2:
# 导包 import unittest import requests class TestTsphopRegist(unittest.TestCase): def setUp(self): # 实例化session self.session = requests.Session() self.url = "http://tpshop-test.itheima.net/Home/User/reg.html" self.headers = {"Content-Type": "application/x-www-form-urlencoded"} def tearDown(self): # 关闭Session self.session.close() # 将session实现注册的代码拷贝到框架中 def test01_regist(self): # 使用session发送获取验证码的请求 resp_verify = self.session.get( url="http://tpshop-test.itheima.net/index.php?m=Home&c=User&a=verify&type=user_reg") # 断言响应头中包含 image self.assertIn('image', resp_verify.headers.get('Content-Type')) # 使用session发送注册的请求 response = self.session.post(url=self.url, headers=self.headers, data={"scene": "1", "username": "13822138017", "verify_code": "8888", "password": "123456", "password2": "123456", "invite": ""}) # 断言 响应状态码 200 self.assertEqual(200, response.status_code) # 断言 响应体 status 1 self.assertEqual(1, response.json().get('status')) # 断言 响应体 msg 登录成功 self.assertEqual('注册成功', response.json().get('msg')) # 打印注册的结果 print("注册的结果为:", response.json())