#文档 #测试 #API #验证 #测试工具 #阅读 #命令行工具

bin+lib doc-assert

通过验证 markdown API 文档与实际端点,确保文档的准确性

2 个版本

0.1.1 2024年4月29日
0.1.0 2024年2月27日

#739 in 网络编程

Apache-2.0

365KB
2K SLoC

DocAssert crates.io

DocAssert 是一个文档测试工具,提供了一种全新的方法。将您的文档编写成您想向用户讲述的故事,并对其 API 进行测试。

它是如何工作的?

DocAssert 读取指定的 README.md 文件,并扫描其中的代码块,查找包含请求和响应描述的代码块。然后,它将这些请求发送到您的 API,并验证响应是否与文档中指定的响应匹配。

使用测试 API

首先,您需要在 README.md 文件中定义您的文档。一个请求可以看起来像这样

```docassertrequest
POST /blog
Content-Type: application/json
{
    "title": "My First Blog",
    "body": "Blog content"
}
```

上述定义指示 DocAssert 向 /blog 发送一个 POST 请求,并带有 Content-Type: application/json 标头和代码块中指定的正文。请注意代码块开头的 docassertrequest。您的文档可以包含任何数量的文本、代码块和其他元素,只需在 DocAssert 代码块之间即可。只有带有 docassertrequestdocassertresponse 的代码块将被解析。

预期的响应可以定义如下

```docassertresponse
HTTP 201
Content-Type: application/json
{
    "id": "d8f7d454-c436-4e0f-9613-1d69036ad421",
    "title": "My First Blog",
    "body": "Blog content"
}
```

[ignore]: # ($.id)
[ignore]: # ($.date_upd)
[ignore]: # ($.comments)

此配置告诉 DocAssert 期望一个状态码为 201 并带有 Content-Type: application/json 标头的响应。将检查响应正文,但您可以指定要忽略的 JSONPaths。如果响应包含随机值(如 IDs 或时间戳),则此功能非常有用。请记住,在响应代码块后放置 [ignore]: # (your_json_path)。您可以包括所需数量的这些。

准备您的文档后,您可以从测试中运行 DocAssert,如下所示

use doc_assert::DocAssert;

#[cfg(test)]
mod tests {
    #[tokio::test]
    async fn test_docs() {
        let result = DocAssert::new()
            .with_url("https://127.0.0.1:8080")
            .with_doc_path("README.md")
            .assert()
            .await;
        match result {
            Ok(report) => {
                // handle report
            }
            Err(err) => {
                // handle error
            }
        }
    }
}

如果在 Err 的情况下,结果将包含一个错误列表,其中包含关于出错原因的详细信息。

变量

在某些情况下,我们可能需要设置一些将在请求之间共享的值。例如测试认证令牌。

在运行测试之前,我们可以在API中定义变量

use doc_assert::DocAssert;

#[cfg(test)]
mod tests {
    #[tokio::test]
    async fn test_docs() {
        let result = DocAssert::new()
            .with_url("https://127.0.0.1:8080")
            .with_doc_path("README.md")
            .with_variable("auth_token", "some_token")
            .assert()
            .await;
        match result {
            Ok(report) => {
                // handle report
            }
            Err(err) => {
                // handle error
            }
        }
    }
}

变量也可以在文档中动态定义。首先我们有一个请求

```docassertrequest
POST /blog
Content-Type: application/json
{
    "title": "My First Blog",
    "body": "Blog content"
}
```

这将导致一个响应

```docassertresponse
HTTP 201
Content-Type: application/json
{
    "id": "d8f7d454-c436-4e0f-9613-1d69036ad421",
    "title": "My First Blog",
    "body": "Blog content"
}
```

[ignore]: # ($.id)
[ignore]: # ($.date_upd)
[ignore]: # ($.comments)
[let id]: # ($.id)

在上面的例子中,一些字段被忽略,但我们还定义了一个变量 id,它将在下一个请求中使用。注意,变量也可以在忽略的字段上定义。

现在我们可以在下一个请求中使用这个变量

```docassertrequest
GET /blog/`id`
```

这将导致一个响应

```docassertresponse
HTTP 200
Content-Type: application/json
{
    "id": `id`,
    "title": "My First Blog",
    "body": "Blog content"
}
```
[ignore]: # ($.date_upd)
[ignore]: # ($.comments)

注意,id 也被用于响应,并在断言期间进行评估。

使用命令行工具

您可以将DocAssert集成到测试中,也可以将其用作独立的命令行工具

doc-assert --url https://127.0.0.1:8081 --variables '{"auth_token": "some_token"}' README.md

重试策略

在某些情况下,如果请求失败,您可能希望重试请求。您可以在文档中定义重试策略

```docassertrequest
GET /blog/`id`
```
```docassertresponse
HTTP 200
Content-Type: application/json
```
[retry]: # (3,4500)

重试策略中的第一个数字是重试次数,第二个数字是重试之间的延迟(以毫秒为单位)。

安装

要使用DocAssert作为CLI工具,您可以使用cargo进行安装

cargo install doc-assert --features="binary"

为了直接从源代码构建它,请运行

cargo build --features="binary"

依赖项

~8-21MB
~320K SLoC