Test Driven Development Setup With Jest in VS Code

Learn how to set up a Test Driven Development (TDD) environment using Jest in Visual Studio Code (VS Code) to ensure code quality and reliability.

Test Driven Development (TDD) is a software development approach where tests are written before the actual code. This method helps ensure that the code meets its requirements and behaves as expected. In this guide, we will set up a TDD environment using Jest, a popular testing framework, in Visual Studio Code (VS Code). This setup is divided into several steps to help get started with TDD effectively. Assuming you have Node.js and npm installed, follow these steps:


🛠️ Setting Up Test Driven Development (TDD) with Jest in VS Code

Test Driven Development (TDD) is a software development approach where tests are written before the actual code. This method helps ensure that the code meets its requirements and behaves as expected. In this guide, we will set up a TDD environment using Jest, a popular testing framework, in Visual Studio Code (VS Code). This setup is divided into several steps to help get started with TDD effectively.This setup includes multiple components working together:

  • Jest for unit testing and test automation
  • cSpell for spell checking in documentation and code
  • VS Code extensions for enhanced development experience
  • Configuration files for seamless integration

Prerequisites: Ensure you have Node.js (version 16 or higher) and npm installed on your system, along with Visual Studio Code.

Step - 1 Project Initialization and VS Code Extensions

1.1 Initialize a New Node.js Project

Open your terminal and create a new directory for your project. Navigate into the directory and run the following command to initialize a new Node.js project:

1mkdir my-tdd-project
2cd my-tdd-project
3npm init -y

1.2 Install Essential VS Code Extensions

Install the following extensions from the VS Code marketplace for optimal TDD experience:

Core Testing Extensions

  • Jest: Provides Jest integration with test running capabilities, inline test results, and debugging support.
  • Jest Runner: Allows running individual Jest tests directly from the editor.

Spell Checking Extensions

  • Code Spell Checker: Basic spell checking for code and comments.
  • cSpell: Advanced spell checking with bundled dictionaries for technical terms.

Install cSpell and Jest for manual Testing

To install cSpell and Jest for manual testing, run the following command:

1npm install --save-dev jest cspell @cspell/dict-software-terms

1.3 Verify Installations

To verify that the extensions and packages are installed correctly, you can check the installed extensions in VS Code by navigating to the Extensions view (Ctrl+Shift+X or Cmd+Shift+X on Mac) and searching for the names mentioned above. For npm packages, you can check your package.json file to ensure that jest and cspell are listed under devDependencies.

1 "devDependencies": {
2    "@cspell/dict-software-terms": "^5.1.8",
3    "cspell": "^9.2.1",
4    "jest": "^30.1.3"
5  }

1.4 Create Basic Project Structure

Create the following folder structure in your project directory:

1my-tdd-project/
2├── docs/
3├── .vscode/
4│   └── settings.json
5├── __tests__/
6├── package.json
7└── package-lock.json

1.4 Configure VS Code Settings

Create a .vscode folder in the root of your project and add a settings.json file with the following content to configure VS Code settings for Jest and cSpell:

1{
2  "editor.formatOnSave": true,
3  "cSpell.language": "en-GB",
4  "cSpell.enabledFileTypes": {
5    "markdown": true,
6    "plaintext": true
7  },
8  "jest.runMode": "watch"
9}

1.5 Add scripts in package.json

1 "scripts": {
2  "test": "jest",
3  "test:watch": "jest --watch",
4  "test:spell": "jest spellcheck",
5  "spell:check": "cspell \"docs/**/*.md\"",
6  "spell:check:verbose": "cspell \"docs/**/*.md\" --no-progress --no-summary"
7 }

1.5 Test Setup with Jest

To test other script, create a spell.md file with some spelling mistakes in the docs folder and run the following commands to check if cSpell is working fine. Run first script npm run test to check if jest is working fine. It should say the following

 1npm run test
 2
 3> vscode-jest-tdd-cspell@1.0.0 test
 4> jest
 5
 6No tests found, exiting with code 1
 7Run with `--passWithNoTests` to exit with code 0
 8In /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell
 9  3 files checked.
