以下为 HarmonyOS 5基于OpenAPI文档自动生成Mock测试的完整方案,包含接口解析、Mock服务生成和自动化验证的代码实现:
1. 整体架构
2. OpenAPI解析器
2.1 接口模型提取
// openapi-parser.ets
class OpenAPIParser {
static async parse(specPath: string): Promise<ApiModel[]> {
const spec = await YamlLoader.load(specPath);
return Object.entries(spec.paths).map(([path, methods]) => {
return Object.entries(methods).map(([method, definition]) => ({
path,
method: method.toUpperCase(),
parameters: definition.parameters || [],
responses: definition.responses
}));
}).flat();
}
}
// 示例:解析Swagger文档
const apis = await OpenAPIParser.parse('api/user-service.yaml');
2.2 响应模型生成
// response-generator.ets
class ResponseGenerator {
static generateExample(responseDef: ResponseDef): any {
if (responseDef.content?.['application/json']?.schema) {
return this.generateFromSchema(
responseDef.content['application/json'].schema
);
}
return { status: 'success' };
}
private static generateFromSchema(schema: SchemaObject): any {
if (schema.example) return schema.example;
switch (schema.type) {
case 'object':
return Object.fromEntries(
Object.entries(schema.properties || {}).map(([key, prop]) =>
[key, this.generateFromSchema(prop)]
)
);
case 'array':
return [this.generateFromSchema(schema.items)];
default:
return this.getMockValue(schema.type);
}
}
}
3. Mock服务生成
3.1 动态路由创建
// mock-server.ets
class MockServer {
private static routes: MockRoute[] = [];
static createFromOpenAPI(apis: ApiModel[]) {
apis.forEach(api => {
this.routes.push({
path: api.path,
method: api.method,
handler: (req) => this.handleRequest(api, req)
});
});
HttpServer.registerRoutes(this.routes);
}
private static handleRequest(api: ApiModel, req: Request): Response {
const statusCode = req.query.status || '200';
const responseDef = api.responses[statusCode];
return {
status: parseInt(statusCode),
body: ResponseGenerator.generateExample(responseDef)
};
}
}
3.2 异常场景模拟
// failure-mock.ets
class FailureInjector {
static enableForRoute(path: string) {
const route = MockServer.routes.find(r => r.path === path);
if (route) {
const originalHandler = route.handler;
route.handler = (req) => {
if (req.headers['x-failure-rate'] > Math.random()) {
return { status: 503, body: { error: '服务不可用' } };
}
return originalHandler(req);
};
}
}
}
4. 测试用例生成
4.1 自动化测试生成
// test-generator.ets
class TestCaseGenerator {
static generate(api: ApiModel): TestCase[] {
return Object.entries(api.responses).map(([status, responseDef]) => ({
name: `${api.method} ${api.path} -> ${status}`,
request: {
method: api.method,
path: api.path,
params: this.generateParams(api.parameters)
},
expect: {
status: parseInt(status),
schema: responseDef.content?.['application/json']?.schema
}
}));
}
private static generateParams(params: ParameterObject[]): any {
return params.reduce((acc, param) => {
acc[param.name] = this.generateParamValue(param);
return acc;
}, {});
}
}
4.2 参数生成策略
// param-generator.ets
class ParamGenerator {
static generate(param: ParameterObject): any {
switch (param.schema?.type) {
case 'string':
return param.schema.enum?.[0] ||
`mock_${param.name}_${Math.random().toString(36).slice(2)}`;
case 'number':
return param.schema.minimum || 0;
case 'boolean':
return true;
default:
return null;
}
}
}
5. 自动化验证
5.1 响应验证器
// response-validator.ets
class ResponseValidator {
static validate(res: Response, expected: ExpectedResponse): ValidationResult {
const schema = expected.schema;
if (!schema) return { valid: true };
return {
valid: this.validateSchema(res.body, schema),
errors: this.findSchemaErrors(res.body, schema)
};
}
private static validateSchema(data: any, schema: SchemaObject): boolean {
// 使用JSON Schema验证库实现
return JsonSchema.validate(data, schema);
}
}
5.2 测试执行引擎
// test-engine.ets
class TestEngine {
static async run(test: TestCase): Promise<TestResult> {
const res = await HttpClient.request({
method: test.request.method,
url: test.request.path,
params: test.request.params
});
const validation = ResponseValidator.validate(res, test.expect);
return {
name: test.name,
passed: res.status === test.expect.status && validation.valid,
response: res,
errors: validation.errors
};
}
}
6. 完整工作流示例
6.1 从OpenAPI生成测试
// generate-tests.ets
async function generateAndRunTests() {
// 1. 解析OpenAPI文档
const apis = await OpenAPIParser.parse('api-spec.yaml');
// 2. 生成Mock服务
MockServer.createFromOpenAPI(apis);
// 3. 创建测试用例
const testCases = apis.flatMap(api =>
TestCaseGenerator.generate(api)
);
// 4. 执行自动化测试
const results = await Promise.all(
testCases.map(tc => TestEngine.run(tc))
);
// 5. 生成报告
return TestReport.generate(results);
}
6.2 带异常注入的测试
// failure-test.ets
describe('异常场景测试', () => {
beforeAll(() => {
FailureInjector.enableForRoute('/api/users');
});
it('应处理服务不可用错误', async () => {
const res = await HttpClient.get('/api/users', {
headers: { 'x-failure-rate': 1 }
});
expect(res.status).toBe(503);
expect(res.body.error).toBe('服务不可用');
});
});
7. 高级功能扩展
7.1 流量录制回放
// traffic-recorder.ets
class TrafficRecorder {
static async recordAndGenerate(apiUrl: string) {
const traffic = await ProxyServer.captureTraffic(apiUrl);
return traffic.map(req => ({
name: `${req.method} ${req.path}`,
request: {
method: req.method,
path: req.path,
params: req.query
},
expect: {
status: req.response.status,
body: req.response.body
}
}));
}
}
7.2 智能参数变异
// param-mutator.ets
class ParamMutator {
static generateInvalidParams(param: ParameterObject): any[] {
const valid = ParamGenerator.generate(param);
return [
null,
typeof valid === 'string' ? 123 : 'invalid_string',
param.required ? undefined : valid
];
}
}
8. 测试报告生成
8.1 可视化报告
// report-visualizer.ets
@Component
struct TestReport {
@Prop results: TestResult[];
build() {
Column() {
Text('API测试报告').fontSize(24)
PieChart({
data: [
{ label: '通过', value: this.results.filter(r => r.passed).length },
{ label: '失败', value: this.results.filter(r => !r.passed).length }
]
})
ForEach(this.results.filter(r => !r.passed), result => (
Text(`${result.name}: ${result.errors?.join(',')}`)
.fontColor('#ff0000')
))
}
}
}
8.2 CI集成配置
# .github/workflows/api-test.yml
jobs:
api-mock-test:
runs-on: harmonyos
steps:
- uses: harmonyos/openapi-test-action@v1
with:
spec: ./api-spec.yaml
mock-port: 8080
- name: Run Tests
run: |
ohpm install @test/mock-generator
node generate-tests.ets
9. 关键生成规则
| 字段类型 | 生成策略 | 验证方法 |
|---|---|---|
| string | 枚举值优先/随机字符串 | 正则匹配/长度检查 |
| number | 最小值/典型值 | 范围验证 |
| boolean | true/false轮换 | 类型检查 |
| object | 递归生成所有属性 | 深度对比 |
| array | 生成1-3个元素 | 长度验证+元素类型检查 |
10. 完整示例输出
10.1 生成的Mock测试
// generated/user-api.test.ets
describe('用户服务API测试', () => {
beforeAll(() => MockServer.start(3000));
it('GET /users/1 应返回用户详情', async () => {
const res = await HttpClient.get('/users/1');
expect(res.status).toBe(200);
expect(res.body).toMatchSchema({
type: 'object',
properties: {
id: { type: 'number' },
name: { type: 'string' }
},
required: ['id', 'name']
});
});
it('POST /users 应创建新用户', async () => {
const res = await HttpClient.post('/users', {
name: 'test_user',
age: 25
});
expect(res.status).toBe(201);
expect(res.body.id).toBeDefined();
});
});
10.2 Mock服务输出
// GET /users/1 响应示例
{
"id": 1,
"name": "张三",
"email": "zhangsan@example.com"
}
通过本方案可实现:
- 100% OpenAPI接口自动覆盖
- 零代码 生成完整Mock服务
- 智能 异常场景注入
- 可集成 到CI/CD流水线