VSCode Task for Jest
Tags: vscode, javascript, testing
Published: 2020-09-20 14:26:50

I've tried the VSCode Jest extension a few times and never had much success with it. That said, the promise of tests running automatically and failures being added to my error list always seemed cool, so I decided to see if I could piece together a solution with tasks.

First off, set up a Jest Reporter to make it easier to parse the output from Jest. The documentation for reporters is pretty light, but thankfully [there are type definitions](https://github.com/facebook/jest/blob/master/packages/jest-reporters/src/types.ts#L59). Here's what I use:

```javascript
// custom reporter to make it easier to configure vscode to read problems
class CodeReporter {
  constructor(globalConfig, options) {
    this._globalConfig = globalConfig;
    this._options = options;
  }

  onRunStart(results, options) {
    console.log();
    console.log("-- RUN START");
  }

  onTestResult(test, testResult) {
    console.log(testResult.testFilePath);

    if (testResult.testExecError) {
      console.log(
        `-- failed;${
          testResult.testFilePath
        };1:1;${testResult.testExecError._originalMessage.replace(/\n/g, " ")}`
      );
    }

    testResult.testResults.forEach((r) => {
      if (r.status === "failed") {
        try {
          const stack = r.failureDetails[0].stack.split("\n");

          const frame1 = stack.findIndex((row) => row.startsWith("    at"));
          const location = stack[frame1].match(/[^:]*:([^:]*:[^:]*)/);

          console.log(
            `-- failed;${testResult.testFilePath};${
              location[1]
            };${r.failureDetails[0].message.replace(/\n/g, " ")}`
          );
        } catch (e) {
          console.log("ERROR", e);
        }
      }
    });
  }

  onRunComplete(contexts, results) {
    console.log();
    console.log("-- RUN COMPLETE");
  }
}

module.exports = CodeReporter;
```

Since it's intended for use in VSCode, I put it in my `.vscode` directory as `.vscode/code-reporter.js`.

Now we'll need to set up a `tasks.json` in the `.vscode` directory to configure the actual test task:

```json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "test",
      "command": "./node_modules/.bin/jest",
      "args": [
        "--watch",
        "--color=false",
        "--reporters=\"<rootDir>/.vscode/code-reporter.js\""
      ],
      "isBackground": true,
      "problemMatcher": {
        "owner": "javascript",
        "fileLocation": "absolute",
        "pattern": {
          "regexp": "^-- failed;([^;]+);([^;]+);([^;]+)$",
          "file": 1,
          "location": 2,
          "message": 3
        },
        "background": {
          "activeOnStart": true,
          "beginsPattern": "^-- RUN START",
          "endsPattern": "^-- RUN COMPLETE"
        }
      }
    }
  ]
}

```

This runs jest with `--watch` and configures the task as a background task. It also parses output using the custom reporter format. There's great [task documentation](https://code.visualstudio.com/Docs/editor/tasks) on the VSCode website.

That's it for configuration! To start the test task, hit Ctrl-Shift-P (Cmd-Shift-p on Mac) and choose `Tasks: Run Task`, and then choose the `test` task. It will run tasks that changed since the last commit, since that's the default for Jest, but you can interact with the task in VSCode's terminal just like you would interact with Jest in a terminal.

Once tests run you should see error highlighting for any failed tests:

![vscode-jest-task](https://dev-to-uploads.s3.amazonaws.com/i/jf84j20kdf310vlnsta2.gif)