接口自动化测试

目录

一、HTTP协议

URL

HTTP协议

二、接口规范

传统接口风格

 RESTful

 三、Postman接口测试

接口测试用例

 Postman

四、接口自动化基础

接口自动化测试

接口自动化测试流程

接口自动化框架设计思路

搭建基础框架-定义项目目录结构

五、Requests库

Requests介绍

Requests发送请求

Response查看响应

对象接口封装

Requests处理multipart/form-data

六、登录示例

数据驱动

项目配置文件

七、Allure报告

allure介绍

操作步骤


一、HTTP协议

URL

URL:是互联网上标准资源的地址,一般称为统一资源定位符

组成:协议://hostname[:post]/path/[?查询参数1 & 查询参数2]

默认端口号:http(80),https(443)


URL由哪几部分组成?

  • 协议
  • 服务器地址
  • 端口号
  • 资源路径
  • 参数

HTTP协议

HTTP:超文本传输协议,基于请求与响应的应用层协议

作用:规定了客户端与服务器之间信息传递规范,是二者共同遵守的协议

组成:

  • HTTP请求:定义请求数据格式  [ 请求行、请求头、请求体 ]
  • HTTP响应:定义响应数据格式  [ 状态行、响应头、响应体 ]

请求行 

位置:请求数据第一行

作用:说明请求方法访问的资源、协议版本

常用请求方法:

  • GET:从服务器获取资源
  • POST:在服务器新建一个资源
  • PUT:在服务器更新资源
  • DELETE:从服务器删除资源

请求行

位置:请求数据第二行到空白行之间

作用:通知服务器客户端请求信息

特点:请求头部由键值对组成,每行一对

Content-Type:请求体数据类型

  • text/html:HTML格式
  • image/jpeg:jpg图片格式
  • application/json:JSON数据格式
  • application/x-www-form-urlencodeed:表单默认的提交数据格式
  • multipart/form-data:在表单中进行文件上传时使用

请求体

位置:空白行之后的内容

作用:传输数据实体

注意:请求体常在POSTPUT方法中使用

常配合的请求头:Content-Type 和 Content-Length


状态行

位置:响应数据第一行

作用:描述服务器处理结果

内容:状态行由协议版本号、状态码、状态消息组成

状态码:三位数字组成。第一个数字定义响应类别

  • 1XX:指示信息
  • 2XX:成功
  • 3XX:重定向
  • 4XX:客户端错误
  • 5XX:服务器错误

 响应头

位置:第二行到空白行之间

作用:描述客户端要使用的一些附加信息

特点:响应头由键值对组成,每行一对

响应体

位置:响应数据空白行之后

作用:服务器返回的数据实体

特点:有图片、json、xml、html等多种类型

二、接口规范

作用:让前端开发与后台接口开发人员更好的配合,提高工作效率

常见接口规范:

  • 传统接口风格
  • RESTful接口风格

传统接口风格

示例:对用户进行相关操作的相关接口,包括增删改查

 RESTful

RESTful:一种网络应用程序的设计风格和开发方式,提供了一组设计原则和约束条件

示例:

 特点:

  • 请求API和URL用来定位资源
  • 通过标准HTTP方法对资源进行增删改查操作
  • 利用HTTP状态码返回状态信息

区别

 三、Postman接口测试

1.拿到一个接口项目之后,先测试业务接口还是先测试单个接口?

  • 先测试业务接口

2.如何测试业务接口?

  • 根据业务流程图梳理业务路径
  • 设计测试用例覆盖每一条业务路径

3.如何进行接口文档解析?

  • 分析接口之间的依赖关系
  • 分析接口请求(如:URL、请求方法、请求头、请求参数类型、请求参数)
  • 分析接口响应(如:响应状态码、响应数据等)

接口测试用例

 Postman

介绍:Postman一款接口调试工具

特点:支持Mac、Windows和Linux

下载:https://www.postman.com/


如何使用Postman发送请求并查看响应结果?

  1. 设置请求方法
  2. 设置URL
  3. 设置请求头
  4. 设置请求数据
  5. 点击Send发送请求
  6. 查看响应状态码
  7. 查看相应体数据

自动关联

1.Postman自动关联解决了什么技术问题?

  • 接口之间需要自动传递数据

2.Postmen自动关联实现思路:

  1. 提取关联数据:pm.response.json()
  2. 保存关联数据:pm.environment.set()
  3. 引用关联数据:{{变量名}}

3.如何针对单个接口设计测试用例?

  • 正向:必填参数、全部参数
  • 逆向:空、类型错误、长度错误、规则不符

断言

作用:让Postman工具代替人工自动判定预期结果和实际结果是否一致

用法:点击Tests--->选择断言方式--->在Test Results查看断言结果

响应状态码断言

模板名称:Status code:Code is 200

