我在尝试使用 Specmatic 测试 API 合约时遇到问题。问题是,当我启动 Specmatic 的测试模式时,它不使用我为测试提供的不记名令牌。我尝试通过文件(bearer.txt)和环境变量(BEARER)传递不记名令牌。我在 MacBook Pro M2 上使用 Macos Sonoma 14.4.1。
我创建了一个 PoC 项目来重现它。可以在这个 GitHub 公共存储库中看到:https://github.com/vladimir-bataller-NTT/specmatic-mini-poc
这是我的 package.json 配置,其中包含我使用的两个脚本,start(启动本地服务器)和 test(启动 Specmatic 测试):
{
"name": "specmatic-mini-poc",
"version": "1.0.0",
"author": "Vladimir Bataller",
"description": "Minimal Express application for testing Rest application with Specmatic",
"main": "app.js",
"type": "module",
"scripts": {
"start": "node app",
"test": "specmatic test --testBaseURL=http://localhost:3000"
},
"dependencies": {
"express": "4.19.2"
},
"devDependencies": {
"specmatic": "^1.3.9"
}
}
小米迷你快递应用程序(app.js)如下:
import express from "express";
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.get("/pets/:id", (req, res) => {
const token = req.get("Authorization");
console.log('----->', token);
if (!token) {
res.status(403);
res.send('Unauthorized');
return;
}
res.json({
id: parseInt(req.params.id),
name: 'Scooby',
type: 'Golden Retriever',
status: 'Adopted'
});
});
app.listen(3000, () => console.log('EXPRESS STARTED ON PORT 3000'));
该服务器实现以下合约,在contract.yaml文件中提供:
openapi: 3.0.1
info:
title: Contract for the petstore service
version: '1'
paths:
/pets/{petid}:
get:
summary: Should be able to get a pet by petId
parameters:
- name: petid
in: path
required: true
schema:
type: number
examples:
SCOOBY_200_OK:
value: 1
responses:
'200':
description: Should be able to get a pet by petId
content:
application/json:
schema:
required:
- id
- name
- status
- type
properties:
id:
type: number
name:
type: string
type:
type: string
status:
type: string
examples:
SCOOBY_200_OK:
value:
id: 1
name: Scooby
type: Golden Retriever
status: Adopted
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
Specmatic 测试的配置由以下 specmatic.json 文件提供:
{
"auth": {
"bearer-file": "bearer.txt"
},
"sources": [
{
"provider": "filesystem",
"test": [
"contract.yaml"
]
}
]
}
可以看出,我在文件“bearer.txt”中提供了不记名令牌。该文件仅包含纯文本形式的令牌,如下所示:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
问题是,当我运行测试时,npm run test,Specmatic 提供的 Bearer 令牌不是我在 bearer.txt 或环境变量中拥有的令牌。尽管如此,它还是提供了一些东西 授权:承载JKCKT 从下面的控制台输出中可以看出。
specmatic-mini-poc % npm run test
> [email protected] test
> specmatic test --testBaseURL=http://localhost:3000
Loading config file ./specmatic.json
API Specification Summary: ./contract.yaml
OpenAPI Version: 3.0.1
API Paths: 1, API Operations: 1
Schema components: null, Security Schemes: [http]
Endpoints API not found, cannot calculate actual coverage
--------------------
Request to http://localhost:3000 at 2024-4-10 0:28:57.961
GET /pets/1
Authorization: Bearer JKCKT
Accept-Charset: UTF-8
Accept: */*
Content-Type: NOT SENT
Response at 2024-4-10 0:28:57.963
200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 69
ETag: W/"45-I28b2GsRHCZOFOGiWEH0LQIrPmk"
Date: Wed, 10 Apr 2024 10:28:57 GMT
Connection: keep-alive
Keep-Alive: timeout=5
{
"id": 1,
"name": "Scooby",
"type": "Golden Retriever",
"status": "Adopted"
}
Scenario: GET /pets/(petid:number) -> 200 | EX:SCOOBY_200_OK has SUCCEEDED
Could not load report configuration, coverage will be calculated but no coverage threshold will be enforced
|----------------------------------------------------------------------|
| API COVERAGE SUMMARY |
|----------------------------------------------------------------------|
| coverage | path | method | response | # exercised | remarks |
|----------|---------------|--------|----------|-------------|---------|
| 100% | /pets/{petid} | GET | 200 | 1 | covered |
|----------------------------------------------------------------------|
| 100% API Coverage reported from 1 path |
|----------------------------------------------------------------------|
Saving Open API Coverage Report json to ./build/reports/specmatic ...
Tests run: 1, Successes: 1, Failures: 0, Errors: 0
有谁知道这是一个 Specmatic 错误还是我缺少一些配置?
我自己回答。
我在 Specmatic 的 GitHub 存储库中看到了这个请求帮助:
https://github.com/znsio/specmatic/discussions/913
这表明现在只有环境变量有效。因此,暂时忘记带有令牌的文本文件。
在这个问题中,我意识到环境变量的名称必须与我们在openapi合约中分配给安全方案的名称相同。
所以在我的示例中,环境变量的名称应该是bearerAuth。请注意区分大小写。
因此,作为修复,我在 package.json 中添加了一个名为 test:macos
的脚本条目“测试:macos”:“导出 bearerAuth=
cat bearer.txt
&& 规范测试 --testBaseURL=http://localhost:3000”
我已将此修复程序推送到 PoC 的存储库中: