杰瑞科技汇

Python如何测试Webservice?

概览

  1. 测试 RESTful WebService:这是目前最主流的方式,通常与 JSON 数据交互,使用 HTTP 方法(GET, POST, PUT, DELETE)。
  2. 测试 SOAP WebService:这是一种较老但仍在企业中广泛使用的标准,通常基于 XML,使用 WSDL(Web Services Description Language)文件定义接口。

测试 RESTful WebService

测试 RESTful API 的核心是发送 HTTP 请求并验证响应,Python 有几个非常流行的库可以做到这一点,requests 是最简单、最常用的。

Python如何测试Webservice?-图1
(图片来源网络,侵删)

推荐库:requests

requests 库极大地简化了 Python 中的 HTTP 请求。

安装

pip install requests

示例:测试一个公共 REST API (JSONPlaceholder)

我们将测试一个免费的在线 REST API 服务,用于练习。

API 端点GET https://jsonplaceholder.typicode.com/posts/1

预期行为:获取 ID 为 1 的文章。

Python如何测试Webservice?-图2
(图片来源网络,侵删)

测试脚本 (test_rest_api.py)

import requests
import pytest # 推荐使用 pytest 进行更结构化的测试
# API 的基础 URL
BASE_URL = "https://jsonplaceholder.typicode.com"
def test_get_single_post():
    """
    测试获取单个文章的接口
    """
    post_id = 1
    url = f"{BASE_URL}/posts/{post_id}"
    # 1. 发送 GET 请求
    response = requests.get(url)
    # 2. 验证响应状态码是否为 200 (OK)
    assert response.status_code == 200, f"Expected status code 200, but got {response.status_code}"
    # 3. 验证响应内容是 JSON 格式
    # requests 会自动将 JSON 响应解析为 Python 字典
    data = response.json()
    assert isinstance(data, dict), "Response is not a valid JSON object (Python dict)"
    # 4. 验证响应数据中的关键字段
    assert "userId" in data, "Response JSON missing 'userId'"
    assert "id" in data, "Response JSON missing 'id'"
    assert "title" in data, "Response JSON missing 'title'"
    assert "body" in data, "Response JSON missing 'body'"
    # 5. 验证返回的 ID 是否正确
    assert data["id"] == post_id, f"Expected post ID {post_id}, but got {data['id']}"
    print("✅ Test 'test_get_single_post' passed!")
def test_create_post():
    """
    测试创建新文章的接口 (POST 请求)
    """
    url = f"{BASE_URL}/posts"
    payload = {
        "title": "foo",
        "body": "bar",
        "userId": 1
    }
    # 发送 POST 请求,并传递 JSON 数据
    response = requests.post(url, json=payload)
    # 验证响应状态码是否为 201 (Created)
    assert response.status_code == 201, f"Expected status code 201, but got {response.status_code}"
    data = response.json()
    # 验证返回的数据中包含了我们发送的数据
    assert data["title"] == payload["title"]
    assert data["body"] == payload["body"]
    assert data["userId"] == payload["userId"]
    # 验证服务器返回了新的 ID
    assert "id" in data, "New post should have an 'id' field"
    print("✅ Test 'test_create_post' passed!")
if __name__ == "__main__":
    # 可以直接运行脚本进行测试
    test_get_single_post()
    test_create_post()
    print("\n🎉 All tests passed!")

如何运行测试

  1. 直接运行

    python test_rest_api.py
  2. 使用 pytest (推荐)pytest 是一个功能强大的测试框架,可以自动发现和运行测试,并提供更详细的报告。

    # 首先安装 pytest
    pip install pytest
    # 然后运行 pytest
    pytest

    pytest 会自动查找所有以 test_ 开头的函数并执行它们。


测试 SOAP WebService

SOAP (Simple Object Access Protocol) 是一个协议,它使用 XML 进行消息格式,测试 SOAP 服务通常涉及:

Python如何测试Webservice?-图3
(图片来源网络,侵删)
  1. 根据 WSDL 文件生成客户端代码(可选,但推荐)。
  2. 构造符合 SOAP 规范的 XML 请求体。
  3. 将请求发送到服务的端点 URL。
  4. 解析返回的 SOAP 响应 XML 并进行验证。

推荐库:zeep

zeep 是一个强大的 Python SOAP 客户端库,它可以自动解析 WSDL 文件,并为你生成 Python 方法来调用 Web Service,极大地简化了 SOAP 交互。

安装

pip install zeep

示例:测试一个公共的 SOAP WebService

我们将使用 wsdlvalidator.com 提供一个公共的 WSDL 文件进行测试。

WSDL 地址http://www.dneonline.com/calculator.asmx?wsdl

服务功能:一个简单的加法计算器。