模板内容:(只需修改200)

// 判断响应状态码是否等于200
pm.test("Status code is 200",function(){
    pm.response.to.have.status(200);
});

pm.test()
// 参数1:字符串-测试断言名称
// 参数2:回调函数-具体断言语句

// 判断是否包含指定的状态码
pm.response.to.have.status(code:Number)

包含指定字符串断言

模板名称:Response body:Contains string

模板内容:(只需修改"string_you_want_to_search"字符串)

// 判断响应结果是否包含指定字符串
pm.test("Body matches string",function(){
    pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});

// 通过一系列调用链判断是否符合预期
pm.expect()     // 接收实际结果
    .to         // 连接符,用于连接断言方式和预期结果
    .include()  // 获取响应结果的文本格式数据

// 获取响应结果的文本格式数据
pm.presponse.text();

JSON数据断言

模板名称:Response body:JSON value check

模板内容:(修改jsonData.value 和 100)

// 校验响应的JSON数据
pm.test("Your test name",function(){
    var jsonData = pm.response.json();
    pm.expect(jsonData.value).to.eql(100);
});

// 通过一系列调用链判断是否符合预期
pm.response.json() // 获取响应结果的json数据
    .eql()         // 用于指定断言方式和预期结果

参数化

场景:测试脚本中仅测试数据不一样,使用参数化提高脚本复用

步骤:

  1. 测试书保存在数据文件单独维护
  2. 引用数据文件实现脚本循环调用

实现:

准备数据文件:

{"username":"root","password":"123456","status":"200","message":"成功","msg":"操作成功"}

引用数据文件:

        1.请求参数中获取

                {{}}引用相关对象的key

                eg:{{username}}

        2.代码中获取

                postman内置data对象引用key

                eg.data.status

选择数据文件:运行测试集时选择数据文件

四、接口自动化基础

接口自动化测试

接口自动化:使用工具或代码代替人对接口进行测试的技术

测试目的:防止开发修改代码时引入新的问题

测试时机:

开发进行系统测试转测前,可以先进行接口自动化脚本的编写

开发进行系统测试转测后,有限进行系统测试用例的执行,在进行接口自动化脚本的编写

接口自动化测试流程

  1. 选取自动化测试用例
  2. 搭建自动化测试环境
  3. 搭建自动化测试框架
  4. 代码实现自动化
  5. 输出测试报告
  6. 实现持续集成

核心技术:

  • 编程语言:python
  • 测试框架:pytest
  • 接口请求:requests

接口自动化框架设计思路

  1. 搭建基础框架:定义项目目录结构
  2. 通用功能类封装:封装通用功能如:数据库工具类等
  3. 接口对象封装与调用:封装接口API对象+PyTest框架编写测试脚本
  4. 测试数据参数化:测试数据json文件设计、参数化实现
  5. 用例组织运行:组织测试用例运行,生成测试报告

搭建基础框架-定义项目目录结构

apiTestFramework        # 项目名称

|——api                        # 定义封装被测系统的接口

|——script                    # 定义测试用例脚本

|——data                     # 存放测试数据文件

|——report                  # 存放生成的测试报告

|——common             #存放通用工具类

|——config.py            #定义项目的配置信息

|——pytest.ini            #pytest配置文件

五、Requests库

Requests介绍

Requests库:python中的“浏览器”,基于urllib的HTTP库

安装:pip3 install requests

验证:pip3 show requests

操作步骤:

  1. 导包
  2. 发送接口请求
  3. 查看响应数据

Requests发送请求

requests.请求方法(url, params=None, data=None, json=None, headers=None)

说明:

  • 常见的请求方法:get/post/put/delete
  • url:                      请求的url地址
  • params:              请求查询参数
  • data:                   请求体为form表单参数
  • json:                   请求体为json参数
  • headers:             请求头参数

Response查看响应

 示例:

# 导包
import requests

# 发送请求
response = requests.get(url="http://www.baidu.com")

# 查看响应
print(response.status_code)
print(response.text)

对象接口封装

核心思想:代码分层思想

接口对象层

  • 根据接口API文档封装
  • 重点关注如何调用接口
  • 请求参数从测试脚本层传递
  • 接口响应结果返回给脚本层

测试脚本层:

  • 重点关注测试数据准备和断言
  • 重点关注业务流程的处理
  • 直接调用接口对象层发送请求

Requests处理multipart/form-data

requests.请求方法(url, data=None, json=None, headers=None, files=None)

说明:

files:上传的文件

符合提交multipart/form-data数据?

1.读取文件数据

        f = open("test.pdf", "rb")

2.设置请求数据

        response = requests.post(url=xxx, files={"file":f})

六、登录示例

api文件夹内容

login.py

# 导包
import requests

