[angular] How to execute only one test spec with angular-cli

I have Angular2 project build with Angular-CLI (beta 20).

Is there a way to run tests against only one selected spec file?

I used to have a project based on Angular2 quick start, and I could manually add specs to jasmine file. But I don't know how to set this up outside of karma testing or how to limit karma tests to specific files with Angular-CLI builds.

This question is related to angular jasmine angular-cli

The answer is


Adding to this for people like me who were searching for a way to run a single spec in Angular and found this SO.

According to the latest Angular docs (v9.0.6 at time of writing), the ng test command has an --include option where you can specify a directory of *.spec.(ts|tsx) files or just a single .spec.(ts|tsx) file itself.

https://angular.io/cli/test


Configure test.ts file inside src folder:

const context = require.context('./', true, /\.spec\.ts$/);

Replace /\.spec\.ts$/ with the file name you want to test. For example: /app.component\.spec\.ts$/

This will run test only for app.component.spec.ts.


This is working for me in Angular 7. It is based on the --main option of the ng command. I am not sure if this option is undocumented and possibly subject to change, but it works for me. I put a line in my package.json file in scripts section. There using the --main option of with the ng test command, I specify the path to the .spec.ts file I want to execute. For example

"test 1": "ng test --main E:/WebRxAngularClient/src/app/test/shared/my-date-utils.spec.ts",

You can run the script as you run any such script. I run it in Webstorm by clicking on "test 1" in the npm section.


Just small change need in test.ts file inside src folder:

const context = require.context('./', true, /test-example\.spec\.ts$/);

Here, test-example is the exact file name which we need to run

In the same way, if you need to test the service file only you can replace the filename like "/test-example.service"


In a bash terminal I like to use the double dash. Using VS Code, you can right click on the spec file in the explorer, or on the open tab. Then select 'Copy Relative Path'. Run the command below pasting the relative path in from the clipboard.

npm t -- --include relative/path/to/file.spec.ts

The double dash signals the end of your command options for npm t and passes anything after that to the next command which is pointing to ng t. It's doesn't require any modification and quickly gives desired results.


If you want to be able to control which files are selected from the command line, I managed to do this for Angular 7.

In summary, you need to install @angular-devkit/build-angular:browser and then create a custom webpack plugin to pass the test file regex through. For example:

angular.json - change the test builder from @angular-devkit/build-angular:browser and set a custom config file:

...

        "test": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./extra-webpack.config.js"
            },
...

extra-webpack.config.js - create a webpack configuration that reads the regex from the command line:

const webpack = require('webpack');
const FILTER = process.env.KARMA_FILTER;
let KARMA_SPEC_FILTER = '/.spec.ts$/';
if (FILTER) {
  KARMA_SPEC_FILTER = `/${FILTER}.spec.ts$/`;
}
module.exports = {
  plugins: [new webpack.DefinePlugin({KARMA_SPEC_FILTER})]
}

test.ts - edit the spec

...
// Then we find all the tests.
declare const KARMA_CONTEXT_SPEC: any;
const context = require.context('./', true, KARMA_CONTEXT_SPEC);

Then use as follows to override the default:

KARMA_FILTER='somefile-.*\.spec\.ts$' npm run test

I documented the backstory here, apologies in advance for types and mis-links. Credit to the answer above by @Aish-Anu for pointing me in the right direction.


I solved this problem for myself using grunt. I have the grunt script below. What the script does is takes the command line parameter of the specific test to run and creates a copy of test.ts and puts this specific test name in there.

To run this, first install grunt-cli using:

npm install -g grunt-cli

Put the below grunt dependencies in your package.json:

"grunt": "^1.0.1",
"grunt-contrib-clean": "^1.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-exec": "^2.0.0",
"grunt-string-replace": "^1.3.1"

To run it save the below grunt file as Gruntfile.js in your root folder. Then from command line run it as:

grunt --target=app.component

This will run app.component.spec.ts.

Grunt file is as below:

