自动化测试

自动化测试

使用python做自动化测试,通常使用requests包

request

requests下载

安装命令

pip install requests

国外源下载速度慢,通常会对pip进行换源,加快下载速度

pip的配置文件 C:\Users\lwj\AppData\Roaming\pip此路径下,有如下三种方式换源

1.使用命令整体换源

pipconfig set global.index-url https://mirrors.aliyun.com/pypi/simple

pip config set install.trusted-host mirrors.aliyun.com

2.修改配置文件换源,使用win+r -> %APPDATA% ->找到pip文件夹下的pip.init文件,编辑如下内容

[global]
index-url = https://mirrors.aliyun.com/pypi/simple

[install]
trusted-host = mirrors.aliyun.com

3.命令,单次换源

pip install requests -i https://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com

 

实现HTTP请求

接口自动化三要素

1.定位接口资源:请求方法+请求地址

2.提交测试数据

3.接收响应接口

#api-1.0.jar项目的接口文档
.查询
1.查询所有区域信息
请求方法:GET
  请求地址:http://192.168.10.131:1234/area/listarea
2查询指定单个区域信息
请求方法:GET
  请求地址: http://192.168.10.131:1234/area/getareabyid?areaId=1
(:areaId为参数名称;1为区域ID;)
.新增
2.1新增区域信息
请求方法:POST
请求地址:http://192.168.10.131:1234/area/addarea
请求键值对:areaName="xxx"&priority="yyy"
       新增成功返回报文:{success: true}
.更新
3.1更新区域信息
请求方法:PUT
请求地址: http://192.168.10.131:1234/area/modifyarea
请求json报文:{
           "areaId": 2,
           "areaName": "xxx",
           "priority":"yyy"
      }
修改成功返回:{success: true}
四、删除
4.1删除单个区域信息
  请求方法:DELETE
请求地址: http://192.168.10.131:1234//area/removearea?areaId=2
(:areaId为参数名称;2为区域ID;)

实现代码

import requests
#查询全部区域信息
listarea1 = requests.get("http://192.168.10.131:1234/area/listarea");
listarea1_status_code = listarea1.status_code;
listarea1_content = listarea1.content;
print(listarea1_status_code)
print(listarea1_content)

#查询单个区域性信息
getareabyid1 = requests.get("http://192.168.10.131:1234/area/getareabyid?areaId=1");
print(getareabyid1.status_code)
print(getareabyid1.content)

getareabyid2 = requests.get("http://192.168.10.131:1234/area/getareabyid",params={"areaId":1});
print(getareabyid2.status_code)
print(getareabyid2.content)
#2.1新增区域信息
addarea = requests.post("http://192.168.10.131:1234/area/addarea",data={"areaName":"红中","priority":"100"})
print(addarea.status_code)
print(addarea.content)
#3.1更新区域信息
modifyarea = requests.put("http://192.168.10.131:1234/area/modifyarea",json={ "areaId": 2,"areaName": "红中红红中","priority":"1000"})
print(modifyarea.status_code)
print(modifyarea.content)

##删除单个区域信息
removearea = requests.delete("http://192.168.10.131:1234//area/removearea?areaId=2");
print(removearea.status_code)
print(removearea.content)

总结

params,用于提交键值对数据,在请求行提交,适用于get和delete方法

data,用于提交键值对数据,在请求体提交,适用于put和post方法

json,用于调教json数据,在请求体提交,适用于post和put请求

请求参数解析

requests中所有请求底层都是调用request方法,源码如下

def get(url, params=None, **kwargs):
   return request("get", url, params=params, **kwargs)

重要参数如下

  • method 请求方式

  • url 地址

  • params 请求行的键值对参数

  • data 请求体的键值对参数

  • json 请求体的json格式传参

  • files 用于文件上传headers 请求头

接收响应结果

#查询单个区域性信息
response = requests.get("http://192.168.10.131:1234/area/getareabyid?areaId=1");
#行解析
print("URL:",response.url);
print("状态码",response.status_code);
#头解析
print("headers信息",response.headers)
print("headers中指定信息",response.headers["Content-type"])
print("cookies信息",response.cookies)
#遍历cookies
for key,value in response.cookies.items():
   print(key,value)
# 体解析
print("以文本方式获取响应体",response.text,type(response.text)) #string类型
print("以json格式输出响应体",response.json(),type(response.json())) #字典类型

pymysql

python不具备直接连接数据库的功能,使用第三方库pymysql对数据库进行操作

pymysql安装

pip install pymysql

pymysql使用

创建连接->创建游标->执行sql语句->关闭游标->关闭连接

import pymysql

# 1.创建连接
conn = pymysql.Connect(
   host="192.168.10.131",
   port=3306,
   database="api_test",
   user="root",
   password="123456",
   charset="utf8",
   autocommit=True     # 自动提交
)

# 2.创建游标
cur = conn.cursor()

# 3.核心: 执行 sql 语句, 并处理结果 (有差异性)
# 查询类操作
sql = "select * from t_area"    # sql语句
cur.execute(sql)    # 执行语句

# 处理结果
# row1 = cur.fetchone()   # 一次拿一行数据, 返回一个元组
# print(row1)
# row2 = cur.fetchone()
# print(row2)

rows = cur.fetchall()   # 一次性拿所有数据, 返回一个元组, 每行数据也是一个元组
print(rows)