# 创建接口类
class LoginAPI:
    # 初始化
    def __init__(self):
        self.url_verify = "http://kdtx-test.itheima.net/api/captchaImage"
        self.url_login = "http://kdtx-test.itheima.net/api/login"

    # 验证码
    def get_verify_code(self):
        return requests.get(url=self.url_verify)

    # 登录
    def login(self, test_data):
        return requests.get(url=self.url_login, json=test_data)

script文件夹内容

test01_login.py

# 导包
form api.login import LoginAPI

# 创建测试类
class TestLoginAPI:
    # 初始化
    uuid = None

    # 前置处理
    def setup(self):
        # 实例化接口类
        self.login_api = LoginAPI()
        # 获取验证码
        response = self.login_api.get_verify_code()
        print(response.json())
        # 提取验证码接口返回的uuid参数值
        TestLoginAPI.uuid = response.json().get("uuid")
        print(TestLoginAPI.uuid)

    # 后置处理
    def teardown(self):
        pass

    # 登录成功
    def test01_success(self):
        login_data = {
            "username":"manager",
            "password":"123456",
            "code":"2",
            "uuid":TestLoginAPI.uuid
        }
        response = self.login_api.login(test_data=login_data)
        # 断言响应状态码为200
        assert 200 == response.status_code
        # 断言响应数据包含“成功”
        assert '成功' in response.text
        # 断言响应json数据中code值
        assert 200 == response.json().get("code")

    # 登录失败(用户名为空)
    def test02_witout_username(self):
        login_data = {
            "username":"",
            "password":"123456",
            "code":"2",
            "uuid":TestLoginAPI.uuid
        }
        response = self.login_api.login(test_data=login_data)
        # 断言响应状态码为200
        assert 200 == response.status_code
        # 断言响应数据包含“错误”
        assert '错误' in response.text
        # 断言响应json数据中code值
        assert 500 == response.json().get("code")

    # 登录失败(未注册用户)
    def test03_username_not_exist(self):
        login_data = {
            "username":"jack666",
            "password":"123456",
            "code":"2",
            "uuid":TestLoginAPI.uuid
        }
        response = self.login_api.login(test_data=login_data)
        # 断言响应状态码为200
        assert 200 == response.status_code
        # 断言响应数据包含“错误”
        assert '错误' in response.text
        # 断言响应json数据中code值
        assert 500 == response.json().get("code")

Python常见断言方式有哪些?

  • 相等断言(assert test_data == 'xxx')
  • 包含断言(assert 'xxx' in test_data)

数据驱动

数据驱动:以测试数据驱动脚本执行,维护焦点从脚本转向测试数据的一种自动化测试设计模式

好处:将测试数据和测试脚本进行分离,便于测试数据的处理


pytest中parametrize装饰器

作用:遍历所有测试数据并运行测试方法

语法:

@pytest.mark.parametrize(②保存数据参数名, ①测试数据)

def test_method(self, ③参数名)

        pass

示例:

test_data=[("manager","123456"),("","123456"),("jack666","123456")]

@pytest.mark.parametrize("mobile,passwd",test_data)
def test_login(self, mobile,passwd)
    pass
# 导包
form api.login import LoginAPI
import pytest

# 测试数据
test_data = [
    ("manager","123456",200,'成功',200),
    ("","123456",200,'错误',500),
    ("jack666","123456",200,'错误',500)
]

# 创建测试类
class TestLoginAPI:
    # 初始化
    uuid = None

    # 前置处理
    def setup(self):
        # 实例化接口类
        self.login_api = LoginAPI()
        # 获取验证码
        response = self.login_api.get_verify_code()
        print(response.json())
        # 提取验证码接口返回的uuid参数值
        TestLoginAPI.uuid = response.json().get("uuid")
        print(TestLoginAPI.uuid)

    # 后置处理
    def teardown(self):
        pass

    # 登录成功
    @pytest.mark.parametrize("username, password, status, message, code",test_data)
    def test01_success(self, username, password, status, message, code):
        login_data = {
            "username":username,
            "password":password,
            "code":"2",
            "uuid":TestLoginAPI.uuid
        }
        response = self.login_api.login(test_data=login_data)
        # 断言响应状态码为200
        assert status == response.status_code
        # 断言响应数据包含“成功”
        assert message in response.text
        # 断言响应json数据中code值
        assert code == response.json().get("code")

   

将测试数据和测试脚本分开,需要将测试数据转为json格式,存放到data文件夹下login.json

[
    {
        "username":"manager",
        "password":"123456",
        "status":200,
        "message":"成功",
        "code":200
    },
    {
        "username":"",
        "password":"123456",
        "status":200,
        "message":"错误",
        "code":500
    },
    {
        "username":"jack666",
        "password":"123456",
        "status":200,
        "message":"错误",
        "code":500
    },
]

测试脚本读取json文件

# 导包
form api.login import LoginAPI
import pytest
import json