/*
This gruntfile is used to run a specific test in watch mode. Example: To run app.component.spec.ts , the Command is: 
grunt --target=app.component
Do not specific .spec.ts. If no target is specified it will run all tests.
*/
module.exports = function(grunt) {
var target = grunt.option('target') || '';
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    clean: ['temp.conf.js','src/temp-test.ts'],
    copy: {
      main: {
        files: [
             {expand: false, cwd: '.', src: ['karma.conf.js'], dest: 'temp.conf.js'},
             {expand: false, cwd: '.', src: ['src/test.ts'], dest: 'src/temp-test.ts'}
             ],
      }
    },
    'string-replace': {
          dist: {
            files: {
              'temp.conf.js': 'temp.conf.js',
              'src/temp-test.ts': 'src/temp-test.ts'
            },
            options: {
              replacements: [{
                pattern: /test.ts/ig,
                replacement: 'temp-test.ts'
              },
              {
                pattern: /const context =.*/ig,
                replacement: 'const context = require.context(\'./\', true, /'+target+'\\\.spec\\\.ts$/);'
              }]
            }
        }
    },
    'exec': {
        sleep: {
          //The sleep command is needed here, else webpack compile fails since it seems like the files in the previous step were touched too recently
          command: 'ping 127.0.0.1 -n 4 > nul',
          stdout: true,
          stderr: true
        },
        ng_test: {
          command: 'ng test --config=temp.conf.js',
          stdout: true,
          stderr: true
        }
    }
  });

  // Load the plugin that provides the "uglify" task.
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-string-replace');
    grunt.loadNpmTasks('grunt-exec');
  // Default task(s).
  grunt.registerTask('default', ['clean','copy','string-replace','exec']);

};

This worked for me in every case:

ng test --include='**/dealer.service.spec.ts'

However, I usually got "TypeError: Cannot read property 'ngModule' of null" for this:

ng test --main src/app/services/dealer.service.spec.ts

Version of @angular/cli 10.0.4


You can test only specific file with the Angular CLI (the ng command) like this:

ng test --main ./path/to/test.ts

Further docs are at https://angular.io/cli/test

Note that while this works for standalone library files, it will not work for angular components/services/etc. This is because angular files have dependencies on other files (namely src/test.ts in Angular 7). Sadly the --main flag doesn't take multiple arguments.


Examples related to angular

error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class error TS1086: An accessor cannot be declared in an ambient context in Angular 9 TS1086: An accessor cannot be declared in ambient context @angular/material/index.d.ts' is not a module Why powershell does not run Angular commands? error: This is probably not a problem with npm. There is likely additional logging output above Angular @ViewChild() error: Expected 2 arguments, but got 1 Schema validation failed with the following errors: Data path ".builders['app-shell']" should have required property 'class' Access blocked by CORS policy: Response to preflight request doesn't pass access control check origin 'http://localhost:4200' has been blocked by CORS policy in Angular7

Examples related to jasmine

How to execute only one test spec with angular-cli Unit testing click event in Angular Angular 2 Unit Tests: Cannot find name 'describe' How to write unit testing for Angular / TypeScript for private methods with Jasmine toBe(true) vs toBeTruthy() vs toBeTrue() How do I mock a service that returns promise in AngularJS Jasmine unit test? jasmine: Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL Jasmine JavaScript Testing - toBe vs toEqual Protractor : How to wait for page complete after click a button? How to spyOn a value property (rather than a method) with Jasmine

Examples related to angular-cli

Why powershell does not run Angular commands? ERROR in The Angular Compiler requires TypeScript >=3.1.1 and <3.2.0 but 3.2.1 was found instead Angular CLI Error: The serve command requires to be run in an Angular project, but a project definition could not be found Could not find module "@angular-devkit/build-angular" How to remove package using Angular CLI? How to set environment via `ng serve` in Angular 6 Error: Local workspace file ('angular.json') could not be found How do I deal with installing peer dependencies in Angular CLI? How to iterate using ngFor loop Map containing key as string and values as map iteration how to format date in Component of angular 5