接口自动化测试

霍格沃兹测试开发学社

ceshiren.com

目录

  • Requests 介绍与安装
  • Requests 使用
  • 接口自动化测试实战

Requests 介绍

演练环境

Requests 安装

  • pip 命令安装:pip install requests
  • pycharm 安装

课堂练习

  • 完成 Requests 环境搭建

发送 GET 请求

# 导入 requests 库
import requests

# 使用 requests 中的 get 方法发出 get 请求
# 变量 r 接收接口返回的响应
r = requests.get(url)

响应内容

# 导入 requests 库
import requests

# 发出 get 请求并接收响应赋值给 r
r = requests.get(url)

# r.text 自动解码来自服务器的内容
r.text

# r.content 以字节的方式访问请求响应体
r.content

# r.json() JSON 解码,返回了一个字典
r.json()

# r.raw 原始数据,返回的是一个内存地址
r.raw

课堂练习

响应状态码

# 导入 requests 库
import requests

# 发出 get 请求并接收响应赋值给 r
r = requests.get(url)

# 获取响应状态码
r.status_code

获取响应头信息

# 导入 requests 库
import requests

# 发出 get 请求并接收响应赋值给 r
r = requests.get(url)

# 获取全部响应头信息
r.headers

# 获取响应头信息中某一个字段的值
r.headers['Content-Type']
r.headers.get('content-type')

课堂练习

  • 接口练习网站 https://httpbin.ceshiren.com/
  • 使用 requests 对接口练习网站发起 get 请求,打印响应信息、响应头和响应状态码

传递 URL 参数

# 导入 requests 库
import requests

# 定义请求参数,字典格式
payload = {
  'key1': 'value1', 
  'key2': 'value2'
}

# 发出 get 请求,通过 params 传入请求参数
r = requests.get(url, params=payload)

课堂练习

  • 接口练习网站:https://httpbin.ceshiren.com/

    每个人都有自己的爱好,同学们可以把自己的爱好添加到请求参数中比如某坤的爱好是唱歌
    可以这样表示: name=lily&hobby=sing
  1. 将自己的兴趣爱好使用 url 拼接的形式发送到接口练习网站并打印响应信息
  2. 将自己的兴趣爱好使用 params 的形式发送到接口练习网站并打印响应信息

定制请求头

# 导入 requests 库
import requests

# 定义头信息,字典格式
headers = {
  'user-agent': 'my-app/0.0.1'
}

# 发出 get 请求,通过 headers 传入请求头
r = requests.get(url, headers=headers)

课堂练习

  • 接口练习网站:https://httpbin.ceshiren.com/

    现在同学之间已经很熟悉了,但是老师还是不太熟悉同学们,同学们可以把自我介绍通过添加请求头的方式添加到请求中
    比如自我介绍可以这样表示:
    Introduce-Myself: sing_dance_rap_basketbal。

练习:将自我介绍添加到请求的请求头上,并打印出响应结果

发送 POST 请求

# 导入 requests 库
import requests

# 发出 post 请求
r = requests.post(url, data)

POST 请求传递表单

# 导入 requests 库
import requests

# 定义请求参数,字典格式
payload = {
  'key1': 'value1', 
  'key2': 'value2'
}

# 发出 post 请求,通过 data 传递表单格式请求参数
r = requests.post(url, data=payload)

POST 请求传递 JSON 数据

# 导入 requests 库
import requests

# 定义请求参数,字典格式
payload = {
  'some': 'data'
}

# 发出 post 请求,通过 json 传递 JSON 式请求参数
r = requests.post(url, json=payload)

课堂练习

小明是我们的一个学生,他想要找工作,但是不是特别会编写简历,所以他需要将简历发送给我们,而我们只接受 json 格式的请求,他不太会发送这种格式的请求,同学们可以帮助一下他吗?

接受简历的接口地址:https://httpbin.ceshiren.com/post

小明的简历:

{
	"name": "xiaoming",
	"gender": "man",
	"age": 20,
	"mail": "24786812512@qq.com",
	"address": {
		"province": "北京市",
		"city": "北京市",
		"area": "昌平区"
	},
	"skills": {
		"python": "熟练",
		"pytest": "熟练",
		"allure": "熟练",
		"selenium": "熟练",
		"appium": "熟练"
	}
}

接口自动化测试实战

Requests 调用宠物接口

  • 创建 test_petstore.py