# 测试数据
# test_data = [
#     ("manager","123456",200,'成功',200),
#     ("","123456",200,'错误',500),
#     ("jack666","123456",200,'错误',500)
# ]

# 读取json文件
def build_data(json_file):
    # 定义空列表
    test_data = []
    # 打开json文件
    with open(json_file, "r") as f:
        # 加载json文件数据
        json_data = json.load(f)
        # 循环遍历测试数据
        for case_data in json_data:
            # 转换数据格式[{},{}] ==> [(),()]
            username = case_data.get("username")
            password = case_data.get("password")
            status = case_data.get("status")
            message = case_data.get("message")
            code = case_data.get("code")
            test_data.append(username, password, status, message, code)
    # 返回处理之后测试数据
    return test_data

# 创建测试类
class TestLoginAPI:
    # 初始化
    uuid = None

    # 前置处理
    def setup(self):
        # 实例化接口类
        self.login_api = LoginAPI()
        # 获取验证码
        response = self.login_api.get_verify_code()
        print(response.json())
        # 提取验证码接口返回的uuid参数值
        TestLoginAPI.uuid = response.json().get("uuid")
        print(TestLoginAPI.uuid)

    # 后置处理
    def teardown(self):
        pass

    # 登录成功
    @pytest.mark.parametrize("username, password, status, message, code",build_data(json_file="../data/login.json"))
    def test01_success(self, username, password, status, message, code):
        login_data = {
            "username":username,
            "password":password,
            "code":"2",
            "uuid":TestLoginAPI.uuid
        }
        response = self.login_api.login(test_data=login_data)
        # 断言响应状态码为200
        assert status == response.status_code
        # 断言响应数据包含“成功”
        assert message in response.text
        # 断言响应json数据中code值
        assert code == response.json().get("code")

   

项目配置文件

由于在每个测试接口中都定义了项目环境域名url地址,导致后续将测试地址改为正式地址较为麻烦,所以将域名配置到config.py文件下

我们使用相对路径时,运行会造成路径错误,将项目路径配置到文件中

config.py

# 导包
import os

# 设置项目环境域名
BASE_URL = "http://kdtx-test.itheima.net"

# 获取项目根路径
BASE_PATH = os.path.dirname(__file__)

/api/login.py

# 导包
import requests
import config

# 创建接口类
class LoginAPI:
    # 初始化
    def __init__(self):
        # 指定url基本信息
        # self.url_verify = "http://kdtx-test.itheima.net/api/captchaImage"
        self.url_verify = config.BASE_URL + "/api/captchaImage"

        # self.url_login = "http://kdtx-test.itheima.net/api/login"
        self.url_login = config.BASE_URL + "/api/login"

    # 验证码
    def get_verify_code(self):
        return requests.get(url=self.url_verify)

    # 登录
    def login(self, test_data):
        return requests.get(url=self.url_login, json=test_data)
# 上传合同成功
def test01_upload_contract(self):
    #读取pdf文件
    # f = open("../data/test.pdf","rb")
    f = open(config.BASE_PATH + "/data/test.pdf","rb")
    response = self.contract_api_upload_contract(test_data=f, token=TestContractBusiness.token)

七、Allure报告

allure介绍

介绍:

  • 能生成美观易读的报告
  • 支持多种开发语言,如java、python等
  • 能快速上手

操作步骤:

  • 生成测试结果文件(json文件)
  • 使用allure命令生成在线报告

帮助文档:https://docs.qameta.io/allure/

操作步骤

1.生成测试结果文件

安装:pip insatll allure-pytest

使用步骤:

1.将pytest配置文件中的命令行参数加上如下代码

--alluredir report

2.编写好测试脚本后,在命令行行中运行pytest

[pytest]

# 指定运行模式,allure产生目录
addopts = -s --alluredir report

# 指定运行的代码文件所在目录
testpath = ./sscripts

# 目录下面哪些文件会被运行
python_files = test*.py

# 文件下哪些类会被运行
python_classes = Test*

# 类下面的哪些方法会被运行
python_functions = test*

pytest.ini文件

[pytest]
addopts = -s --alluredir report
testpath = ./sscripts
python_files = test*.py
python_classes = Test*
python_functions = test*

3.程序运行结束收,会在项目的report目录中生成一些json文件

2.使用allure生成在线报告

安装:

  1. 下载https://github.com/allure-framework/allure2/releases
  2. 解压压缩包到一个不包含中文路径的目录
  3. 右键我的电脑- 属性 - 高级设置 - 环境变量 - 找到系统环境变量的path项 - 增加alure到bin目录
  4. 在命令行中输入 allure --version 命令,能显示allure版本信息,即为成功

在终端运行pytest,产生测试结果文件(json文件)

产生报告:allure serve report

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

舒克小先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值