10  testMatch: **/__tests__/**/*.?([mc])[jt]s?(x), **/?(*.)+(spec|test).?([mc])[jt]s?(x) - 0 matches
11  testPathIgnorePatterns: /node_modules/ - 3 matches
12  testRegex:  - 0 matches
13Pattern:  - 0 matches
  • First three scripts will fail. Since there is no test written yet, it is expected to show no tests found which tells us that jest is working fine.
  • Run npm run spell:check to check if cSpell is working fine. It should say the following
 1npm run spell:check
 2
 3> vscode-jest-tdd-cspell@1.0.0 spell:check
 4> cspell "docs/**/*.md"
 5
 6
 71/1 docs/spell.md 484.05ms X
 8docs/spell.md:3:6 - Unknown word (fyle)
 9docs/spell.md:3:15 - Unknown word (obvios)
10docs/spell.md:3:22 - Unknown word (spellin)
11CSpell: Files checked: 1, Issues found: 3 in 1 file.

The contnes of the spell.md file is as follows

1# Spelling Error
2
3This fyle has obvios spellin errors.

Step - 2

Setting up configuration files for Jest and cSpell.

  1. Create a configuration file in the root of the project. This file can be created in many formats. We will use cspell.config.yaml to have our configuration setup present in ths file.
  2. This setup also uses a global configuration file named cspell.json via import property. The global file resides in /home/ag-sayyed/.config/cspell/ folder. it access already existing global dictionaries present in the same folder.
  3. Here are the contents of cspell.config.yaml file
 1schema: <https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json>
 2 version: '0.2'
 3 language: 'en-GB'
 4 import: '/home/ag-sayyed/.config/cspell/cspell.json'
 5 dictionaryDefinitions:
 6   - name: project-words
 7     path: './.vscode/project-words.txt'
 8     addWords: true
 9 dictionaries:
10   - en_GB
11   - project-words
12 noConfigSearch: true
13 allowCompoundWords: false
14 ignorePaths:
15   - 'node_modules/**'
16   - 'package-lock.json'
17   - 'package.json'
18   - '.git/**'
19 ignoreRegExpList:
20   - '\\{\\{.*?\\}\\}'
21   - '\\[\\[.*?\\]\\]'
22   - '\\$\\{.*?\\}'
23   - 'href=[\"''].*?[\"'']'
24   - 'src=[\"''].*?[\"'']

Run Tests

