【问题标题】:How to execute only one test spec with angular-cli如何使用 angular-cli 只执行一个测试规范
【发布时间】:2017-04-02 16:39:00
【问题描述】:

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

有没有办法只针对一个选定的规范文件运行测试?

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

【问题讨论】:

    标签: angular jasmine angular-cli


    【解决方案1】:

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

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

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

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

    如果你有这样的功能,其他describe 块将不会运行。 顺便提一句。你可以用it => fit 做类似的事情,还有一个“黑名单”版本 - x。所以:

    • fdescribefit 导致标记为这种方式的函数运行
    • xdescribexit 导致除了所有标记为这种方式的函数运行

    【讨论】:

    • 我在 helloworld.component.spec.ts 文件中使用了 fdescribe,但也显示了 app.component.spec.ts 文件的错误。
    • 那是因为所有代码都在被评估(否则它不会知道你的测试中有 fdescribes) - fdescribe 只限制测试结果的执行。您仍然需要修复其他文件中的语法/打字稿错误。
    • 我认为尽管 OP 接受了这个答案,但问题实际上是如何只评估一个规范文件:P
    • 这不是答案。 @iislucas 的答案如下。
    • 我能否在我的 CI 环境中设置一些在遇到 fdescribexdescribe 时会失败的标志?我不希望一个草率的审稿人(我)合并一个跳过我所有测试的 PR。
    【解决方案2】:

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

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

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

    这将仅为app.component.spec.ts 运行测试。

    【讨论】:

    • 应该被接受的答案,这种方法消除了日志中的大量 gumpfy 输出 - 不像 fdescribe 那样冗长
    • 简单的解决方案 :) 节省了大量时间。
    • 这会将组件与“app”之前的任何内容匹配,因此“product-app.component.spec.ts”或“order-app.component.spec.ts”也将是匹配的。我不是最擅长 regx 的。有没有办法专门针对“app.component.spec.ts”?
    • 我试过 /^app.component\.spec\.ts$/ 但没有运气。似乎在正则表达式测试器中工作,但 ng test 由于某种原因不喜欢它;产生错误。
    • 应该是推荐的答案
    【解决方案3】:

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

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

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

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

    【讨论】:

    • 这是一个很好的建议,而且很有效。谢谢!此外值得一提的是,如果我们尝试将其指向自动生成的 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 中完成的设置及其导入在这种情况下不可用。
    • 当我使用命令ng t 运行整个测试时,我正在编写的测试通过了,但是当我运行特定文件时它给出了错误。 TypeError:无法在 TestBedViewEngine._initIfNeeded (node_modules/@angular/core/fesm2015/testing.js:3112:1) 处读取属性 'getComponentFromError' 在 TestBedViewEngine.get (node_modules/@angular/core/fesm2015/testing.js: 3230:1) 在 Function.get (node_modules/@angular/core/fesm2015/testing.js:2960:1) 在 UserContext. (src/app/timebar.service.spec.ts:14:45)"
    • 这个答案也适用于 Angular 8。这应该是公认的答案,因为它将只运行一个测试规范文件。
    • 对于 Angular 9,我得到未知选项“--main” :(
    • 与@pulkitsinghal Error: AsyncTestZoneSpec is needed for the async() 有相同的问题,但在命令中将--main 更改为--include 解决了错误并只执行了该测试。
    【解决方案4】:

    这在任何情况下都对我有用:

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

    但是,我通常会为此收到“TypeError: Cannot read property 'ngModule' of null”:

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

    @angular/cli 10.0.4 的版本

    【讨论】:

    • 仅供参考:甚至可以使用更复杂的通配符。无论如何,请确保您的地址为*.spec.ts。例如。要仅运行共享文件夹的测试或在 src/app 中搜索,请使用 ng test --include='src/app/{shared,search}/*.spec.ts'
    • 你可能还需要像--karma-config karma.conf.js这样指定业力配置文件,否则它会尝试从src/而不是根路径加载配置文件。
    • 这在 Angular CLI:9.1.13 上就像一个魅力......谢谢!
    • 有趣,它在 Windows 10 上不适合我。
    【解决方案5】:

    使用--include

    它适用于--include

    ng test --include src/app/path-to-component/path-component.component.spec.ts
    

    我尝试了--main,但它显示了所有失败结果,而事实并非如此。我认为--main 将更改主要的test.ts 文件。

    【讨论】:

      【解决方案6】:

      如果您希望能够控制从命令行选择哪些文件,我设法为 Angular 7 做到了这一点。

      总的来说,你需要安装@angular-devkit/build-angular:browser,然后创建一个自定义的webpack插件来传递测试文件正则表达式。例如:

      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
      

      我记录了backstory here,提前为类型和错误链接道歉。感谢@Aish-Anu 为我指出正确方向的上述答案。

      【讨论】:

        【解决方案7】:

        在 bash 终端中,我喜欢使用双破折号。使用 VS Code,您可以右键单击资源管理器中的规范文件,或在打开的选项卡上。然后选择“复制相对路径”。运行下面的命令,从剪贴板粘贴相对路径。

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

        双破折号表示npm t 的命令选项结束,并将之后的任何内容传递给指向ng t 的下一个命令。它不需要任何修改,很快就能得到想要的结果。

        【讨论】:

          【解决方案8】:

          这在 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",
          

          您可以像运行任何此类脚本一样运行该脚本。我通过单击 npm 部分中的“test 1”在 Webstorm 中运行它。

          【讨论】:

            【解决方案9】:

            我使用 grunt 为自己解决了这个问题。我有下面的 grunt 脚本。脚本所做的是获取特定测试的命令行参数来运行,并创建一个 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 文件作为 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']);
            
            };
            

            【讨论】:

            • 看接受的方案,我觉得不推荐这种方式
            • @Brian - 我的解决方案避免了修改源代码,从而防止了签入文件时的潜在错误。我的解决方案通过自动执行手动步骤,只需在命令行上指定测试名称。
            • 是的,这实际上是一个好点。您很有可能忘记删除 xdescribe 或 fdescribe - 您的测试将被永久删除!
            • @Ryan 您可以安装/配置 tslint-jasmine-rules 以检查 fdescribe/fit/xdescribe/xit 调用并让您的 tslint 运行失败;如果这是预提交步骤的一部分,它可以防止您意外签入集中或禁用的测试。
            【解决方案10】:

            为像我这样正在寻找在 Angular 中运行单个规范并找到此 SO 的方法的人添加此内容。

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

            https://angular.io/cli/test

            【讨论】:

              【解决方案11】:

              一个简单的方法是用f开始describe和所有it

              fdescribe('testecomponente', () => {
                fit('should create', () => {
                  //your code 
                }
                
              }
                
              

              【讨论】:

                【解决方案12】:

                只需在 src 文件夹内的 test.ts 文件中进行小改动:

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

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

                同理,如果你只需要测试服务文件,你可以将文件名替换为“/test-example.service”

                【讨论】:

                  【解决方案13】:

                  您可以从 angular-cli 运行此命令,测试将仅包含您想要的规范文件。

                  ng test --包含spec文件的路径

                  【讨论】:

                    猜你喜欢
                    • 2016-07-16
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-07-21
                    • 1970-01-01
                    相关资源
                    最近更新 更多