API Testing | API 接口测试#

1. 测试应该放在哪里#

Rust 提供了以下三种选择:

测试类型

描述

代码访问级别

嵌入式测试模块

测试单个函数或模块的行为,通常在同一文件中。

私有

集成测试

测试多个模块或整个应用程序的交互,通常在 tests 目录中。

公有

文档测试

在文档注释中编写示例代码,并验证其正确性。

公有

2. 沿用书中的测试#

tests/health_check.rs 中,书中提供了一个 spawn_app 函数用于启动一个测试服务器,并返回其地址。

1fn spawn_app() -> String {
2    let listener = TcpListener::bind("127.0.0.1:0").expect("Can't spawn tcp listener");
3    let port = listener.local_addr().unwrap().port();
4    let server = zero2prod::run(listener).expect("Can't start zero2prod");
5
6    let _ = tokio::spawn(server);
7
8    format!("http://127.0.0.1:{}", port)
9}

随后,创建一个具体的测试案例

 1#[tokio::test]
 2async fn health_check_works() {
 3    let addr = spawn_app();
 4
 5    let client = reqwest::Client::new();
 6
 7    let response = client
 8        .get(format!("{}/health_check", &addr))
 9        .send()
10        .await
11        .expect("Can't send request");
12
13    assert!(response.status().is_success());
14    assert_eq!(Some(0), response.content_length());
15}

这些测试的大概步骤是:

  1. 使用 spawn_app 函数启动一个测试服务器。

  2. 使用 reqwest 创建一个 HTTP 客户端。

  3. 发送请求并验证响应。

但是弊端也很明显,需要每次执行一个测试,需要创建服务器实列和客户端实列,如果测试数量较多,可能会导致测试执行时间过长。

3. 改进测试#

Flask 提供了用于测试应用程序的工具,可以配合 pytest 使用。下面的是一个具体的示例:

 1import pytest
 2from flask import Flask
 3
 4app = Flask(__name__)
 5
 6@app.route('/health_check')
 7def health_check():
 8    return '', 200
 9
10@pytest.fixture
11def client():
12    with app.test_client() as client:
13        yield client
14
15def test_health_check(client):
16    response = client.get('/health_check')
17    assert response.status_code == 200
18    assert response.data == b''

不确定是否是版本原因还是其他, 原书作者并没有使用到 actix-web 框架本身提供的测试功能。