Running npm run spell:check should give the same output as before. If things do not work, use verbose mode to see more details.

 1 npx cspell docs/spell.md --verbosenpx cspell docs/spell.md --verbose
 2
 3cspell;
 4Date: Fri, 19 Sep 2025 14:47:46 GMT
 5Options:
 6    verbose:   Yes
 7    config:    default
 8    exclude:   node_modules/**
 9    files:     docs/spell.md
10    wordsOnly: No
11    unique:    No
12
13Config Files Found:
14    /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/cspell.config.yaml
15
16Exclusion Globs:
17    Glob: package-lock.json from /home/ag-sayyed/.config/cspell/cspell.json
18    Glob: node_modules from /home/ag-sayyed/.config/cspell/cspell.json
19    Glob: .git from /home/ag-sayyed/.config/cspell/cspell.json
20    Glob: .vscode/** from /home/ag-sayyed/.config/cspell/cspell.json
21    Glob: **/.vscode/** from /home/ag-sayyed/.config/cspell/cspell.json
22    Glob: **/*.code-workspace from /home/ag-sayyed/.config/cspell/cspell.json
23    Glob: settings.json from /home/ag-sayyed/.config/cspell/cspell.json
24    Glob: **/settings.json from /home/ag-sayyed/.config/cspell/cspell.json
25    Glob: node_modules/** from /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/cspell.config.yaml
26    Glob: package-lock.json from /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/cspell.config.yaml
27    Glob: package.json from /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/cspell.config.yaml
28    Glob: .git/** from /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/cspell.config.yaml
29    Glob: node_modules/** from command line
30
31Checking: /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/docs/spell.md, File type: auto, Language: default
32Checked: /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/docs/spell.md, File type: markdown, Language: en-GB ... Issues: 2 570.15ms
33Config file Used: /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/cspell.config.yaml
34Dictionaries Used: aws, companies, cryptocurrencies, filetypes, public-licenses, softwareTerms, coding-compound-terms, computing-acronyms, software-term-suggestions, software-tools, web-services, en_GB, misc, typescript, node, html, css, personal, hbstack-site, project-words, en-common-misspellings, en-gb-common-misspellings, en-gb, html-symbol-entities, npm
351/1 docs/spell.md 570.15ms X
36docs/spell.md:3:15 - Unknown word (obvios)
37docs/spell.md:3:22 - Unknown word (speling) fix: (spelling)
38CSpell: Files checked: 1, Issues found: 2 in 1 file.

Running command with verbose flag shows more details about the configuration files being used and the dictionaries being loaded. It also shows that our configuration files are present and newly created files are detected and used with the exact location of the spelling mistakes in the file. Aslo it tells us which dictionaries are being used.

1Dictionaries Used: aws, companies, cryptocurrencies, filetypes, public-licenses, softwareTerms, coding-compound-terms, computing-acronyms, software-term-suggestions, software-tools, web-services, en_GB, misc, typescript, node, html, css, `personal, hbstack-site`, project-words, en-common-misspellings, en-gb-common-misspellings, en-gb, html-symbol-entities, npm

The above list shows that our global and custom dictionaries named personal, hbstack-site and project-words are being used.

Simply run the command npm run spell:check to see the same output. The output should be the same as before.

Ignore Project Specific Words

To ignore words, which are part of this project, create a file named project-words.txt in the .vscode folder, if not created yet, and add the words to be ignored in this file. For example, add the following words to the file. Run the test again to see if the words are ignored.


Step - 3

Start Adding Jest Tests

  1. Create a test file named jest.config.js in the root of your project with the following content:
1module.exports = {
2  testEnvironment: 'node',
3  testMatch: ['**/__tests__/**/*.js', '**/?(*.)+(spec|test).js'],
4  verbose: true,
5  testTimeout: 15000 // Increased timeout for spell checking operations
6}

The above configuration sets up Jest to use the Node.js environment, specifies the test file patterns, enables verbose output, and increases the default timeout to accommodate spell-checking operations. This file is necessary for jest to run tests. The actual tests are to be written in the __tests__ folder.

  1. Create a test file named spellcheck.test.js in the __tests__ folder with the following content:
 1const { exec } = require('child_process')
 2const fs = require('fs')
 3const path = require('path')
 4const util = require('util')
 5
 6const execPromise = util.promisify(exec)
 7
 8/**
 9 * Helper function to run cspell on specified files
10 * @param {string} files - Glob pattern or specific file path to check
11 * @returns {Promise<Object>} - The result of running cspell
12 */
13async function runCSpell(files) {
14  try {
15    const { stdout } = await execPromise(`npx cspell ${files}`)
16    return { success: true, output: stdout }
17  } catch (error) {
18    return { success: false, output: error.stdout, error: error.stderr }
19  }
20}

The above code sets up a helper function to run cSpell using Node.js’s child_process module. It uses util.promisify to convert the exec function into a promise-based function for easier async/await usage. It also includes error handling to capture both standard output and error output.

  1. Add your first test to see if cSpell configuration file is present or not. In tdd or test driven development, tests are written first before the actual code. So, we will write a test to check if the configuration file cspell.config.yaml is present in the root of the project. Since we have already created this file, for the process to be followed we changed its name to cspell.config.yaml.bak and then run the test. The test should fail since the file is not present. After that we will rename the file back to its original name and run the test again. This time it should pass.
 1describe('CSpell Configuration', () => {
 2  test('cspell.config.yaml exists and is valid', () => {
 3    const cspellConfigPath = path.join(process.cwd(), 'cspell.config.yaml')
 4    expect(fs.existsSync(cspellConfigPath)).toBe(true)
 5
 6    // Read YAML file as text to check basic validity
 7    const configContent = fs.readFileSync(cspellConfigPath, 'utf8')
 8    expect(configContent).toContain('version:')
 9    expect(configContent).toContain("language: 'en-GB'")
10    expect(configContent).toContain('dictionaries:')
11  })
12})

