【问题标题】:Debugging Jest test cases using node-inspector使用节点检查器调试 Jest 测试用例
【发布时间】:2014-09-28 07:31:30
【问题描述】:

有没有办法使用节点检查器来调试带有 Jest 的单元测试?有时可以逐步了解测试失败的原因

我尝试了几种方法

node-debug jest --runInBand 

从以及首先启动检查器,例如

$ node-inspector
$ node --debug-brk .\node_modules\jest-cli --runInBand

然后导航到http://127.0.0.1:8080/debug?port=5858

我发现偶尔(大约 10 次中的 1 次),调试器会打开 jest src 文件并且可以调试它们。不过,一般来说,调试器中的脚本只包含一个“无域”文件夹和另一个不相关的文件夹。 此外,测试脚本本身也不会加载到调试器中。

以前有人试过吗?

【问题讨论】:

    标签: node-inspector jestjs


    【解决方案1】:

    看起来问题在于jest 正在使用harmonize,它会生成一个子进程以确保使用--harmony 选项。

    harmonize/harmonize.js,第 30-35 行

    var node = child_process.spawn(process.argv[0], ['--harmony'].concat(process.argv.slice(1)), {});
    node.stdout.pipe(process.stdout);
    node.stderr.pipe(process.stderr);
    node.on("close", function(code) {
        process.exit(code);
    });
    

    通过注释掉 jest 用于生成协调进程的代码,我能够成功调试 jest 测试(尽管 tests that use JSX transforms are incredibly slow)。

    node_modules/jest-cli/bin/jest.js,文件最后几行:

    if (require.main === module) {
      //harmonize();                  <--- comment out
      _main(function (success) {
        process.exit(success ? 0 : 1);
      });
    }
    

    然后就可以运行了:

    $ node-debug --nodejs --harmony ./node_modules/jest-cli/bin/jest.js --runInBand
    

    Jest 依赖于存在的--harmony 标志,因此我们需要使用--nodejs --harmony 将其添加回来。我们还添加了--runInBand,以便测试按顺序运行,而不是并行运行。

    这将打开 Web 调试器,您可以调试测试,尽管到达您想要的测试可能会很慢。如果有人知道如何使这更快,请发表评论,我会更新我的答案。

    您可以将其添加到您的 package.json 以更轻松地开始:

    ...
        scripts: {
            "test": "jest",
            "test-debug": "node-debug --nodejs --harmony ./node_modules/jest-cli/bin/jest.js --runInBand"
        }
    ...
    

    当然,这个解决方案的主要关注点是编辑jest 源代码。将考虑如何提出拉取请求以使其坚持下去。

    在此处创建 Github 问题https://github.com/facebook/jest/issues/152

    【讨论】:

    • 对我来说很棒!不需要 monkeypatch 并且删除 --runInBand 似乎可以让您更快地进行测试。感谢脚本提示。
    • 是的,我的 PR 被拒绝了,因为您刚刚引用了它检查 Proxy 的行,但我认为如果没有手动 --harmony 标志,它对我不起作用,但我没有最近没有时间再试一次。如果我可以验证它在没有猴子补丁的情况下可以工作,我会更新这个答案。
    • 有没有一步一步的让它与 webstorm 调试器一起工作?
    【解决方案2】:

    现在正式支持 Node >= 6.3。
    引用Jest documentation:

    在您的任何测试中放置 debugger; 语句,然后在您的项目目录中运行:

    node --debug-brk --inspect ./node_modules/.bin/jest -i [any other arguments here]
    

    这将输出一个您可以在 Chrome 中打开的链接。打开该链接后,将显示 Chrome 开发人员工具,并在 Jest CLI 脚本的第一行设置断点(这样做只是为了让您有时间打开开发人员工具并防止 Jest 在您之前执行有时间这样做)。单击屏幕右上角看起来像“播放”按钮的按钮以继续执行。当 Jest 执行包含 debugger 语句的测试时,执行将暂停,您可以检查当前范围和调用堆栈。

    注意:-i cli 选项确保 Jest 在同一进程中运行测试,而不是为单个测试生成进程。通常 Jest 会跨进程并行测试运行,但很难同时调试多个进程。

    关于 V8 检查器的更多信息可以在这里找到:https://nodejs.org/api/debugger.html#debugger_v8_inspector_integration_for_node_js

    【讨论】:

    • 这看起来很有希望,我试过了,但它永远不会在调试器语句上停止。有什么想法吗?
    • 这里也一样。脚本正确启动,我可以打开浏览器窗口并单击类似播放按钮...调试器永远不会被击中:|
    • 对我来说,jest的路径不同,所以我的命令是node --debug-brk --inspect ./node_modules/jest/bin/jest -i --env jest-environment-node-debug
    • 我也没有看到使用这种方法在我的规范中的 debugger 语句上开玩笑。
    • 它适用于我,但运行测试时未定义 window
    【解决方案3】:

    使用 Node 7.4.0、Jest 18.x 和 jest-environment-node-debug 包(来自 this comment),现在可以使用 chrome devtools 来调试 Jest 测试:

    $ npm install -D jest-environment-node-debug
    $ node --inspect-brk ./node_modules/.bin/jest -i --env jest-environment-node-debug
    

    【讨论】:

    • 这是最好的答案。其他的都过时了。
    • 使用--inspect-brk 并没有开始测试(它'breaks before user code starts'),但使用--inspect 它确实
    【解决方案4】:

    这是一个 Gruntfile.js 配置,用于使用 Grunt 自动化 @Sean 的回答。

    grunt testd
    

    grunt testd --tests=MyTestName
    

    grunt testd --tests=MyTestName,AnotherTestName
    

    需要“node-inspector”(必须全局安装才能在您的路径中获取 node-debug bin)、“lodash”、“jest-cli”和“grunt-shell”节点模块。

    var _ = require('lodash');
    
    var commaSplitToRegex = function(input) {
      return _.map(input.split(','), function(part) {
        return '(' + part + ')';
      }).join('|');
    };
    
    var getTestRegex = function(tests) {
      if (tests) {
        return '.*' + commaSplitToRegex(tests) + '.*';
      }
    
      return '.*';
    }
    
    module.exports = function(grunt) {
      grunt.loadNpmTasks('grunt-shell');
    
      grunt.initConfig({
        shell: {
          jestd: {
            command: function() {
              var testsRegex = getTestRegex(grunt.option('tests'));
              var cmd = 'node-debug --nodejs --harmony ./node_modules/jest-cli/bin/jest.js --runInBand --config="test_utils/jest.json"';
    
              if (testsRegex) {
                cmd += ' "' + testsRegex + '"';
              }
    
              return cmd;
            }
          },
          monkeypatchjest: {
            command: 'sed -i.bak s\\/harmonize\\(\\)\\;\\/\\\\/\\\\/wtf\\/g ./node_modules/jest-cli/bin/jest.js'
          },
          unmonkeypatchjest: {
            command: 'sed -i.bak s\\/\\\\/\\\\/wtf\\/harmonize\\(\\)\\;\\/g ./node_modules/jest-cli/bin/jest.js'
          }
        }
      });
    
      grunt.registerTask('testd', 'Run tests with debugger.', ['shell:monkeypatchjest', 'shell:jestd']);
    };
    

    【讨论】:

      猜你喜欢
      • 2015-06-18
      • 2015-07-16
      • 2020-12-19
      • 2014-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-28
      • 2019-04-21
      相关资源
      最近更新 更多