软件测试知识点和面试题--性能测试篇
软件测试知识点和面试题--手工测试篇
软件测试知识点和面试题--app测试篇
接口规范
接口测试流程
测试用例的思路和方法
pymysql操作数据库
#导入pymysql
import pymysql
#建立连接
conn = pymysql.connect(host='ip', port=3306,user='账号', password='密码',database='数据库名',arset='utf8')
#获取游标
cursor = conn.cursor()
#执行查询语句
cursor.execute('select version();') #返回受影响行数
#查看查询结果
resp = cursor.fetchall()
resp = cursor.fetchone()
resp = cursor.fetchmany(6)
#关闭游标和连接对象
cursor.close()
conn.close()
#执行dml语句
try:
n = cursor.execute('delete from table where id = '1';')
except Exception as e:
# 有异常,回滚事务
logging.info(e)
conn.rollback()
else:
# 没有异常,提交事务
conn.commit()
finally:
# 关闭游标和连接对象
cursor.close()
conn.close()
读取JSON方法
import json
import logging
def param_data(cls, path):
'''
用于参数化,解析json文件
:param path: json文件路径
:return:返回元组型列表[(),(),...]
'''
with open(path, 'r', encoding='utf-8') as f:
json_data = json.load(f)
json_list = []
for i in json_data:
json_list.append(tuple(i.values()))
return json_list
读取XLSX方法
import json
from openpyxl import load_workbook
def read_xlsx(cls, file_path, sheet_name):
'''
:param file_path: xlsx文件路径
:param sheet_name: xlsx底部的工作表名称
:return: [(),(),(),...]
'''
wb = load_workbook(file_path)
sheet = wb.get_sheet_by_name(sheet_name)
case_data = []
i = 2
while i <= sheet.max_row:
# C表格中【标题】的列名,K表格中【请求参数】的列名,L表格中【状态码】的列名,M表格中【预期结果】的列名
tuple_data = sheet[f'C{i}'].value, json.loads(sheet[f'K{i}'].value), sheet[f'L{i}'].value, json.loads(sheet[f'M{i}'].value)
case_data.append(tuple_data)
i += 1
return case_data
Requests使用
导库
import requests
发送请求
resp = requests.请求方式(url,params=查询参数,data=表单请求体,json=json请求体,headers=请求头,cookies=cookies的信息)
multiply表单的请求方式:
resp = requests.请求方式(url,data=表单请求体,files={'x': 'y'})
响应内容获取
状态码
resp.status_code
查看响应头部字符编码
resp.encoding
请求头信息
resp.headers
cookie信息
resp.cookies
请求url
resp.url
返回内容为网页
resp.text
返回内容为json
resp.json()
字节形式的响应内容
resp.content
resp.content.decode('utf-8')
token机制
token机制
获取token后带入请求头内
headers_data={
'Authorization': token值
}
requests.请求方式(url,json=json请求体,headers=请求头)
Session+cookes机制
方式一:
cookie带入请求内,发送请求后获取cookies
response.cookies
将cookies放入请求参数内
requests.请求方式(url,cookies=cookies信息)
方式二:Session对象发送请求
1.创建Session实例对象
session=requests.Session()
2.多个请求使用session发送
resp = session.post('xxx')
3.关闭session
session.close()
日志初始化配置
日志级别
只显示大于等于设置的级别信息
DEBUG
INFO
WARNING
ERROR
CRITICAL
内部实现原理
创建日志器对象
logger = logging.getLogger()
设置日志打印级别
logger.setLevel(logging.INFO)
创建处理器对象
输出到控制台
st = logging.StreamHandler()
输出到日志文件
fh = logging.handlers.TimedRotatingFileHandler('a.log',when='midnight',interval=1,
backupCount=7,encoding='utf-8')
创建格式化器
fmt = '%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s'
给处理器设置格式化器
st.setFormatter(formatter)
fh.setFormatter(formatter)
给日志器添加处理器
logger.addHandler(st)
logger.addHandler(fh)
日志调用
Dubbo接口测试
概念
RPC协议
Dubbo架构
Dubbo是什么
Dubbo是一款高性能、 轻量级、 基于Java的开源RPC框架
为什么使用Dubbo
开源,使用的人比较多
把核心业务抽离出来,通过内部接口通信,提高业务的灵活性
通过分布式提高并发
telnet调用Dubbo接口
连接服务
telnet IP 端口
查看服务列表
ls
显示指定服务中包含的方法
ls -l 服务名
调用服务接口
invoke 服务名.方法(参数)
Python调用Dubbo接口
创建telnet 实例对象
import telnetlib
telnet = telnetlib.Telnet(host, port)
调用接口
telnet.write('invoke 服务名.方法名(参数列表)'.encode())
读取响应数据
telnet.read_until('dubbo>'.encode())
第三方接口测试
接口Mock
定义:
跟开发一样去编写一个接口(虚拟一个接口)
接口Mock测试
使用场景:当针对业务流程进行接口测试时,其中某一个接口无法被获取,为了确保流程能够执行完成,将无法实现的接口进行Mock
项目组常出现无法获取接口的原因:
1. 开发没有完成
2. 第三方接口(测试环境)
会针对Mock的接口,进行专门的单接口测试嘛?
不会
代码实现Mock服务
工具:flask
安装:pip install flask
确认安装:pip show flask
代码实现Mock服务步骤
1. 导包 flask
2. 调用flask,创建应用对象
3. 定义接口的请求方法和请求路径
4. 定义接口返回的响应体数据
5. 启动WEB服务(启动应用对象)
代码实现-Mock(ihrm登录接口)
from flask import Flask, json
# 创建应用对象
app = Flask(__name__)
# 设置Mock接口的请求数据(请求方法,和路径)
@app.route('/login', methods=['get', 'post'])
# 在函数中实现接口的业务逻辑,函数的返回结果(return),为Mock接口的响应体数据
def login():
data = {'success': True, 'code': 10000, 'message': '操作成功!', 'data':'1233333333'}
return json.jsonify(data)
# 调用app配置对象,使用run方法,启动编写的Mock接口
if __name__ == '__main__':
app.run()
Postman支持的请求体数据类型
multipart/form-data,它将表单的数据组织成Key-Value形式;
当上传的字段是文件时,会有content-type来说明文件类型;content-disposition,用来说明字段的一些信息;
由于有boundary隔离,所以multipart/form-data 既可以上传文件,也可以上传键值对,它采用了键值对的方式,所以可以上传多个文件。
application/x-www-from-urlencoded,将表单内的数据转换为Key-Value,只能上传键值对,不能用于文件上传。
传输txt,JavaScript,json,xml,html的数据
表示只可以上传二进制数据,用来上传文件,一次只能上传1个数据
Jmeter请求体支持的数据类型
表单-键值对
文件
Postman执行接口测试
变量优先级
Data ---- > Local ---- > Enviroment ---- > Global
断言
状态码断言
pm.test('Status code is 200', function () {
pm.response.to.have.status(200);
});
包含指定字符串
pm.test('Body matches 成功', function () {
pm.expect(pm.response.text()).to.include('成功');
});
JSON数据断言
pm.test('response json value check', function () {
var jsonData = pm.response.json();
pm.expect(jsonData.success).to.eql(true);
pm.expect(jsonData.code).to.eql(10000);
//大于 pm.expect(jsonData.items.length).to.above(4);
//小于 pm.expect(jsonData.items.length).to.below(6);
//不等于 pm.expect(jsonData.items.length).to.not.eql(6);
});
关联
1.在后置脚本里设置环境变量或全局变量
var jsonData = pm.response.json();
pm.environment.set('token', jsonData.token);
2.非代码区域,使用{{变量名}}
{'token':'{{token}}'}
批量执行测试用例
在用例集合执行RUN
参数化
意义:测试数据和测试脚本分离,提高接口测试效率
数据文件
csv:不支持布尔值和复杂数据类型,数据组织格式简单
json:支持布尔值和复杂数据类型,数据组织格式复杂
引用数据文件
请求参数中获取 {{key}}
代码中(pm内置data对象) data.key
注意
只能通过用例集合RUN,选择数据文件后执行
生成测试报告
1.导出用例集
2.执行命令:newman run 测试脚本文件 -e 环境变量文件 -d 测试数据文件 -r html --reporter-html-export report.html
Jmeter执行接口测试
初始化设置
setUP线程组:在所有普通线程组之前执行
数据库连接配置:连接项目的数据库
HTTP请求默认值:统一管理项目的域名,端口号,编码格式
HTTP Cookie管理器:在线程组中,自动传递接口之间的cookie
用户定义的变量:统一管理,项目中的测试数据
HTTP信息头管理器:统一管理项目中接口的请求头数据
tearDown:在所有普通线程组之后执行
实现接口测试
线程组:一个线程=一条测试用例
HTTP请求:发送接口请求
查看结果树:查看响应/请求数据
实现接口自动化
断言:JSON断言、响应断言
关联:正则表达式提取器、JSON提取器
参数化:CSV数据文件设置
测试数据的初始化/清洗
测试报告
功能和特点
非常容易上手,入门简单,文档丰富,文档中有很多实例可以参考。能够支持简单的单元测试和复杂的功能测试。支持参数化。能够执行全部测试用例,也可以挑选部分测试用例执行,并能重复执行失败的用例。支持并发执行,还能运行由nose,unittest编写的测试用例。方便、简单的断言方式。能够生成标准的JunitXML格式的测试结果。具有很多第三方插件,并且可以自定义扩展。方便的和持续集成工具集成。
用例运行规则
所有的包(package)必项要有__init__.py 文件
文件名以test开头或_test结尾
函数以test_开头
测试类以Test开头,不能包含 __init__ 方法
测试方法以test_开头
调用方式
用于控制Fixture的作用范围作用类似于Pytest的setup/teardown默认取值为function,控制范围的排序为:session>module>class>function
function | 函数级 | 只要测试方法调用到就会执行 |
class | 类级别 | 从调用的测试方法开始,每个测试类只运行一次 |
module | 模块级 | 只从.py文件开始引用fixture的位置生效,每一个.py文件调用一次 |
session | 会话级 | 每次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法 |
用于参数化,Fixture的可选形参列表,支持列表传入默认None,每个param的值fixture都会去调用执行一次,类似for循环可与参数ids一起使用,作为每个参数的标识
@pytest.fixture(params=[1,2,{1,2},(3,2)])
def demo(request):
return request.param #固定写法
用例标识ID与params配合使用,一对一关系
默认False若为True,刚每个测试函数都会自动调用该fixture,无需传入fixture函数名
fixture的重命名通常来说使用fixture的测试函数会将fixture的函数名作为参数传递,但是pytest也允许将fixture重命名如果使用了name,那只能将name传如,函数名不再生效调用方法:@pytest.marusefixtures(‘fixture1’,‘fixture2’)
前后置
参数化
方式一:
@pytest.mark.parametrize('title,body,expected', [(),(),()...])
方式二:
@pytest.fixture(params=[('标题1',{'r':1},{'code':200}),('标题2',{'r':1.1},{'code':200})], ids=['1','2'])
def params_data(request):
return request.param
def test_01(params_data):
print(params_data)
重复执行
1.安装pytest-repeat插件
pip ptyest-repeat
2.mark标注
@pytest.mark.repeat(5) # test_a用例执行5次
def test_demo():
pass
跳过执行
@pytest.mark.skip('skip')
def test_skip(self):
pass
version = 20
@pytest.mark.skipif(version > 20)
def test_skip(self):
pass
断言失败继续执行
1.安装pytest-assume插件
2.断言用pytest.assume(判断)
def test_01():
print('---用例01---')
pytest.assume(1==2)
pytest.assume(1<2)
print('执行完成!')
执行顺序
方式一:
测试方法标上数字 test01_demo test02_demo
方式二:
插件:pytest-ordering,数字越小优先级越高,正数比负数优先级高
@pytest.mark.run(order=1)
def test_demo():
pass
打标签执行
通过自定义标签,可以执行某一类标签的用例
1.在pytest.ini配置marker
markers=
smoke:冒烟测试
2.给用例打标记
@pytest.mark.smoke
def test_mark_1(self):
print('test_mark_1')
3.执行命令:如果标签有逻辑运算时,一定要用双引号,'标签1 and 标签2 or 标签3'
pytest -m '标签名'
pytest执行
pytest
# 全量执行
# run all tests below current dir
pytest test_mod.py
# 指定文件执行
# run tests in module file test_mod.py
pytest somepath
# 指定路径执行
# run all tests below somepath like ./tests/
pytest -k stringexpr
# 模糊查询执行
# only run tests with names that match the
# the 'string expression', e.g. 'MyClass and not method'
# will select TestMyClass.test_something
# but not TestMyClass.test_method_simple
pytest test_mod.py::test_func
# 显式指定函数名
# only run tests that match the 'node ID',
# e.g 'test_mod.py::test_func' will be selected
# only run test_func in test_mod.py
计算pytest覆盖率
测试报告
方式一:
插件:pytest-html
pytest.ini配置:
addopts = --html=./report/report.html
--self-contained-html
方式二:
配合jenkins+Allure使用
jenkins的构建命令:
call pytest case --alluredir ${WORKSPACE}
eportallure_report
exit 0
分布式测试
插件:pytest-xdist
用于解析HTML的内容,使用步骤:
1.创建BeautifulSoup对象 from bs4 import BeautifulSoup bs = BeautifulSoup(data, 'html.parser')
2.常用方法
bs.标签名 #返回整个标签内容
bs.标签名.string #返回标签的值
bs.标签名.get_text() #返回标签的值
bs.标签名.get(属性名称) #返回属性值
bs.find_all(标签名) #返回列表
GIT操作
git 将代码上传到github上 git add –all git commit ‘注释’ git push
git 将github上的代码拉下来 git clone ‘github的项目地址’
jenkin持续集成
基本操作
新建Item;码源管理,关联项目的GITEE地址;设置触发器H8***;输入构建命令;构建后操作,选择HTML报告-PbulishHTMLreports执行构建;
邮箱设置
文章为作者独立观点,不代表股票交易接口观点