Python接口测试案例如何测试API接口

wen python案例 22

本文目录导读:

Python接口测试案例如何测试API接口

  1. 环境准备
  2. 基础接口测试案例
  3. 使用pytest框架进行测试
  4. 完整的接口测试框架
  5. 实际项目测试案例
  6. 运行测试
  7. 最佳实践建议

我来为你详细介绍Python接口测试的完整案例,从基础到实战。

环境准备

安装依赖库

pip install requests pytest allure-pytest

基础接口测试案例

1 简单的GET请求测试

import requests
import json
def test_get_user():
    """测试获取用户信息的GET接口"""
    url = "https://api.example.com/users/1"
    # 发送GET请求
    response = requests.get(url)
    # 打印响应信息
    print(f"状态码: {response.status_code}")
    print(f"响应体: {response.text}")
    # 断言验证
    assert response.status_code == 200
    assert response.json()["id"] == 1
    assert "username" in response.json()
# 执行测试
test_get_user()

2 POST请求测试

def test_create_user():
    """测试创建用户的POST接口"""
    url = "https://api.example.com/users"
    # 请求数据
    payload = {
        "name": "张三",
        "email": "zhangsan@example.com",
        "age": 25
    }
    # 发送POST请求
    response = requests.post(
        url,
        json=payload,
        headers={"Content-Type": "application/json"}
    )
    # 验证响应
    assert response.status_code == 201
    assert response.json()["name"] == "张三"
    assert "id" in response.json()
test_create_user()

使用pytest框架进行测试

1 创建测试文件 test_api.py

import pytest
import requests
class TestAPI:
    """API测试类"""
    BASE_URL = "https://api.example.com"
    def setup_method(self):
        """每个测试方法执行前的准备工作"""
        self.session = requests.Session()
        self.session.headers.update({
            "Content-Type": "application/json"
        })
    def teardown_method(self):
        """每个测试方法执行后的清理工作"""
        self.session.close()
    # 测试GET请求
    def test_get_all_users(self):
        """测试获取所有用户"""
        response = self.session.get(f"{self.BASE_URL}/users")
        assert response.status_code == 200
        assert isinstance(response.json(), list)
        assert len(response.json()) > 0
    # 测试POST请求
    def test_create_user_success(self):
        """测试创建用户成功"""
        payload = {
            "name": "测试用户",
            "email": "test@example.com"
        }
        response = self.session.post(
            f"{self.BASE_URL}/users",
            json=payload
        )
        assert response.status_code == 201
        data = response.json()
        assert data["name"] == payload["name"]
        assert data["email"] == payload["email"]
    # 测试参数化
    @pytest.mark.parametrize("user_id,expected_name", [
        (1, "张三"),
        (2, "李四"),
        (3, "王五")
    ])
    def test_get_user_by_id(self, user_id, expected_name):
        """测试根据ID获取用户,参数化测试"""
        response = self.session.get(f"{self.BASE_URL}/users/{user_id}")
        assert response.status_code == 200
        assert response.json()["name"] == expected_name

完整的接口测试框架

1 创建测试工具类 api_client.py

import requests
import json
from typing import Dict, Any
class APIClient:
    """API客户端封装"""
    def __init__(self, base_url: str, headers: Dict = None):
        self.base_url = base_url
        self.session = requests.Session()
        if headers:
            self.session.headers.update(headers)
    def get(self, endpoint: str, params: Dict = None) -> requests.Response:
        """发送GET请求"""
        url = f"{self.base_url}{endpoint}"
        return self.session.get(url, params=params)
    def post(self, endpoint: str, data: Dict = None, json_data: Dict = None) -> requests.Response:
        """发送POST请求"""
        url = f"{self.base_url}{endpoint}"
        return self.session.post(url, data=data, json=json_data)
    def put(self, endpoint: str, data: Dict = None) -> requests.Response:
        """发送PUT请求"""
        url = f"{self.base_url}{endpoint}"
        return self.session.put(url, json=data)
    def delete(self, endpoint: str) -> requests.Response:
        """发送DELETE请求"""
        url = f"{self.base_url}{endpoint}"
        return self.session.delete(url)

2 创建测试数据管理 test_data.py

import json
import os
class TestData:
    """测试数据管理"""
    @staticmethod
    def load_test_data(file_path: str) -> Dict:
        """从JSON文件加载测试数据"""
        with open(file_path, 'r', encoding='utf-8') as f:
            return json.load(f)
    @staticmethod
    def get_test_user() -> Dict:
        """获取测试用户数据"""
        return {
            "username": "test_user",
            "password": "test_pass123",
            "email": "test@example.com"
        }
    @staticmethod
    def get_invalid_data() -> Dict:
        """获取无效测试数据"""
        return {
            "username": "",  # 空用户名
            "password": "123"  # 密码太短
        }

