【问题标题】:List all mocha tests without executing them列出所有 mocha 测试而不执行它们
【发布时间】:2023-03-14 14:31:01
【问题描述】:

有没有办法在 mochajs 中列出测试运行器收集的所有测试而不执行它们?

例如如果有看起来像这样的规格:

describe('First', function() {
    it('should test something', function() {
        ...
    })
});

describe('Second', function() {
    it('should test something else', function() {
        ...
    })
});

然后我想获得类似于测试报告器产生的输出的控制台输出,但不执行实际测试,如下所示:

First
    should test something
Second
    should test something else

UPD:

目前我正在使用正则表达式提取所有 describes 和 its,但正在寻找更清洁的解决方案。

【问题讨论】:

    标签: javascript node.js testing mocha.js


    【解决方案1】:

    mocha-list-tests 包很有用,但仅适用于 BDD 样式 describe()it(),如果您 .skip() 进行任何测试,它会中断,因为它会模拟 it()

    如果您需要克服其中任何一个问题或获取有关测试的其他信息,您可以自己执行此操作的一种方法是利用 Mocha 的根 before() 钩子。这将在 Mocha 加载所有文件之后但在执行任何测试之前执行,因此您需要的所有信息都存在于那个时候。

    这样,很容易在--list-only 命令行选项中打补丁来切换测试运行的行为,而无需添加或更改任何其他内容。

    关键是before()钩子中的this是Mocha的Context,其中的.test指的是钩子本身。所以this.test.parent 指的是根套件。从那里,您可以沿着 .suites 数组树和每个套件的 .tests 数组树向下走。

    收集到你想要的任何东西后,你必须输出它并退出该过程以阻止 Mocha 继续。

    纯文本示例

    鉴于 root.js

    #!/bin/env mocha
    
    before(function() {
        if(process.argv.includes('--list-only')) {
            inspectSuite(this.test.parent, 0);
            process.exit(0);
        }
        // else let Mocha carry on as normal...
    });
    
    function inspectSuite(suite, depth) {
        console.log(indent(`Suite ${suite.title || '(root)'}`, depth));
    
        suite.suites.forEach(suite => inspectSuite(suite, depth +1));
        suite.tests.forEach(test => inspectTest(test, depth +1));
    }
    
    function inspectTest(test, depth) {
        console.log(indent(`Test ${test.title}`, depth));
    }
    
    function indent(text, by) {
        return '    '.repeat(by) + text;
    }
    

    还有test.js

    #!/bin/env mocha
    
    describe('foo', function() {
        describe('bar', function() {
            it('should do something', function() {
                // ...
            });
        });
    
        describe('baz', function() {
            it.skip('should do something else', function() {
                // ...
            });
    
            it('should do another thing', function() {
                // ...
            });
        });
    });
    

    然后像往常一样运行mocha 会得到你期望的测试结果:

      foo
        bar
          ✓ should do something
        baz
          - should do something else
          ✓ should do another thing
    
    
      2 passing (8ms)
      1 pending
    

    但是运行 mocha --list-only 会给你(不运行任何测试):

    Suite (root)
        Suite foo
            Suite bar
                Test should do something
            Suite baz
                Test should do something else
                Test should do another thing
    

    JSON 示例

    root.js

    #!/bin/env mocha
    
    before(function() {
        let suites = 0;
        let tests = 0;
        let pending = 0;
    
        let root = mapSuite(this.test.parent);
    
        process.stdout.write(JSON.stringify({suites, tests, pending, root}, null, '    '));
        process.exit(0);
    
        function mapSuite(suite) {
            suites += +!suite.root;
            return {
                title: suite.root ? '(root)' : suite.title,
                suites: suite.suites.map(mapSuite),
                tests: suite.tests.map(mapTest)
            };
        }
    
        function mapTest(test) {
            ++tests;
            pending += +test.pending;
            return {
                title: test.title,
                pending: test.pending
            };
        }
    });
    

    使用与以前相同的测试脚本会给你:

    {
        "suites": 3,
        "tests": 3,
        "pending": 1,
        "root": {
            "title": "(root)",
            "suites": [
                {
                    "title": "foo",
                    "suites": [
                        {
                            "title": "bar",
                            "suites": [],
                            "tests": [
                                {
                                    "title": "should do something",
                                    "pending": false
                                }
                            ]
                        },
                        {
                            "title": "baz",
                            "suites": [],
                            "tests": [
                                {
                                    "title": "should do something else",
                                    "pending": true
                                },
                                {
                                    "title": "should do another thing",
                                    "pending": false
                                }
                            ]
                        }
                    ],
                    "tests": []
                }
            ],
            "tests": []
        }
    }
    

    【讨论】:

      【解决方案2】:

      将所有描述块包装在描述块中并跳过它。

      describe.skip('Outline', function() {
          describe('First', function() {
              it('should test something', function() {
                  ...
              })
          });
      
          describe('Second', function() {
              it('should test something else', function() {
                  ...
              })
          });
      });
      

      【讨论】:

      • 虽然这会打印出测试列表,但并不能真正解决问题。我不知道如何将此解决方案用于测试存储在多个文件中并且需要定期检索测试列表的项目。
      • 你真正想要的是--dry-run 选项,它已经被提议但从未被合并。见mocha pull request #1070
      • 是的,这正是我正在寻找的,遗憾的是它没有被接受。
      【解决方案3】:

      mocha-list-tests

      我不骗你,有一个单独的包:https://www.npmjs.com/package/mocha-list-tests

      npm install mocha mocha-list-tests
      node ./node_modules/mocha-list-tests/mocha-list-tests.js main.js
      

      示例输出:

      {
        "suites": [
          "a1",
          "a2"
        ],
        "tests": [
          "a1.a11",
          "a1.a12",
          "a2.a21",
          "a2.a22"
        ],
        "tree": {
          "a1": {
            "a11": true,
            "a12": true
          },
          "a2": {
            "a21": true,
            "a22": true
          }
        }
      }
      

      对于这个测试文件:

      main.js

      #!/usr/bin/env node
      
      const assert = require('assert');
      const fs = require('fs');
      
      describe('a1', function() {
        it('a11', function() {
          assert.equal(1, 1);
          fs.writeFileSync('abc', 'def', 'utf8');
        });
        it('a12', function() {
          assert.equal(1, 2);
        });
      });
      describe('a2', function() {
        it('a21', function() {
          assert.equal(1, 1);
        });
        it('a22', function() {
          assert.equal(1, 2);
        });
      });
      

      文件abc 没有创建,所以我知道测试没有执行。

      这很可能是使用在:https://github.com/mochajs/mocha/wiki/Using-Mocha-programmatically 中提到的 API Mocha

      在 mocha@6.2.2、mocha-list-tests@1.0.2、Node v10.15.1 中测试。

      【讨论】:

      • 仅供参考,不,它不使用 API。它专门模拟 describe()it() 然后 require()s 测试脚本,捕获它们的用法。
      • 没有用。幸运的是,mocha-decaf 确实有效。
      • @Domi 相同版本的 mocha 和 mocha-list-tests?输出是什么?
      • mocha-list-tests 没有输出任何东西,只是产生了一个空对象。幸运的是,自从 mocha 最终添加了 dry-run 选项后,它不再需要 - 请参阅 my answer here
      • (仅供参考:我在sequelize test 文件夹上测试了它,使用DIALECT=sqlite
      【解决方案4】:

      截至mocha@9,已添加dry-run option (PR here)。

      如果您想列出(并以编程方式使用)所有测试,您需要启用 dry-run 可能还有 json 报告器,如下所示:

      {
        "dry-run": true,
        "reporter": "json"
      }
      

      如何生成我们可以通过编程方式使用的测试列表?

      如果您想以编程方式使用测试输出:运气不好。事实证明,与它的名字相反,JSON 报告器不会生成纯 JSON(如 in this outstanding Mocha issue 所讨论的那样)。

      作为一种解决方法,我编写了一个小脚本 (gist here),其工作原理如下:

      1. 将 mocha 输出存储到文件:npm run test > tests-raw.json
        • 或:yarn test > tests-raw.json
        • 或:mocha --dry-run --reporter=json ... > tests-raw.json
      2. 转换输出:./mocha-list-tests.js tests-raw.json tests.json
      3. 文件tests.json 现在包含所有测试结果对象的数组。记录的对mocha 的每次调用都应该产生一个这样的对象。

      我找不到太多关于确切输出格式的文档,但主要是两件事:

      • stats - 基本的整体统计数据
      • tests - 所有找到的测试(见Test#serialize method
      • failurespendingpasses - 如果您只想列出测试,您可能不会关心这些。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多