javascript 如果挂起,如何调试mocha v4的示例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript 如果挂起,如何调试mocha v4的示例相关的知识,希望对你有一定的参考价值。

Here's an example of how to debug Mocha v4 if it hangs.

Ensure you're using a Node.js 8 or newer (or any version with [async_hooks](https://nodejs.org/api/async_hooks.html#async_hooks_async_hooks) support).

If you run your test, you'll notice it hangs:

```bash
$ mocha test.js


  how to debug Mocha when it hangs
    ✓ should complete, but Mocha should not exit


  1 passing (25ms)

```

You can include a module like `async-dump.js` to print information about what's happening.  First, add this hook somewhere in the `describe` block:

```js
after(function () {
  global.asyncDump();
});
```

Then, you can `--require` `async-dump.js` with Mocha:

```bash
$ mocha --require async-dump test.js


  how to debug Mocha when it hangs
    ✓ should complete, but Mocha should not exit

STUFF STILL IN THE EVENT LOOP:
Type: SIGNALWRAP
Error
    at AsyncHook.init (async-dump.js:12:62)
    at Signal.emitInitNative (async_hooks.js:458:43)
    at process.<anonymous> (internal/process.js:209:20)
    at startup (bootstrap_node.js:201:16)
    at bootstrap_node.js:626:3


Type: TCPWRAP
Error
    at AsyncHook.init (async-dump.js:12:62)
    at TCP.emitInitNative (async_hooks.js:458:43)
    at createServerHandle (net.js:1267:14)
    at Server.setupListenHandle [as _listen2] (net.js:1310:14)
    at listenInCluster (net.js:1391:12)
    at Server.listen (net.js:1474:7)
    at Context.<anonymous> (debug-hanging-mocha.js:9:12)


Type: TCPWRAP
Error
    at AsyncHook.init (async-dump.js:12:62)
    at TCP.emitInitNative (async_hooks.js:458:43)
    at Socket.connect (net.js:997:40)
    at Object.connect (net.js:104:35)
    at Context.<anonymous> (debug-hanging-mocha.js:17:22)


Type: DNSCHANNEL
Error
    at AsyncHook.init (async-dump.js:12:62)
    at ChannelWrap.emitInitNative (async_hooks.js:458:43)
    at new Resolver (dns.js:249:20)
    at dns.js:380:25
    at NativeModule.compile (bootstrap_node.js:614:7)
    at NativeModule.require (bootstrap_node.js:559:18)
    at lazyDns (net.js:1376:11)
    at lookupAndConnect (net.js:1026:15)
    at Socket.connect (net.js:1019:5)
    at Object.connect (net.js:104:35)
    at Context.<anonymous> (debug-hanging-mocha.js:17:22)


Type: TCPWRAP
Error
    at AsyncHook.init (async-dump.js:12:62)
    at TCP.emitInitNative (async_hooks.js:458:43)


Type: Immediate
Error
    at AsyncHook.init (async-dump.js:12:62)
    at emitInitNative (async_hooks.js:458:43)
    at emitInitScript (async_hooks.js:361:3)


  1 passing (25ms)
```

These are not *Errors*; everything that's printed above are async tasks that have been "started" but not "finished".

From the above, you will notice that the `TCPWRAP` resource(s) are interesting.  Within the stack trace, you can see where exactly these happen in your code:

```
Type: TCPWRAP
Error
    at AsyncHook.init (async-dump.js:12:62)
    at TCP.emitInitNative (async_hooks.js:458:43)
    at createServerHandle (net.js:1267:14)
    at Server.setupListenHandle [as _listen2] (net.js:1310:14)
    at listenInCluster (net.js:1391:12)
    at Server.listen (net.js:1474:7)
    at Context.<anonymous> (debug-hanging-mocha.js:9:12)
```

On line 9, we're listening on a port, but we never shut down the server.

`async-dump.js` could certainly be improved upon, but this is a rough guide.

The Node.js inspector (use `--inspect-brk`, etc.) will also give you similar information, but it's not so easily filtered.

[why-is-node-running](https://npm.im/why-is-node-running) can also be used with some fiddling (do `node --expose-internals /path/to/_mocha test.js` then `require('why-is-node-running')()` at the top of `test.js`), but YMMV.
'use strict';

const {createHook} = require('async_hooks');
const {stackTraceFilter} = require('mocha/lib/utils');
const allResources = new Map();

// this will pull Mocha internals out of the stacks
const filterStack = stackTraceFilter();

const hook = createHook({
  init(asyncId, type, triggerAsyncId) {
    allResources.set(asyncId, {type, triggerAsyncId, stack: (new Error()).stack});
  },
  destroy(asyncId) {
    allResources.delete(asyncId);
  }
}).enable();

global.asyncDump = module.exports = () => {
  hook.disable();
  console.error(`
STUFF STILL IN THE EVENT LOOP:`)
  allResources.forEach(value=> {
    console.error(`Type: ${value.type}`);
    console.error(filterStack(value.stack));
    console.error('\n');
  });
};
'use strict';

const net = require('net');
const assert = require('assert');

describe('how to debug Mocha when it hangs', function () {
  before(function (done) {
    const server = net.createServer();
    server.listen(10101, done);
  });

  it('should complete, but Mocha should not exit', function(done) {
    const sock = net.createConnection(10101, () => {
      assert.deepEqual(sock.address().family, 'IPv4');
      done();
    });
  });
});

以上是关于javascript 如果挂起,如何调试mocha v4的示例的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Visual Studio Code 中的 Mocha 调试 Typescript 编写的单元测试

如何检查请求是不是使用 JavaScript (Mocha) 发送

如何在 Mocha 测试中调试“错误:无理由或错误理由拒绝承诺”?

VSCode下调试mocha测试用例

如何使用 Mocha 测试“正常”(非节点特定)JavaScript 函数?

如何调试在 Windows Phone 8.1 上挂起的应用程序