As the file is not present, the test should fail with the following output

 1 vscode-jest-tdd-cspell@1.0.0 test
 2> jest --testLocationInResults --json --useStderr --outputFile /tmp/jest_runner_vscode_jest_tdd_cspell_1000_2.json --testNamePattern CSpell Configuration cspell\.config\.yaml exists and is valid$ --no-coverage --reporters default --reporters /home/ag-sayyed/.vscode/extensions/orta.vscode-jest-6.4.4/out/reporter.js --colors --watchAll=false --testPathPatterns /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/__tests__/spellcheck\.test\.js
 3
 4 FAIL  __tests__/spellcheck.test.js
 5  CSpell Configuration
 6     cspell.config.yaml exists and is valid (3 ms)
 7
 8   CSpell Configuration  cspell.config.yaml exists and is valid
 9
10    expect(received).toBe(expected) // Object.is equality
11
12    Expected: true
13    Received: false
14
15      26 |   test('cspell.config.yaml exists and is valid', () => {
16      27 |     const cspellConfigPath = path.join(process.cwd(), 'cspell.config.yaml');
17    > 28 |     expect(fs.existsSync(cspellConfigPath)).toBe(true);
18         |                                             ^
19      29 |
20      30 |     // Read YAML file as text to check basic validity
21      31 |     const configContent = fs.readFileSync(cspellConfigPath, 'utf8');
22
23      at Object.toBe (__tests__/spellcheck.test.js:28:45)
24
25Test Suites: 1 failed, 1 total
26Tests:       1 failed, 1 total
27Snapshots:   0 total
28Time:        0.13 s, estimated 1 s
29Ran all test suites matching /home/ag-sayyed/Documents/projects/vscode-setups/vscode-jest-tdd-cSpell/__tests__/spellcheck\.test\.js with tests matching "CSpell Configuration cspell\.config\.yaml exists and is valid$".

The test fails as expected. To make the test pass, rename the file back to its original name and watchAll settings will pickup the changes. This time it should pass. You can make a note on many different places that it passes.

  1. In the Test Results panel at the bottom of VS Code window.
  2. In the terminal output.
  3. In the Jest output panel, and If you have Jest extension installed, you will see a green check mark next to the test name in the test explorer.
  4. In the gutter of the test file, next to the test name, a round green circle with a check mark will appear.
1 PASS  __tests__/spellcheck.test.js
2  CSpell Configuration
3    ✓ cspell.config.yaml exists and is valid (3 ms)

Step - 4

Add More Tests

Write more test to make sure that required setup meets the criteria and if it fails the test starts to fail and you get alerted. Add following tests.

  1. Ensure dictionary project-word.txt exist.
  2. Ensure that test can be run and use cspell commands.
  3. Test correct docs without spelling errors, and make sure it detects no errors.
  4. Test incorrect docs with spelling errors, and make sure it detects errors.
  5. Test to check if specific words are ignored.
  6. Test custom dictionary words are recognized.

Once the tests are written, run the tests to see if they pass or fail. If they fail, fix the issues and run the tests again. Repeat this process until all tests pass. Here is the TEST RESULTS panel output after adding all the tests and making sure they pass.

 1 TestRun "[vscode-jest-tdd-cSpell] watch-all-tests:4:scheduled:4 (6)" started
 2 PASS  __tests__/spellcheck.test.js
 3  CSpell Configuration
 4    ✓ cspell.config.yaml exists and is valid (4 ms)
 5    ✓ project-words.txt exists in .vscode directory
 6    ✓ can run cspell command with configuration (403 ms)
 7  Valid Documents
 8    ✓ should pass spell check on well-formed documents (949 ms)
 9  Documents With Spelling Errors
10    ✓ should detect spelling errors in test-errors.md (954 ms)
11    ✓ should detect spelling errors in spell.md (965 ms)
12  Custom Dictionary
13    ✓ should recognize custom words added to project dictionary (950 ms)
14  Ignore Patterns
15    ✓ cspell configuration has ignore patterns defined (1 ms)
16    ○ skipped should ignore specified patterns in content
17
18Test Suites: 1 passed, 1 total
19Tests:       1 skipped, 8 passed, 9 total
20Snapshots:   0 total
21Time:        4.503 s, estimated 5 s
22Ran all test suites.PASS  __tests__/

Conclusion


FAQs