Skip to content

Commit

Permalink
Detect active inspectors; update VSCode debugging recipe
Browse files Browse the repository at this point in the history
Don't open inspectors if one is already connected. Like with AVA's own `debug` command, disable timeouts and switch to verbose output. This allows VSCode 1.47 to debug AVA test files.

Update VSCode debugging recipe accordingly. Promote Debug Terminal in favor of launch configuration.

Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
Co-authored-by: Mark Wubben <mark@novemberborn.net>
  • Loading branch information
3 people committed Jul 27, 2020
1 parent 142363b commit bc39bcc
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 21 deletions.
32 changes: 18 additions & 14 deletions docs/recipes/debugging-with-vscode.md
Expand Up @@ -4,8 +4,17 @@ Translations: [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/do

You can debug your tests using [Visual Studio Code](https://code.visualstudio.com/).

## Debugging with the debug terminal

You can use VS Code's “JavaScript Debug Terminal” to automatically debug AVA run on the command-line.

1. From the Command Palette (<kbd>F1</kbd> or <kbd>command + shift + p</kbd> / <kbd>control + shift + p</kbd>), run `Debug: Create JavaScript Debug Terminal`
2. Run `npx ava` in the terminal

## Creating a launch configuration

Alternatively you can create a lanch configuration, which makes it easier to debug individual test files.

1. Open a workspace for your project.
1. In the sidebar click the *Debug* handle.
1. Create a `launch.json` file.
Expand All @@ -19,25 +28,22 @@ You can debug your tests using [Visual Studio Code](https://code.visualstudio.co
"name": "Debug AVA test file",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/ava",
"runtimeArgs": [
"debug",
"--break",
"${file}"
],
"port": 9229,
"outputCapture": "std",
"skipFiles": [
"<node_internals>/**/*.js"
]
}
```

## Using the debugger
### Using the debugger

Open the file(s) you want to debug. You can set breakpoints or use the `debugger` keyword.

Now, *with a test file open*, from the *Debug* menu run the *Debug AVA test file* configuration.

## Debugging precompiled tests
### Debugging precompiled tests

If you compile your test files into a different directory, and run the tests *from* that directory, the above configuration won't work.

Expand All @@ -51,11 +57,8 @@ Assuming the names of your test files are unique you could try the following con
"name": "Debug AVA test file",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/ava",
"runtimeArgs": [
"debug",
"--break",
"build/**/${fileBasenameNoExtension}.*"
],
"port": 9229,
"outputCapture": "std",
"skipFiles": [
"<node_internals>/**/*.js"
Expand All @@ -65,7 +68,13 @@ Assuming the names of your test files are unique you could try the following con

## Serial debugging

By default AVA runs tests concurrently. This may complicate debugging. Add a configuration with the `--serial` argument so AVA runs only one test at a time:
By default AVA runs tests concurrently. This may complicate debugging. Instead make sure AVA runs only one test at a time.

*Note that, if your tests aren't properly isolated, certain test failures may not appear when running the tests serially.*

If you use the debug terminal make sure to invoke AVA with `npx ava --serial`.

Or, if you're using a launch configuration, add the `--serial` argument:

```json
{
Expand All @@ -74,17 +83,12 @@ By default AVA runs tests concurrently. This may complicate debugging. Add a con
"name": "Debug AVA test file",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/ava",
"runtimeArgs": [
"debug",
"--break",
"--serial",
"${file}"
],
"port": 9229,
"outputCapture": "std",
"skipFiles": [
"<node_internals>/**/*.js"
]
}
```

*Note that, if your tests aren't properly isolated, certain test failures may not appear when running the tests serially.*
2 changes: 1 addition & 1 deletion lib/api.js
Expand Up @@ -147,7 +147,7 @@ class Api extends Emittery {
runStatus = new RunStatus(selectedFiles.length, null);
}

const debugWithoutSpecificFile = Boolean(this.options.debug) && selectedFiles.length !== 1;
const debugWithoutSpecificFile = Boolean(this.options.debug) && !this.options.debug.active && selectedFiles.length !== 1;

await this.emit('run', {
bailWithoutReporting: debugWithoutSpecificFile,
Expand Down
25 changes: 21 additions & 4 deletions lib/cli.js
Expand Up @@ -88,7 +88,19 @@ exports.run = async () => { // eslint-disable-line complexity
confError = error;
}

let debug = null;
// Enter debug mode if the main process is being inspected. This assumes the
// worker processes are automatically inspected, too. It is not necessary to
// run AVA with the debug command, though it's allowed.
const activeInspector = require('inspector').url() !== undefined; // eslint-disable-line node/no-unsupported-features/node-builtins
let debug = activeInspector ?
{
active: true,
break: false,
files: [],
host: undefined,
port: undefined
} : null;

let resetCache = false;
const {argv} = yargs
.parserConfiguration({
Expand Down Expand Up @@ -122,7 +134,11 @@ exports.run = async () => { // eslint-disable-line complexity
array: true,
describe: 'Glob patterns to select what test files to run. Leave empty if you want AVA to run all test files instead. Add a colon and specify line numbers of specific tests to run',
type: 'string'
}))
}), argv => {
if (activeInspector) {
debug.files = argv.pattern || [];
}
})
.command(
'debug [<pattern>...]',
'Activate Node.js inspector and run a single test file',
Expand All @@ -148,6 +164,7 @@ exports.run = async () => { // eslint-disable-line complexity
}),
argv => {
debug = {
active: activeInspector,
break: argv.break === true,
files: argv.pattern,
host: argv.host,
Expand Down Expand Up @@ -444,14 +461,14 @@ exports.run = async () => { // eslint-disable-line complexity
} else {
let debugWithoutSpecificFile = false;
api.on('run', plan => {
if (plan.debug && plan.files.length !== 1) {
if (debug !== null && plan.files.length !== 1) {
debugWithoutSpecificFile = true;
}
});

const runStatus = await api.run({filter});

if (debugWithoutSpecificFile) {
if (debugWithoutSpecificFile && !debug.active) {
exit('Provide the path to the test file you wish to debug');
return;
}
Expand Down
10 changes: 8 additions & 2 deletions lib/worker/subprocess.js
Expand Up @@ -205,8 +205,14 @@ ipc.options.then(async options => {
// to make sure we also track dependencies with custom require hooks
dependencyTracking.install(testPath);

if (options.debug) {
require('inspector').open(options.debug.port, options.debug.host, true); // eslint-disable-line node/no-unsupported-features/node-builtins
if (options.debug && options.debug.port !== undefined && options.debug.host !== undefined) {
// If an inspector was active when the main process started, and is
// already active for the worker process, do not open a new one.
const inspector = require('inspector'); // eslint-disable-line node/no-unsupported-features/node-builtins
if (!options.debug.active || inspector.url() === undefined) {
inspector.open(options.debug.port, options.debug.host, true);
}

if (options.debug.break) {
debugger; // eslint-disable-line no-debugger
}
Expand Down

0 comments on commit bc39bcc

Please sign in to comment.