引言

在当今软件开发过程中,接口自动化测试已成为保障软件质量的关键环节。关键字驱动设计提供了一种高效、灵活的解决方案,通过定义和封装关键字,可以实现对复杂接口的高效测试。本文将介绍如何基于关键字驱动设计和实现接口的自动化测试框架,涵盖多环境切换、多协议支持、请求方法封装、断言封装、性能优化与扩展以及日志记录与分析等方面。

关键字驱动设计

关键字驱动设计是一种测试自动化的方法,它通过定义和使用关键字来描述测试用例,使得测试用例更加简洁、易读和易维护。以下是一个简单的关键字驱动设计示例,展示了如何定义和使用关键字来实现接口自动化测试

示例代码

首先,定义一些基本的关键字:


# keywords.py

import requests

from hamcrest import assert_that, equal_to


BASE_URL = "https://dev.example.com/api"


def send_get_request(endpoint, params=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.get(url, params=params)

    return response


def send_post_request(endpoint, data=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.post(url, json=data)

    return response


def assert_status_code(response, expected_status_code):

    assert_that(response.status_code, equal_to(expected_status_code))


def assert_response_contains(response, key, expected_value):

    assert_that(response.json().get(key), equal_to(expected_value))

然后,在测试用例中使用这些关键字:


# test_cases.py

import pytest

from keywords import send_get_request, assert_status_code, assert_response_contains


def test_get_user_info():

    response = send_get_request("user/1")

    assert_status_code(response, 200)

    assert_response_contains(response, "name", "John Doe")
多环境切换

在实际测试过程中,我们通常需要在多个环境中执行测试。通过使用配置文件,可以方便地实现多环境切换。以下示例展示了如何通过配置文件实现多环境切换:

配置文件(config.yaml)

environments:

  dev:

    base_url: "https://dev.example.com/api"

  staging:

    base_url: "https://staging.example.com/api"

  prod:

    base_url: "https://prod.example.com/api"
示例代码

在关键字中读取配置文件中的环境配置:


# config.py

import yaml


def load_config(env):

    with open("config.yaml", "r") as file:

        config = yaml.safe_load(file)

    return config["environments"][env]


# keywords.py

import requests

from config import load_config

from hamcrest import assert_that, equal_to


ENV = "dev"

CONFIG = load_config(ENV)

BASE_URL = CONFIG["base_url"]


def send_get_request(endpoint, params=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.get(url, params=params)

    return response


def send_post_request(endpoint, data=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.post(url, json=data)

    return response


def assert_status_code(response, expected_status_code):

    assert_that(response.status_code, equal_to(expected_status_code))


def assert_response_contains(response, key, expected_value):

    assert_that(response.json().get(key), equal_to(expected_value))
多协议支持

为了支持多种协议的接口测试,我们可以在关键字中封装不同协议的请求方法。以下示例展示了如何支持 HTTP 和 WebSocket 协议的接口测试:

示例代码

封装不同协议的请求方法:


# keywords.py

import requests

import websocket

from config import load_config

from hamcrest import assert_that, equal_to


ENV = "dev"

CONFIG = load_config(ENV)

BASE_URL = CONFIG["base_url"]


def send_get_request(endpoint, params=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.get(url, params=params)

    return response


def send_post_request(endpoint, data=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.post(url, json=data)

    return response


def send_ws_message(endpoint, message):

    url = f"ws://{BASE_URL}/{endpoint}"

    ws = websocket.create_connection(url)

    ws.send(message)

    response = ws.recv()

    ws.close()

    return response


def assert_status_code(response, expected_status_code):

    assert_that(response.status_code, equal_to(expected_status_code))


def assert_response_contains(response, key, expected_value):

    assert_that(response.json().get(key), equal_to(expected_value))
请求方法封装

为了提高测试用例的可读性和可维护性,我们可以将常用的请求方法进行封装。以下示例展示了如何封装 GET 和 POST 请求方法:

示例代码

封装 GET 和 POST 请求方法:


# keywords.py

import requests

from config import load_config

from hamcrest import assert_that, equal_to


ENV = "dev"

CONFIG = load_config(ENV)

BASE_URL = CONFIG["base_url"]


def send_get_request(endpoint, params=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.get(url, params=params)

    return response


def send_post_request(endpoint, data=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.post(url, json=data)

    return response


def assert_status_code(response, expected_status_code):

    assert_that(response.status_code, equal_to(expected_status_code))


def assert_response_contains(response, key, expected_value):

    assert_that(response.json().get(key), equal_to(expected_value))

在测试用例中调用封装的请求方法:


# test_cases.py

import pytest

from keywords import send_get_request, assert_status_code, assert_response_contains


def test_get_user_info():

    response = send_get_request("user/1")

    assert_status_code(response, 200)

    assert_response_contains(response, "name", "John Doe")
断言封装

为了提高断言的可读性和可维护性,我们可以将常用的断言方法进行封装。以下示例展示了如何封装状态码断言和响应内容断言:

示例代码

封装状态码断言和响应内容断言:


# keywords.py

import requests

from config import load_config

from hamcrest import assert_that, equal_to


ENV = "dev"

CONFIG = load_config(ENV)

BASE_URL = CONFIG["base_url"]


def send_get_request(endpoint, params=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.get(url, params=params)

    return response


def send_post_request(endpoint, data=None):

    url = f"{BASE_URL}/{endpoint}"

    response = requests.post(url, json=data)

    return response


def assert_status_code(response, expected_status_code):

    assert_that(response.status_code, equal_to(expected_status_code))


def assert_response_contains(response, key, expected_value):

    assert_that(response.json().get(key), equal_to(expected_value))

在测试用例中调用封装的断言方法:


# test_cases.py

import pytest

from keywords import send_get_request, assert_status_code, assert_response_contains


def test_get_user_info():

    response = send_get_request("user/1")

    assert_status_code(response, 200)

    assert_response_contains(response, "name", "John Doe")
性能优化与扩展

为了提升测试框架的性能和扩展性,我们可以对代码进行优化和扩展。以下示例展示了如何进行性能优化和扩展:

示例代码

对请求方法进行优化:


# optimized_keywords.py

import requests

from requests.adapters import HTTPAdapter

from requests.packages.urllib3.util.retry import Retry

from config import load_config

from hamcrest import assert_that, equal_to


ENV = "dev"

CONFIG = load_config(ENV)

BASE_URL = CONFIG["base_url"]


session = requests.Session()

retry = Retry(total=3, backoff_factor=0.1)

adapter = HTTPAdapter(max_retries=retry)

session.mount("http://", adapter)

session.mount("https://", adapter)


def send_get_request(endpoint, params=None):

    url = f"{BASE_URL}/{endpoint}"

    response = session.get(url, params=params)

    return response


def send_post_request(endpoint, data=None):

    url = f"{BASE_URL}/{endpoint}"

    response = session.post(url, json=data)

    return response


def assert_status_code(response, expected_status_code):

    assert_that(response.status_code, equal_to(expected_status_code))


def assert_response_contains(response, key, expected_value):

    assert_that(response.json().get(key), equal_to(expected_value))

在测试用例中调用优化后的请求方法:


# test_cases.py

import pytest

from optimized_keywords import send_get_request, assert_status_code, assert_response_contains


def test_get_user_info():

    response = send_get_request("user/1")

    assert_status_code(response, 200)

    assert_response_contains(response, "name", "John Doe")
日志记录与分析(使用 Loguru 模块)

Loguru 是一个功能强大的日志记录库,它提供了简单易用的 API 和丰富的功能,使得日志记录变得

更加方便和高效。以下示例展示了如何使用 Loguru 记录和分析日志:

示例代码

配置 Loguru 并记录日志:


# log_config.py

from loguru import logger


logger.add("file_{time}.log", rotation="500 MB")


def log_request(request):

    logger.info(f"Request: {request.method} {request.url}")

    logger.info(f"Headers: {request.headers}")

    logger.info(f"Body: {request.body}")


def log_response(response):

    logger.info(f"Response: {response.status_code}")

    logger.info(f"Headers: {response.headers}")

    logger.info(f"Body: {response.text}")

在关键字中调用日志记录方法:


# keywords.py

import requests

from loguru import logger

from log_config import log_request, log_response

from config import load_config

from hamcrest import assert_that, equal_to


ENV = "dev"

CONFIG = load_config(ENV)

BASE_URL = CONFIG["base_url"]


session = requests.Session()


def send_get_request(endpoint, params=None):

    url = f"{BASE_URL}/{endpoint}"

    response = session.get(url, params=params)

    log_request(response.request)

    log_response(response)

    return response


def send_post_request(endpoint, data=None):

    url = f"{BASE_URL}/{endpoint}"

    response = session.post(url, json=data)

    log_request(response.request)

    log_response(response)

    return response


def assert_status_code(response, expected_status_code):

    assert_that(response.status_code, equal_to(expected_status_code))


def assert_response_contains(response, key, expected_value):

    assert_that(response.json().get(key), equal_to(expected_value))

在测试用例中调用包含日志记录的关键字:


# test_cases.py

import pytest

from keywords import send_get_request, assert_status_code, assert_response_contains


def test_get_user_info():

    response = send_get_request("user/1")

    assert_status_code(response, 200)

    assert_response_contains(response, "name", "John Doe")
结果报告模块优化(使用 Allure 报告框架)

Allure 是一个灵活的轻量级多语言测试报告工具,它不仅可以生成详细的测试报告,还可以集成多种测试框架。以下示例展示了如何使用 Allure 报告框架生成测试报告:

示例代码

安装 Allure 和 pytest-allure-adaptor 插件:

pip install allure-pytest

在测试用例中使用 Allure 标记:


# test_cases.py

import pytest

import allure

from keywords import send_get_request, assert_status_code, assert_response_contains


@allure.feature("User Info")

@allure.story("Get User Info")

@allure.severity(allure.severity_level.CRITICAL)

def test_get_user_info():

    response = send_get_request("user/1")

    with allure.step("Verify status code"):

        assert_status_code(response, 200)

    with allure.step("Verify response contains name"):

        assert_response_contains(response, "name", "John Doe")

生成 Allure 报告:


pytest --alluredir=allure-results

allure serve allure-results

结尾

本文详细介绍了基于关键字驱动设计和实现接口的自动化测试框架的方法,涵盖多环境切换、多协议支持、请求方法封装、断言封装、性能优化与扩展以及日志记录与分析等方面。通过这些技术和方法,可以有效提升接口自动化测试的效率和质量,为软件开发过程中的质量保障提供坚实的基础。希望本文能为读者在实际工作中提供有价值的参考和帮助。

最后作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些软件测试的学习资源,希望能给你前进的路上带来帮助。

视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