# 增删改类操作, 以delete为例, 其他都一样
#sql = "delete from t_area where area_name = '333'" # 语句
#cur.execute(sql)   # 执行语句
# conn.commit()   # 提交

# 处理结果
#print(cur.rowcount)     # 打印受影响的行数

# 5.关闭游标
cur.close()

# 6.关闭连接
conn.close()

pytest

概述

pytest是python的一个单元测试框架,相比于自带的unitest框架使用起来更简洁

安装

pip install pytest

pytest运行示例

#demo文件
def demo(x):
if x == '狗':
return("汪汪汪")
if x == '羊':
return("咩咩咩")
if x== '牛':
return("哞哞哞")
#test_demo文件
from pytest_study.demo import demo

class Test_demo:
def test_a(self):
print(demo('狗'))
def test_b(self):
print(demo('羊'))
def test_c(self):
print(demo('牛'))

pytest在执行时,会自动从当前目录及子目录中寻找符合规则的测试函数来执行

  • 测试文件以test_开头

  • 测试类以Test开头,且不能有init方法

  • 测试函数以test_开头

1.在命令行运行pytest

pytest -vs test_demo.py
  • -v 输出更详细的信息

  • -s 支持打印

2.调用pytest提供的main()函数来运行测试函数,写一个run.py文件,专门用于运行

#run.py文件
import pytest

if __name__ == '__main__':
pytest.main(["-vs","test_demo.py"])

断言

可以使用python自带的assert关键字来断言

  • assert 实际结果 == 预期结果类似jmeter中的JSON断言

  • assert 预期结果 in 实际结果类似jmeter中的响应断言

前置和后置方法

前置方法

  • setup_method

    • 方法级别

    • 在测试类中每个测试方法执行前调用

    • 在测试类中定义,方法名必须为setup——method

  • setup_class

    • 类级别

    • 在测试类所有测试方法之前执行

    • 在测试类定义,方法名必须为setup_class

  • setup_medule

    • 模块级别

    • 在模块中所有测试方法之前执行

    • 在模块内定义,不能定义在类中,方法名只能为setup_module

后置方法,有teardown_mothod,teardown_class,teardown_module

配置文件

配置文件为ini格式文件

测试函数的标记和分组执行,先在配置文件注册标记

[pytest]
addopts = -vs
python_files = test_*.py
python_classes = Test
python_functions = test_*

markers =
MY:冒烟测试
HG:回归用例

再使用装饰器标记函数

@pytest.mark.MY
def test_a(self):
assert (demo('狗')) == '汪汪汪'

选择并执行

pytest -m MY用于执行标记了MY的测试用例

[插件]控制执行顺序

使用pytest-ording插件控制执行顺序

安装

pip install pytest-ording

使用

使用装饰器@pytest.mark.run(ording=n)标记测试函数,n代表执行顺序的数字,执行顺序为

0>正数从小到大>不标记>负数从小到大

[插件]测试报告

使用pytest-html插件控制执行顺序

安装

pip install pytest-html

使用

1.pytest.ini通过参数配置

[pytest]
addopts = -vs --html=./report/report.html

2.通过main文件配置

if __name__ == '__main__':
pytest.main(["-vs","--html=report/report.hrml","test_demo.py"])

跳过测试函数

  • 使用装饰器@pytest.mark.skip标记测试函数,表示无条件跳过

  • 使用装饰器@pytest.mark.skio(condition,reson=”X”),表示有条件跳过

    • condition时条件判断,reason用于备注跳过的原因

预期失败

使用装饰器@pytest.mark.xfail标记测试函数,表示预期失败

结果有两种可能性

  • 预期失败,结果失败,属于Expected failues,不是bug

  • 预期失败,结构成果,属于Unexpected Passes,是bug

失败重试

使用pytest-rerunfailues插件实现

安装

pip install pytest-rerunfailures

使用

  • 单个测试函数失败重试,使用@pytest.mark.flaky(reruns=次数,reruns-delay=间隔时长)标记测试函数

    • returns表示重试次数,returns_delay表示间隔多久后再次重试,单位是秒

      @pytest.mark.flaky(reruns=1,reruns_delay=1)
      def test_d(self):
      assert False
  • 全部测试函数失败重试

    [pytest]
    addopts = -vs --html=./report/report.html --reruns 1 --reruns-delay 1

夹具

夹具,本质上也是一个函数,使用装饰器@pytest.fixture标记某个函数为夹具,然后再函数上使用@pytest.mark.usefixtures来引用

  • 标记

@pytest.fixture()
def f():
print("初始化数据")
yield
print("销毁数据")
  • 引用

@pytest.mark.usefixtures("f")
def test_c(self):
print(demo('牛'))

夹具的参数

  • scope 作用域

    • function 函数级别

    • class 类级别

    • module 模块级别

    • session 会话级别,一次性,用的最多

  • antouse 自动使用

    @pytest.fixture(scope="session",autouse=True)
    def f():
    print("初始化数据")
    yield
    print("销毁数据")

胶水文件

conftest.py文件是pytest中一个特殊文件,用于定义测试项目中的夹具,勾子函数等

是一个能写,t.ini文件,会在执行测试前自动加载并运行(无需import)

#conftest.py
import pytest

@pytest.fixture(scope="session",autouse=True)
def f():
print("初始化数据")
yield
print("销毁数据")

数据参数化

 

发表评论