测试脚本 (test_soap_api.py)

from zeep import Client
import pytest
# WSDL 文件的地址
WSDL_URL = "http://www.dneonline.com/calculator.asmx?wsdl"
def test_add_soap_service():
    """
    测试 SOAP WebService 的加法功能
    """
    # 1. 创建 SOAP 客户端,zeep 会自动加载 WSDL
    client = Client(wsdl=WSDL_URL)
    # 2. 准备测试数据
    num1 = 5
    num2 = 10
    expected_sum = 15
    print(f"Calling SOAP Add service with {num1} and {num2}...")
    # 3. 调用 WSDL 中定义的 'Add' 方法
    # zeep 会自动将 Python 参数转换为 SOAP XML
    response = client.service.Add(intA=num1, intB=num2)
    # 4. 验证响应
    # 响应通常是 zeep.objects 对象,可以直接访问其属性
    assert response is not None, "SOAP service returned None"
    # 假设 WSDL 定义的响应元素名为 'AddResult'
    assert response == expected_sum, f"Expected sum {expected_sum}, but got {response}"
    print(f"✅ SOAP Add test passed! Result: {response}")
def test_subtract_soap_service():
    """
    测试 SOAP WebService 的减法功能
    """
    client = Client(wsdl=WSDL_URL)
    num1 = 20
    num2 = 8
    expected_difference = 12
    print(f"Calling SOAP Subtract service with {num1} and {num2}...")
    response = client.service.Subtract(intA=num1, intB=num2)
    assert response is not None
    assert response == expected_difference
    print(f"✅ SOAP Subtract test passed! Result: {response}")
if __name__ == "__main__":
    test_add_soap_service()
    test_subtract_soap_service()
    print("\n🎉 All SOAP tests passed!")

如何运行测试

与 REST 测试类似,你可以直接运行或使用 pytest

# 直接运行
python test_soap_api.py
# 使用 pytest 运行
pytest

进阶主题与最佳实践

  1. 使用测试框架 (pytest)

    • Fixturepytest 的 fixture 非常有用,可以用来管理测试资源,比如创建和销毁客户端会话、数据库连接等。
    • 参数化 (@pytest.mark.parametrize):当你想用多组数据测试同一个函数时,这非常有用。
    import pytest
    @pytest.mark.parametrize("a, b, expected", [
        (1, 2, 3),
        (10, 20, 30),
        (-1, 5, 4),
        (0, 0, 0)
    ])
    def test_add_with_params(client, a, b, expected): # 假设 client 是一个 fixture
        response = client.service.Add(intA=a, intB=b)
        assert response == expected
  2. 测试数据管理

    避免在代码中硬编码测试数据,可以将数据存储在单独的文件中,如 JSON、YAML 或 CSV 文件。

  3. 环境管理

    你的测试脚本应该能在不同环境(如开发、测试、生产)下运行,可以通过环境变量或配置文件来管理不同环境的 URL 和凭据。

  4. Mocking (模拟)

    • 在单元测试中,你不应该依赖真实的、外部的 Web 服务,因为这会使测试变慢、不稳定且不可靠,你应该使用 unittest.mock 库来模拟(mock)HTTP 请求和 SOAP 客户端,让它们返回预设的响应。
    from unittest.mock import patch
    import requests
    def test_get_post_with_mock():
        # 定义模拟的响应
        mock_response_data = {'id': 1, 'title': 'Mock Title'}
        # 使用 patch 装饰器来模拟 requests.get
        with patch('requests.get') as mock_get:
            # 配置模拟对象
            mock_get.return_value.status_code = 200
            mock_get.return_value.json.return_value = mock_response_data
            # 现在调用你的函数,它会使用模拟的响应
            response = requests.get("http://fake-api-url.com/posts/1")
            assert response.status_code == 200
            assert response.json()['title'] == 'Mock Title'
            # 验证 requests.get 是否被正确调用
            mock_get.assert_called_once_with("http://fake-api-url.com/posts/1")
特性 RESTful WebService (使用 requests) SOAP WebService (使用 zeep)
数据格式 JSON (主流) XML
协议 HTTP HTTP/HTTPS, SMTP 等
核心库 requests zeep
测试重点 HTTP 状态码、JSON 数据结构、业务逻辑 WSDL 解析、SOAP 信封结构、业务逻辑
易用性 非常简单直观 相对复杂,依赖 WSDL
适用场景 现代Web应用、移动端API 企业级应用、金融、电信等传统领域

对于新的项目,RESTful API 是首选,如果你的项目需要与遗留的 SOAP 服务集成,zeep 是一个非常可靠的工具,结合 pytestmock,你可以构建一个健壮、可维护的自动化测试体系。

分享:
扫描分享到社交APP
上一篇
下一篇