httprunner是面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。
4. 创建工程
5. 创建虚拟环境
方法1: mkvirtualenv -p python3 hrun_learn
1. 创建login.yml文件,并添加如下内容
login.yml文件 (以登录qq为例)
name: "登录接口"
variables:
var1: value1
var2: value2
request:
# url: http://127.0.0.1:8000/user/login
url: https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&redirect_uri=http%3A%2F%2Fspcdp.cdposs.qq.com%2Fauth%2Fcallback&client_id=101477813&state=http%3A%2F%2Fspcdp.cdposs.qq.com%2F
method: POST
headers:
Content-Type: "application/json"
json:
# 1. 在项目根目录下的.env中定义环境变量
# 2. 调用环境变量,使用${ENV(变量名)}
username: ${ENV(USERNAME)}
password: ${ENV(PASSWORD)}
validate:
- eq: ["status_code", 200]
env文件
USERNAME=qq账号
PASSWORD=密码
2. 运行测试
1. 基本架构概览
2. api 接口层
login.yml文件
name: "登录接口"
base_url: http://127.0.0.1:8000
variables:
# 4. 可以在variables区域下定义变量,导入环境变量作为值
username: ${ENV(USERNAME)}
password: ${ENV(PASSWORD)}
request:
# 6.可以将url固定部分提出处理,在base_url中定义
url: /user/login
method: POST
headers:
Content-Type: "application/json"
# User-Agent: "Mozilla/5.0 (Windows NT 10.0; WOW64)"
# 5. 可以调用项目根目录下debugtalk.py文件中定义的Python函数
User-Agent: ${get_user_agent()}
json:
# 1. 在项目根目录下的.env中定义环境变量
# 2. 调用环境变量,使用${ENV(变量名)}
#username: ${ENV(USERNAME)}
#password: ${ENV(PASSWORD)}
# 3. 可以使用$变量名,来获取variables区域下的变量
username: $username
password: $password
validate:
# 7.可用的响应属性有:status_code,cookies,elapsed,headers,content,text,json,encoding,ok,reason,url
- eq: ["status_code", 200]
- eq: ["headers.Content-Type", "application/json"]
# 8. check指定断言哪一个字段(哪一个字段)
# comparator指定断言的规则(操作):eq,lte,gt,gte,str_eq,len_eq,contains,contained_by
# {check: "headers.Content-Type",comparator: "eq",expect: "application/json"}
project_create.yml文件
name: 创建项目接口
base_url: http://127.0.0.1:8000
variables:
user_agent: ${get_user_agent()}
my_token: $token
name: ${get_project_name()}
leader: icon
tester: luola
programer: jsonLiu
publish_app: django测开平台
desc: 接口测试项目管理
request:
url: /projects
method: POST
headers:
Content-Type: "application/json"
Accept: "application/json"
User-Agent: $user-agnet
Authorization: JWT $my_tokon
json:
name: $name
leader: $leader
validate:
- eq: ["status_code", 200]
3. code代码逻辑层
run_test.py文件
# —— coding :utf-8 ——
# @time: 2020/10/3 14:40
# @IDE: hrun_learn02
# @Author: xxxxx
# @Email: [email protected]
# @File: run_test.py
from httprunner.api import HttpRunner
# 1.创建HttpRunner对象
# failfast 当用例执行失败之后,会自动暂停
runner = HttpRunner(failfast=False)
# 2.运行用例
# run方法支持如下参数:
# yaml用例文件路径
# 字典(用例的信息)
runner.run(r'G:\python3_code\sublime_text03\14SoftwareTest\APITest\python_apiTest\httprunnerLearn\testsuites\testsuite.yml')
print(runner.summary)
# 3.文件夹路径
# runner.run("testcases")
# 4.混合情况
# runner.run(["testsuites","testsuites/api_testsuite.yml"])
user_agents.py 浏览器代理列表
user_agents = [
# safari5.1–MAC
'User-Agent:Mozilla/5.0(Macintosh;U;IntelMacOSX10_6_8;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50',
# safari5.1–Windows
'User-Agent:Mozilla/5.0(Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50',
# IE9.0
'User-Agent:Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0;',
# IE8.0
'User-Agent:Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)',
# IE7.0
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0)',
# IE6.0
'User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)',
# Firefox4.0.1–MAC
'User-Agent:Mozilla/5.0(Macintosh;IntelMacOSX10.6;rv:2.0.1)Gecko/20100101Firefox/4.0.1',
# Firefox4.0.1–Windows
'User-Agent:Mozilla/5.0(WindowsNT6.1;rv:2.0.1)Gecko/20100101Firefox/4.0.1',
# Opera11.11–MAC
'User-Agent:Opera/9.80(Macintosh;IntelMacOSX10.6.8;U;en)Presto/2.8.131Version/11.11',
# Opera11.11–Windows
'User-Agent:Opera/9.80(WindowsNT6.1;U;en)Presto/2.8.131Version/11.11',
# Chrome17.0–MAC
'User-Agent:Mozilla/5.0(Macintosh;IntelMacOSX10_7_0)AppleWebKit/535.11(KHTML,likeGecko)Chrome/17.0.963.56Safari/535.11',
# 傲游(Maxthon)
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Maxthon2.0)',
# 腾讯TT
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;TencentTraveler4.0)',
# 世界之窗(TheWorld)2.x
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1)',
# 世界之窗(TheWorld)3.x
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;TheWorld)',
# 搜狗浏览器1.x
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Trident/4.0;SE2.XMetaSr1.0;SE2.XMetaSr1.0;.NETCLR2.0.50727;SE2.XMetaSr1.0)',
# 360浏览器
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;360SE)',
# Avant
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;AvantBrowser)',
# GreenBrowser
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1)',
# 移动设备端:
# safariiOS4.33–iPhone
'User-Agent:Mozilla/5.0(iPhone;U;CPUiPhoneOS4_3_3likeMacOSX;en-us)AppleWebKit/533.17.9(KHTML,likeGecko)Version/5.0.2Mobile/8J2Safari/6533.18.5',
# safariiOS4.33–iPodTouch
'User-Agent:Mozilla/5.0(iPod;U;CPUiPhoneOS4_3_3likeMacOSX;en-us)AppleWebKit/533.17.9(KHTML,likeGecko)Version/5.0.2Mobile/8J2Safari/6533.18.5',
# safariiOS4.33–iPad
'User-Agent:Mozilla/5.0(iPad;U;CPUOS4_3_3likeMacOSX;en-us)AppleWebKit/533.17.9(KHTML,likeGecko)Version/5.0.2Mobile/8J2Safari/6533.18.5',
# AndroidN1
'User-Agent:Mozilla/5.0(Linux;U;Android2.3.7;en-us;NexusOneBuild/FRF91)AppleWebKit/533.1(KHTML,likeGecko)Version/4.0MobileSafari/533.1',
# AndroidQQ浏览器Forandroid
'User-Agent:MQQBrowser/26Mozilla/5.0(Linux;U;Android2.3.7;zh-cn;MB200Build/GRJ22;CyanogenMod-7)AppleWebKit/533.1(KHTML,likeGecko)Version/4.0MobileSafari/533.1',
# AndroidOperaMobile
'User-Agent:Opera/9.80(Android2.3.4;Linux;OperaMobi/build-1107180945;U;en-GB)Presto/2.8.149Version/11.10',
# AndroidPadMotoXoom
'User-Agent:Mozilla/5.0(Linux;U;Android3.0;en-us;XoomBuild/HRI39)AppleWebKit/534.13(KHTML,likeGecko)Version/4.0Safari/534.13',
# BlackBerry
'User-Agent:Mozilla/5.0(BlackBerry;U;BlackBerry9800;en)AppleWebKit/534.1+(KHTML,likeGecko)Version/6.0.0.337MobileSafari/534.1+',
# WebOSHPTouchpad
'User-Agent:Mozilla/5.0(hp-tablet;Linux;hpwOS/3.0.0;U;en-US)AppleWebKit/534.6(KHTML,likeGecko)wOSBrowser/233.70Safari/534.6TouchPad/1.0',
# NokiaN97
'User-Agent:Mozilla/5.0(SymbianOS/9.4;Series60/5.0NokiaN97-1/20.0.019;Profile/MIDP-2.1Configuration/CLDC-1.1)AppleWebKit/525(KHTML,likeGecko)BrowserNG/7.1.18124',
# WindowsPhoneMango
'User-Agent:Mozilla/5.0(compatible;MSIE9.0;WindowsPhoneOS7.5;Trident/5.0;IEMobile/9.0;HTC;Titan)',
# UC无
'User-Agent:UCWEB7.0.2.37/28/999',
# UC标准
'User-Agent:NOKIA5700/UCWEB7.0.2.37/28/999',
# UCOpenwave
'User-Agent:Openwave/UCWEB7.0.2.37/28/999',
# UCOpera
'User-Agent:Mozilla/4.0(compatible;MSIE6.0;)Opera/UCWEB7.0.2.37/28/999',
]
4. datas测试数据层
login_data.csv登录数据
正常登录,admin,123456,200,token
用户名为空,,123456,400,non_field_errors
密码为空,admin,,400,non_field_errors
用户名错误,"admin999,123456,400,username
密码错误,admin,123450,400,password
5. testcases测试用例层
login.yml文件
config: # 全局配置
name: "登录接口测试"
variables:
title: "login"
status_code: 200
contain_msg: "token"
base_url: "http://127.0.0.1:8000"
teststeps:
-
name: $title
# 继承api目录下的登录接口,会与本区域定义的variables、validate合并覆盖
api: api/login.yml
validate:
- {check: "status_code",comparator: "eq",expect: $status_code}
- {check: "content",comparator: "contains",expect: $contain_msg}
project_create.yml文件
config:
name: 创建项目接口
variables:
user_agent: ${get_user_agent()}
title: 创建项目
status_code: 201
teststeps:
-
name: 正常登录
# 继承api目录下的登录接口,会与本区域定义的variables、validate合并覆盖
api: api/login.yml
# extract实现接口之间的依赖,将本接口中执行的数据,保存到变量汇总,后面用例调用
extract:
- token: content.token
validate:
- {check: "content", comparator: "contains", expect: "token"}
-
name: $title
api: api/project_create.yml
validate:
- eq: ["status_code", $status_code]
6. testsuites测试套件层
testsuite.yml文件
config:
name: "接口测试套件"
variables:
title: "login"
# base_url: "http://127.0.0.1:8000"
testcases:
-
name: "登录接口"
testcase: testcases/login.yml
# 在parameters下实现数据驱动
parameters:
# 方式1:多个参数具有关联性的参数将其定义在一起,采用短横线“-"连接
- title-username-password-status-code-contain_msg:
- ["正常登录","admin","123456",200,"token"]
- ["用户名为空","","123456",400,"non_field_errors"]
- ["密码为空","admin","",400,"non_field_errors"]
- ["用户名错误","admin999","123456",400,"username"]
- ["密码错误","admin","123450",400,"password"]
# 方式2: 使用csv文件保存测试数据
# - title-username-password-code-contain_msg: ${P(datas/login_data.csv)}
# 方式3:使用函数动态生成参数;函数需要返回嵌套字典的列表
- title-username-password-code-contain_msg: ${get_login_data()}
-
name: call
testcase: path
variables:
device_sn: $device_sn
7. .env 配置文件
USERNAME=leolee
PASSWORD=123456
8. debugtalk.py辅助函数文件
import random
import time
import os
from httprunner import __version__
def get_httprunner_version():
return __version__
def sum_two(m, n):
return m + n
def sleep(n_secs):
time.sleep(n_secs)
def get_login_data():
accounts = [
{"title": "正常登录", "username": "admin", "password": "123456",
"status_code": 200, "contain_msg": "token"},
{"title": "用户名为空", "username": "", "password": "123456",
"status_code": 400, "contain_msg": "non_field_errors"},
{"title": "密码为空", "username": "admin", "password": "",
"status_code": 400, "contain_msg": "non_field_errors"},
{"title": "用户名错误", "username": "Admin", "password": "123456",
"status_code": 400, "contain_msg": "username"},
{"title": "密码错误", "username": "admin", "password": "123458",
"status_code": 400, "contain_msg": "password"},
]
return accounts
def get_user_agent():
user_agents = [
# safari5.1–MAC
'User-Agent:Mozilla/5.0(Macintosh;U;IntelMacOSX10_6_8;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50',
# safari5.1–Windows
'User-Agent:Mozilla/5.0(Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50',
# IE9.0
'User-Agent:Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0;',
# IE8.0
'User-Agent:Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)',
# IE7.0
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0)',
# IE6.0
'User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)',
# Firefox4.0.1–MAC
'User-Agent:Mozilla/5.0(Macintosh;IntelMacOSX10.6;rv:2.0.1)Gecko/20100101Firefox/4.0.1',
# Firefox4.0.1–Windows
'User-Agent:Mozilla/5.0(WindowsNT6.1;rv:2.0.1)Gecko/20100101Firefox/4.0.1',
# Opera11.11–MAC
'User-Agent:Opera/9.80(Macintosh;IntelMacOSX10.6.8;U;en)Presto/2.8.131Version/11.11',
# Opera11.11–Windows
'User-Agent:Opera/9.80(WindowsNT6.1;U;en)Presto/2.8.131Version/11.11',
# Chrome17.0–MAC
'User-Agent:Mozilla/5.0(Macintosh;IntelMacOSX10_7_0)AppleWebKit/535.11(KHTML,likeGecko)Chrome/17.0.963.56Safari/535.11',
# 傲游(Maxthon)
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Maxthon2.0)',
# 腾讯TT
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;TencentTraveler4.0)',
# 世界之窗(TheWorld)2.x
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1)',
# 世界之窗(TheWorld)3.x
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;TheWorld)',
# 搜狗浏览器1.x
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Trident/4.0;SE2.XMetaSr1.0;SE2.XMetaSr1.0;.NETCLR2.0.50727;SE2.XMetaSr1.0)',
# 360浏览器
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;360SE)',
# Avant
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;AvantBrowser)',
# GreenBrowser
'User-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1)',
]
return random.choice(user_agents)
def get_project_name():
base_dir = os.path.split(os.path.split(os.path.realpath(__file__))[0])[-1]
return base_dir
github官方httprunner帮助使用文档链接:https://github.com/httprunner/httprunner/tree/master/docs
中文文档链接: https://docs.httprunner.org/