实际项目测试案例

1 完整的用户管理API测试

import pytest
import requests
import json
import allure
class TestUserAPI:
    """用户管理API测试"""
    BASE_URL = "https://api.example.com/v1"
    @allure.feature("用户管理")
    @allure.story("创建用户")
    def test_create_user(self):
        """测试创建用户接口"""
        # 准备测试数据
        user_data = {
            "username": "testuser_" + str(int(time.time())),
            "email": "test@example.com",
            "password": "Test123!",
            "phone": "13800138000"
        }
        # 发送请求
        with allure.step("发送创建用户请求"):
            response = requests.post(
                f"{self.BASE_URL}/users",
                json=user_data,
                headers={"Content-Type": "application/json"}
            )
        # 验证响应
        with allure.step("验证响应状态码"):
            assert response.status_code == 201
        with allure.step("验证响应数据"):
            response_data = response.json()
            assert response_data["username"] == user_data["username"]
            assert "id" in response_data
        # 清理测试数据
        user_id = response_data["id"]
        requests.delete(f"{self.BASE_URL}/users/{user_id}")
    @pytest.mark.parametrize("invalid_data,expected_status", [
        ({"username": "", "email": "test@test.com"}, 400),
        ({"username": "test", "email": "invalid_email"}, 400),
        ({"username": "test", "email": "test@test.com", "password": "123"}, 400),
    ])
    def test_create_user_invalid_data(self, invalid_data, expected_status):
        """测试创建用户时的无效数据验证"""
        with allure.step(f"使用无效数据测试: {invalid_data}"):
            response = requests.post(
                f"{self.BASE_URL}/users",
                json=invalid_data
            )
        with allure.step("验证返回错误状态码"):
            assert response.status_code == expected_status
            assert "error" in response.json()
    @allure.feature("用户管理")
    @allure.story("登录认证")
    def test_user_login(self):
        """测试用户登录接口"""
        # 创建测试用户
        test_user = {
            "username": "logintest",
            "password": "Login123!",
            "email": "login@test.com"
        }
        create_response = requests.post(
            f"{self.BASE_URL}/users",
            json=test_user
        )
        user_id = create_response.json()["id"]
        # 测试登录
        with allure.step("使用正确密码登录"):
            login_response = requests.post(
                f"{self.BASE_URL}/auth/login",
                json={
                    "username": test_user["username"],
                    "password": test_user["password"]
                }
            )
        with allure.step("验证登录成功"):
            assert login_response.status_code == 200
            assert "token" in login_response.json()
        # 清理
        requests.delete(f"{self.BASE_URL}/users/{user_id}")
    @allure.feature("用户管理")
    @allure.story("查询用户")
    def test_get_user_with_auth(self):
        """测试带认证的用户查询"""
        # 获取认证token
        auth_token = self.get_auth_token()
        # 发送带认证的请求
        with allure.step("发送带token的查询请求"):
            response = requests.get(
                f"{self.BASE_URL}/users/profile",
                headers={"Authorization": f"Bearer {auth_token}"}
            )
        with allure.step("验证查询结果"):
            assert response.status_code == 200
            assert "username" in response.json()
    def get_auth_token(self):
        """获取认证token的辅助方法"""
        # 实现登录获取token的逻辑
        pass

运行测试

命令行运行

# 运行所有测试
pytest test_api.py -v
# 运行特定测试
pytest test_api.py::TestUserAPI::test_create_user -v
# 生成allure报告
pytest test_api.py --alluredir=./allure-results
allure serve ./allure-results
# 并行运行测试
pytest test_api.py -n 4

最佳实践建议

  1. 测试数据管理

    • 使用独立的测试数据文件
    • 测试前后清理数据
    • 避免硬编码测试数据
  2. 错误处理

    def safe_request(url, **kwargs):
        try:
            response = requests.get(url, timeout=10, **kwargs)
            response.raise_for_status()
            return response
        except requests.exceptions.RequestException as e:
            print(f"请求失败: {e}")
            return None
  3. 断言封装

    def assert_response(response, expected_status=200, expected_keys=None):
        assert response.status_code == expected_status, \
            f"期望状态码{expected_status},实际{response.status_code}"
        data = response.json()
        if expected_keys:
            for key in expected_keys:
                assert key in data, f"响应中缺少key: {key}"

这个完整的案例包含了从基础到高级的接口测试方法,你可以根据实际项目需求进行调整和扩展。

抱歉,评论功能暂时关闭!