每个文件强制执行一个描述
Enforce one describe per file
故事:
我们有一个相当大的测试代码库,其中包含 Protractor+Jasmine 测试。
我们目前遇到的一个问题是 一些 test/spec 文件包含多个 describe 这不时会引起麻烦 - 例如,当我们使用 fdescribe
/fit
逐个(或分批)调试测试;有时我们没有注意到底部的同一文件中还有其他 decribe
,最终导致部分测试被无意中跳过。
换句话说,这是一种 "one assertion per test" 类型规则的变体,有助于保持测试代码库的清洁和 "flat".
问题:
有没有办法禁止每个文件超过一个 describe
?我目前正在考虑通过静态代码分析和 ESLint
来解决它,但我也对其他解决方案持开放态度。
样本:
违规示例:
describe("Test 1", function () {
it("should do something", function () {
expect(true).toBe(true);
});
});
describe("Test 2", function () {
it("should do something else", function () {
expect(false).toBe(false);
});
});
如果有单个 describe
块,但它包含嵌套的 describe
,则不应将其报告为违规。换句话说,可以拥有:
describe("Test 1", function () {
it("should do something", function () {
expect(true).toBe(true);
});
describe("Test 2", function () {
it("should do something else", function () {
expect(false).toBe(false);
});
});
});
棘手的部分是标记仅描述未嵌套的块,或 "top-level" 描述。幸运的是,这完全可以通过 ESLint 实现!
ESLint "visits" 遍历 JavaScript 代码的抽象语法树(简称 AST)时节点两次: down 一次树,另一个正在备份。
首先遍历树的深度,因此如果您的代码中有 3 个 describe
块,如下所示:
describe("Test 1", function () {
it("should do something", function () {
expect(true).toBe(true);
});
describe("Test 2", function () {
it("should do something else", function () {
expect(false).toBe(false);
});
});
});
describe("Test 3", function () {
it("should do something", function () {
expect(true).toBe(true);
});
});
将按以下顺序访问节点:
enter "Test 1"
-> enter "Test 2"
-> exit "Test 2"
-> exit "Test 1"
-> enter "Test 3"
-> exit "Test 3"
这意味着我们只需要在进入 "down" 子树时跟踪堆栈中的所有 describe
调用,然后在进入 "up" 时一次弹出一个子树。如果在上升过程中只剩下一个节点要从堆栈中弹出,那么该节点是 "top-level" describe
.
最后,如果我们发现超过 "top-level" 描述,那么我们的规则应该报告错误。我为您制作了一个小型工作原型:https://astexplorer.net/#/3vMUwQjfpD/2
借助@vitorbal 的规则示例代码,pull request with the new max-top-level-suites
rule is now merged into and is a part of eslint-plugin-mocha
ESLint 插件。
您可以使用 no-restricted-syntax rule.
您要使用的选择器是:Program > ExpressionStatement[expression.type='CallExpression'][expression.callee.type='Identifier'][expression.callee.name='describe'] ~ ExpressionStatement[expression.type='CallExpression'][expression.callee.type='Identifier'][expression.callee.name='describe']
完整示例:
"no-restricted-syntax": [2,
{
"selector": "Program > ExpressionStatement[expression.type='CallExpression'][expression.callee.type='Identifier'][expression.callee.name='describe'] ~ ExpressionStatement[expression.type='CallExpression'][expression.callee.type='Identifier'][expression.callee.name='describe']",
"message": "Only one top level describe per test file"
}
],
故事:
我们有一个相当大的测试代码库,其中包含 Protractor+Jasmine 测试。
我们目前遇到的一个问题是 一些 test/spec 文件包含多个 describe 这不时会引起麻烦 - 例如,当我们使用 fdescribe
/fit
逐个(或分批)调试测试;有时我们没有注意到底部的同一文件中还有其他 decribe
,最终导致部分测试被无意中跳过。
换句话说,这是一种 "one assertion per test" 类型规则的变体,有助于保持测试代码库的清洁和 "flat".
问题:
有没有办法禁止每个文件超过一个 describe
?我目前正在考虑通过静态代码分析和 ESLint
来解决它,但我也对其他解决方案持开放态度。
样本:
违规示例:
describe("Test 1", function () {
it("should do something", function () {
expect(true).toBe(true);
});
});
describe("Test 2", function () {
it("should do something else", function () {
expect(false).toBe(false);
});
});
如果有单个 describe
块,但它包含嵌套的 describe
,则不应将其报告为违规。换句话说,可以拥有:
describe("Test 1", function () {
it("should do something", function () {
expect(true).toBe(true);
});
describe("Test 2", function () {
it("should do something else", function () {
expect(false).toBe(false);
});
});
});
棘手的部分是标记仅描述未嵌套的块,或 "top-level" 描述。幸运的是,这完全可以通过 ESLint 实现!
ESLint "visits" 遍历 JavaScript 代码的抽象语法树(简称 AST)时节点两次: down 一次树,另一个正在备份。
首先遍历树的深度,因此如果您的代码中有 3 个 describe
块,如下所示:
describe("Test 1", function () {
it("should do something", function () {
expect(true).toBe(true);
});
describe("Test 2", function () {
it("should do something else", function () {
expect(false).toBe(false);
});
});
});
describe("Test 3", function () {
it("should do something", function () {
expect(true).toBe(true);
});
});
将按以下顺序访问节点:
enter "Test 1"
-> enter "Test 2"
-> exit "Test 2"
-> exit "Test 1"
-> enter "Test 3"
-> exit "Test 3"
这意味着我们只需要在进入 "down" 子树时跟踪堆栈中的所有 describe
调用,然后在进入 "up" 时一次弹出一个子树。如果在上升过程中只剩下一个节点要从堆栈中弹出,那么该节点是 "top-level" describe
.
最后,如果我们发现超过 "top-level" 描述,那么我们的规则应该报告错误。我为您制作了一个小型工作原型:https://astexplorer.net/#/3vMUwQjfpD/2
借助@vitorbal 的规则示例代码,pull request with the new max-top-level-suites
rule is now merged into and is a part of eslint-plugin-mocha
ESLint 插件。
您可以使用 no-restricted-syntax rule.
您要使用的选择器是:Program > ExpressionStatement[expression.type='CallExpression'][expression.callee.type='Identifier'][expression.callee.name='describe'] ~ ExpressionStatement[expression.type='CallExpression'][expression.callee.type='Identifier'][expression.callee.name='describe']
完整示例:
"no-restricted-syntax": [2,
{
"selector": "Program > ExpressionStatement[expression.type='CallExpression'][expression.callee.type='Identifier'][expression.callee.name='describe'] ~ ExpressionStatement[expression.type='CallExpression'][expression.callee.type='Identifier'][expression.callee.name='describe']",
"message": "Only one top level describe per test file"
}
],