如何使用angular-cli仅执行一个测试规范


142

我有使用Angular-CLI(beta 20)构建的Angular2项目。

有没有一种方法可以仅对一个选定的规格文件运行测试?

我曾经有一个基于Angular2快速入门的项目,并且可以手动将规格添加到jasmine文件中。但是我不知道如何在业力测试之外进行设置,或者如何使用Angular-CLI构建将业力测试限制在特定文件中。

Answers:


224

每个.spec.ts文件都将其所有测试分组在describe块中,如下所示:

describe('SomeComponent', () => {...}

您可以通过在describe函数名称前添加前缀来轻松运行此单个块f

fdescribe('SomeComponent', () => {...}

如果具有此功能,则不会describe运行其他任何块。顺便说一句。您可以使用it=> 做类似的事情,fit并且还有一个“黑名单”版本- x。所以:

  • fdescribefit导致以这种方式标记的功能运行
  • xdescribexit导致所有以这种方式标记的功能运行

1
我在helloworld.component.spec.ts文件中使用了fdescribe,但同时也显示了app.component.spec.ts文件的错误。
尤达大师

1
那是因为所有代码都正在评估中(否则它将不知道测试中包含fdescribes)-fdescribe仅限制测试结果的执行。您还需要修复其他文件中的语法/打字错误。
TomekSułkowski18年

3
我认为,尽管OP接受了这个答案,但问题是,严格来说,如何只评估一个规格文件:P
robertotomás19

4
这不是答案。@iislucas有下面的答案。
Ben Racicot

我可以在CI环境中设置一些标志,如果遇到该标志将失败fdescribexdescribe?我不希望草率的审阅者(me)合并跳过所有测试的PR。
ILikeFood

80

配置test.ts文件src夹中的文件:

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

/\.spec\.ts$/您要测试的文件名替换。例如:/app.component\.spec\.ts$/

这只会针对进行测试app.component.spec.ts


8
应该被接受的答案,这种方法消除了日志中gumppy的输出负载-不像fdescribe那样冗长
danday74 '18

3
简单的解决方法:)节省了大量时间。
Detoxic-Soul

这将使组件与“ app”之前的任何内容匹配,因此“ product-app.component.spec.ts”或“ order-app.component.spec.ts”也将匹配。我不是regx的佼佼者。有没有一种方法专门针对'app.component.spec.ts'?
hanesjw

我尝试了/^app.component\.spec\.ts$/,但是没有运气。似乎可以在正则表达式测试器中工作,但是ng test由于某种原因不喜欢它。产生一个错误。
hanesjw '19

应该是推荐的答案
Anil Vangari

55

您可以使用Angular CLIng命令)仅测试特定文件,如下所示:

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

更多文档位于https://angular.io/cli/test

请注意,虽然这适用于独立库文件,但不适用于有角度的组件/服务/等。这是因为有角度的文件依赖于其他文件(即src/test.ts在Angular 7中)。遗憾的是,该--main标志没有多个参数。


2
这是一个很好的建议,并且有效。谢谢!另外值得一提的是,如果我们尝试将其指向一个自动生成的component.spec.ts文件,我们将看到测试永远不会启动:Error: AsyncTestZoneSpec is needed for the async() test helper but could not be found. Please make sure that your environment includes zone.js/dist/async-test.js...我敢肯定,可以将其他解决方法结合在一起,但这是需要注意的这是因为src/main.ts在这种情况下无法进行内部设置及其导入。
pulkitsinghal

当我使用命令运行整个测试时ng t,我正在编写的测试通过了,但是当我运行特定文件时,它给出了错误。TypeError:在TestBedViewEngine.get(node_modules/@angular/core/fesm2015/testing.js: 3230:1)在UserContext上的Function.get(node_modules/@angular/core/fesm2015/testing.js:2960:1)。<匿名>(src / app / timebar.service.spec.ts:14:45)”
canbax

1
这个答案也适用于Angular 8。这应该是可接受的答案,因为它将仅运行一个测试规范文件。

2
对于Angular 9,我得到了未知选项“
--main

6

如果您希望能够控制从命令行中选择了哪些文件,我设法对Angular 7进行了此操作。

总之,您需要安装 @angular-devkit/build-angular:browser然后创建自定义Webpack插件以通过测试文件regex。例如:

angular.json-从更改测试生成器@angular-devkit/build-angular:browser并设置自定义配置文件:

...

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

extra-webpack.config.js-创建一个从命令行读取正则表达式的webpack配置:

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-编辑规格

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

然后使用以下命令覆盖默认值:

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

我在这里记录了背景故事,对于类型和错误链接,我们事先表示歉意。感谢@ Aish-Anu的上述回答,指出了我的正确方向。


4

这在Angular 7中对我有用。它基于ng命令的--main选项。我不确定此选项是否未记录并且可能会更改,但是它对我有用。我在脚本部分的package.json文件中添加了一行。在使用ng test命令的--main选项时,我指定了要执行的.spec.ts文件的路径。例如

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

您可以在运行任何此类脚本时运行该脚本。我在Webstorm中通过单击npm部分中的“测试1”来运行它。


3

我自己用咕solved声解决了这个问题。我有下面的咕unt声脚本。该脚本的作用是运行特定测试的命令行参数,并创建一个test.ts副本,并将该特定测试名称放入其中。

要运行此程序,请首先使用以下命令安装grunt-cli:

npm install -g grunt-cli

将以下grunt依赖项放入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"

要运行它,请将以下grunt文件另存为root文件夹中的Gruntfile.js。然后从命令行运行它为:

grunt --target=app.component

这将运行app.component.spec.ts。

Grunt文件如下:

/*
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']);

};

考虑到公认的解决方案,我不建议采用这种方式
Drenai

2
@Brian-我的解决方案避免了必须修改源代码,从而避免了在检入文件时可能出现的错误。我的解决方案允许通过自动执行手动步骤在命令行上指定测试名称。
vanval

是的,实际上这是一个好主意。您很有可能忘记删除xdescribe或fdescribe-而测试将被永久删除!
德雷奈'17

3
@Ryan,您可以安装/配置tslint-jasmine-rules来检查fdescribe / fit / xdescribe / xit调用并导致tslint无法运行;如果这是预提交步骤的一部分,则可以防止您意外检查集中或禁用的测试。
尼尔·孟席斯

1

对于像我这样的人,他们正在寻找一种方法来在Angular中运行单个规范并找到了这种SO,这也增加了这一点。

根据最新的Angular文档(撰写本文时为v9.0.6),该ng test命令具有一个--include选项,您可以在其中指定*.spec.(ts|tsx)文件目录或仅指定一个.spec.(ts|tsx)文件本身。

https://angular.io/cli/test


0

只需对test.tssrc文件夹中的文件进行少量更改即可:

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

这里, test-example是我们需要运行的确切文件名

同样,如果只需要测试服务文件,则可以替换文件名,例如“ /test-example.service”


0

这在每种情况下都对我有用:

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

但是,我通常为此收到“ TypeError:无法读取null的属性'ngModule'”:

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

@ angular / cli 10.0.4的版本

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.