每个文件强制执行一次描述

时间:2016-09-11 13:19:20

标签: javascript jasmine protractor eslint static-code-analysis

故事:

我们有一个相当大的测试代码库,带有Protractor + Jasmine测试。

我们当前遇到的一个问题是某些测试/规范文件包含多个描述,这会不时引起麻烦 - 例如,在逐个调试测试时(或我们分批使用fdescribe / fit;有时候我们没有注意到底部的同一个文件中还有其他decribe个,最终导致部分测试被无意中跳过。

换句话说,这是"每个测试一个断言的变体"帮助保持测试代码库清洁的规则类型"平坦"。

问题:

有没有办法禁止每个文件有多个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);
        });
    });
});

2 个答案:

答案 0 :(得分:4)

棘手的部分是标记仅描述未嵌套的块或“顶级”描述的块。幸运的是,ESLint完全可以实现这一点!

ESLint在遍历JavaScript代码的抽象语法树(简称AST)时“访问”节点两次:一次在向下树时,另一次在返回时向上即可。 树首先遍历深度,因此,例如,如果您的代码中有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"

这意味着我们只需要跟踪一个堆栈中的所有describe调用,同时“向下”一个子树,然后在“向上”该子树的同时弹出一个。如果在上升时只剩下一个节点从堆栈弹出,则该节点是“顶级”describe

最后,如果我们发现超过“顶级”描述,那么我们的规则应报告错误。我为你准备了一个小型工作原型:https://astexplorer.net/#/3vMUwQjfpD/2

答案 1 :(得分:1)

在@ vitorbal的规则示例代码的帮助下,pull request与新max-top-level-suites rule现已合并,并且是eslint-plugin-mocha ESLint插件的一部分。