使用Mocha/Chai时如何避免多测试用例中重复断言?
嘿,针对你这20个包含重复断言的测试用例,我给你几个实用的重构思路,帮你彻底干掉重复代码,以后维护起来也省心!
方案1:提取重复断言为独立函数
这是最直接的做法,把end回调里的所有断言逻辑抽成一个单独的函数,所有测试用例共享这个函数即可。还能顺便统一处理错误,避免每个测试都漏写错误处理逻辑。
// 把重复的断言逻辑抽成可复用的函数 function validateApiResponse(err, res, done) { // 统一处理请求错误,避免每个测试都重复写 if (err) return done(err); // 所有共享的断言都放在这里 expect(res.statusCode).equals(200); expect(res.body.refId.length).equals(36); // 这里建议用断言库的equals方法,比直接==的错误信息更清晰 expect(res.body.this1.length).equals(1); expect(res.body.that2.length).equals(2); expect(res.body.that3.length).equals(3); done(); } // 改造后的测试用例变得异常简洁 describe('my test 1', function() { it('responds with expected email id reference', function(done) { request .post(apiPath) .send(input) .end(validateApiResponse); // 直接传入复用函数,参数会自动匹配 }); });
方案2:参数化测试,批量生成测试用例
如果你的20个测试用例只是输入数据不同,断言逻辑完全一致,那可以把所有测试的输入和名称整理成数组,通过循环批量生成测试用例。这样不仅干掉了断言重复,连重复的describe/it结构也能省掉。
// 把20个测试的输入数据和测试名称整理成数组 const testCases = [ { name: 'my test 1', input: input1 }, { name: 'my test 2', input: input2 }, { name: 'my test 3', input: input3 }, // ... 剩下的17个测试用例依次添加 ]; // 配合方案1的断言函数,批量生成测试 function validateApiResponse(err, res, done) { if (err) return done(err); expect(res.statusCode).equals(200); expect(res.body.refId.length).equals(36); expect(res.body.this1.length).equals(1); expect(res.body.that2.length).equals(2); expect(res.body.that3.length).equals(3); done(); } describe('API Response Validation Suite', function() { testCases.forEach(test => { it(`responds with expected email id reference for ${test.name}`, function(done) { request .post(apiPath) .send(test.input) .end(validateApiResponse); }); }); });
方案3:用Promise+Async/Await简化回调,进一步优化可读性
如果你的测试框架支持Async/Await(比如Mocha v3.0+),可以把请求逻辑封装成Promise,摆脱回调地狱的同时让测试代码更清爽。
// 封装请求为Promise函数 function makeApiRequest(input) { return new Promise((resolve, reject) => { request .post(apiPath) .send(input) .end((err, res) => { err ? reject(err) : resolve(res); }); }); } // 断言函数改成同步形式,更直观 function validateApiResponse(res) { expect(res.statusCode).equals(200); expect(res.body.refId.length).equals(36); expect(res.body.this1.length).equals(1); expect(res.body.that2.length).equals(2); expect(res.body.that3.length).equals(3); } // 测试用例直接用async函数,不用再写done回调 describe('my test 1', function() { it('responds with expected email id reference', async function() { const res = await makeApiRequest(input); validateApiResponse(res); }); });
小提醒
你原来代码里的expect(res.body.refId.length == 36)这种写法,建议换成断言库的equals方法(比如Chai的expect(...).equals(...)),这样当断言失败时,会输出更清晰的错误信息,方便排查问题。
内容的提问来源于stack exchange,提问作者RajKon
相关产品推荐
相关产品推荐