class TestPetstore:

    def test_getpet(self):
        '''
        获取宠物信息
        :return: 
        '''
        url = "https://petstore.swagger.io/v2/pet/findByStatus"
        parmas = {
            "status": "available"
        }
        r = requests.get(url, parmas)
        print(r.json())
        assert r.status_code == 200
        assert "id" in r.text

    def test_addpet(self):
        '''
        添加宠物信息
        :return: 
        '''
        url = "https://petstore.swagger.io/v2/pet"
        data = {

            "id": 9223372000001083222,
            "category": {
                "id": 1,
                "name": "cat"
            },
            "name": "miao",
            "photoUrls": [
                "string"
            ],
            "tags": [
                {
                  "id": 5,
                  "name": "cute"
                }
            ],
            "status": "available"
        }
        r = requests.post(url, json=data)
        print(r.json())
        assert r.status_code == 200
        assert r.json() == data

    def test_updatepet(self):
        '''
        更新宠物信息
        :return: 
        '''
        url = "https://petstore.swagger.io/v2/pet"
        data = {
            "id": 9223372000001083222,
            "category": {
                "id": 1,
                "name": "cat"
            },
            "name": "小小",
            "photoUrls": [
                "string"
            ],
            "tags": [
                {
                    "id": 5,
                    "name": "cute"
                }
            ],
            "status": "available"
        }
        r = requests.put(url, json=data)
        print(r.json())
        assert r.status_code == 200
        assert r.json() == data
    
    def test_deletepet(self):
        '''
        删除宠物信息
        :return: 
        '''
        pet_id = 9223372000001083222
        url = f"https://petstore.swagger.io/v2/pet/{pet_id}"
        r = requests.delete(url)
        print(r.json())
        assert r.status_code == 200
        assert r.json()["message"] == str(pet_id)

课堂练习

  • 优化测试数据的准备
import requests


class TestPetstore:

    def setup_class(self):
        '''
        准备测试数据
        :return: 
        '''
        # 请求的基础 url
        self.url = "https://petstore.swagger.io/v2/pet"
        # 要操作的宠物 id
        self.pet_id = 9223372000001083222
        # 查询状态
        self.find_parmas = {
            "status": "available"
        }
        # 新增宠物的数据
        self.add_data = {
            "id": self.pet_id,
            "category": {
                "id": 1,
                "name": "cat"
            },
            "name": "miao",
            "photoUrls": [
                "string"
            ],
            "tags": [
                {
                  "id": 5,
                  "name": "cute"
                }
            ],
            "status": "available"
        }
        # 更新宠物的数据
        self.update_data = {
            "id": self.pet_id,
            "category": {
                "id": 1,
                "name": "cat"
            },
            "name": "小小",
            "photoUrls": [
                "string"
            ],
            "tags": [
                {
                    "id": 5,
                    "name": "cute"
                }
            ],
            "status": "available"
        }

    def test_getpet(self):
        '''
        获取宠物信息
        :return:
        '''
        get_url = self.url + "/findByStatus"

        r = requests.get(get_url, self.find_parmas)
        print(r.json())
        assert r.status_code == 200
        assert "id" in r.text

    def test_addpet(self):
        '''
        新增宠物信息
        :return: 
        '''

        r = requests.post(self.url, json=self.add_data)
        print(r.json())
        assert r.status_code == 200
        assert r.json() == self.add_data

    def test_updatepet(self):
        '''
        更新宠物信息
        :return: 
        '''
        r = requests.put(self.url, json=self.update_data)
        print(r.json())
        assert r.status_code == 200
        assert r.json() == self.update_data

    def test_deletepet(self):
        '''
        删除宠物信息
        :return: 
        '''
        delete_url = self.url + "/" + str(self.pet_id)
        r = requests.delete(delete_url)
        print(r.json())
        assert r.status_code == 200
        print(r.json())
        assert r.json()["message"] == str(self.pet_id)

课堂练习

  • 添加 allure 报告

  • 搜集测试结果

    • pytest test_petstore.py --alluredir=./result
  • 生成 allure 报告

    • allure serve ./result
    • allure generate --clean result -o result/html
import allure
import requests

@allure.feature("宠物商店宠物信息接口测试")
class TestPetstore:

    @allure.story("查询宠物接口冒烟用例")
    def test_getpet(self):
        '''
        获取宠物信息
        :return:
        '''
        get_url = self.url + "/findByStatus"
        
        with allure.step("发出查询接口请求"):
            r = requests.get(get_url, self.find_parmas)
        with allure.step("获取查询接口响应"):
            print(r.json())
        with allure.step("查询接口断言"):
            assert r.status_code == 200
            assert "id" in r.text

    @allure.story("新增宠物接口冒烟用例")
    def test_addpet(self):
        '''
        新增宠物信息
        :return:
        '''
        with allure.step("发出新增接口请求"):
            r = requests.post(self.url, json=self.add_data)
        with allure.step("获取新增接口响应"):
            print(r.json())
        with allure.step("新增接口断言"):
            assert r.status_code == 200
            assert r.json() == self.add_data

    @allure.story("更新宠物接口冒烟用例")
    def test_updatepet(self):
        '''
        更新宠物信息
        :return:
        '''
        with allure.step("发出更新接口请求"):
            r = requests.put(self.url, json=self.update_data)
        with allure.step("获取更新接口响应"):
            print(r.json())
        with allure.step("更新接口断言"):
            assert r.status_code == 200
            assert r.json() == self.update_data

    @allure.story("删除宠物接口冒烟用例")
    def test_deletepet(self):
        '''
        删除宠物信息
        :return:
        '''
        delete_url = self.url + "/" + str(self.pet_id)
        with allure.step("发出删除接口请求"):
            r = requests.delete(delete_url)
        with allure.step("获取删除接口响应"):
            print(r.json())
        with allure.step("删除接口断言"):
            assert r.status_code == 200
            assert r.json()["message"] == str(self.pet_id)

总结

  • 接口自动化的环境配置与使用
  • 接口自动化脚本编写与断言