Description

While developing a typescript (TS) application, unit testing is needed. Also, unit tests are written in TS.

Jasmine is the test framework used to test TS code.

When TS applications depend on browser context and use global DOM objects like window or location then unit tests are executed in the browser with jasmine for browsers.

All files with unit tests are in spec folder, with *.spec.ts extension.

The structure of spec folder should be similar to the structure of src folder (where is code).

Jasmin for browsers configuration is in spec\support\jasmine-browser.json.

ES module is natively supported by the browser, so our unit test files should be transpiled from TS to JS as ES module with *.mjs extension.

Spec folder should have additional tsconfig.json configururation for esnext modules nad tsc -w will transpile from TS to JS with js extension.

Node script can change exntesion from js to mjs.

Unit tests are executed with npm test.

Pre req

  • .gitignore, git init; git add .; git commit
  • npm init
  • npm install --save-dev typescript
  • npx tsc --init
  • tsconfig.json
    {"compilerOptions":
    {"target": "esnext",
    "module": "esnext",
    "lib": ["es2016","dom"],
    "allowJs": true,
    "sourceMap": true,
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
    }
    }
  • npm install --save-dev webpack webpack-cli webpack-dev-server
  • npm install --save-dev ts-loader
  • webpack.config.js
    const path = require('path');
    module.exports = {
        entry: './src/index.ts',
        devtool: 'inline-source-map',
        module: {
            rules: [
                {
                    test: /\.tsx?$/,
                    use: 'ts-loader',
                    exclude: /node_modules/,
                    include: [
                        path.resolve(__dirname, "src")
                    ],
                },
            ],
        },
        resolve: {
            extensions: [ '.tsx', '.ts', '.js' ],
        },
        output: {
            filename: 'bundle.js',
            path: path.resolve(__dirname, 'dist'),
        },
    };
  • add script to package.json
    "build": "npx webpack --config=webpack.config.js"
    npm run build

tsconfig.js for spec folder

{
"compilerOptions": {
  "target": "ESNext",
  "module": "ESNext"
},
"include": [
  "./spec/**/*.ts"
]
}

Jasmine for browsers

  • npm install --save-dev jasmine-browser-runner jasmine-core @types/jasmine
  • jasmine-browser.json
    {  
      "srcDir": "src",
      "srcFiles": [
      ],
      "specDir": ".",
      "specFiles": [
        "spec/**/*.[sS]pec.?(m)js"
      ],
      "helpers": [
        "spec/helpers/**/*.?(m)js"
      ],
      "env": {
        "stopSpecOnExpectationFailure": false,
        "stopOnSpecFailure": false,
        "random": false
      },
      "browser": {
        "name": "firefox"
      }
    }
  • add script to package.json
    "test": "jasmine-browser-runner runSpecs"
    npm test

package.json scripts

  "scripts": {
  "test": "jasmine-browser-runner runSpecs",
  "test:watch": "concurrently -k \"tsc -w\" \"npm run js2mjs:watch\" \"jasmine-browser-runner\"",
  "test:browse": "open-cli http://localhost:8888 --wait -- chrome",
  "js2mjs:watch": "nodemon -e js --watch spec --exec \"npm run js2mjs:run\"",
  "js2mjs:run": "renamer --force --find /\\.js$/ --replace .mjs --path-element ext \"spec/!(support)**/*.*\""
}

More info

https://jasmine.github.io/pages/getting_started.html