Làm thế nào để chỉ thực hiện một thông số thử nghiệm với angular-cli


142

Tôi có bản dựng dự án Angular2 với Angular-CLI (beta 20).

Có cách nào để chạy thử nghiệm chỉ với một tệp spec được chọn không?

Tôi đã từng có một dự án dựa trên khởi động nhanh Angular2 và tôi có thể tự thêm thông số kỹ thuật vào tập tin hoa nhài. Nhưng tôi không biết làm thế nào để thiết lập điều này bên ngoài kiểm tra nghiệp hoặc cách giới hạn kiểm tra nghiệp lực vào các tệp cụ thể với các bản dựng Angular-CLI.

Câu trả lời:


224

Mỗi .spec.tstệp của bạn có tất cả các thử nghiệm được nhóm thành một describekhối như thế này:

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

Bạn có thể dễ dàng chạy chỉ một khối này, bằng cách thêm tiền tố vào describetên hàm f:

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

Nếu bạn có chức năng như vậy, không có describekhối khác sẽ chạy. Btw. bạn có thể làm điều tương tự với it=> fitvà đó cũng là phiên bản "danh sách đen" - x. Vì thế:

  • fdescribechỉfit gây ra các chức năng được đánh dấu theo cách này để chạy
  • xdescribexitgây ra tất cả trừ các chức năng được đánh dấu theo cách này để chạy

1
Tôi đã sử dụng fdescribe trong tệp helloworld.component.spec.ts của tôi nhưng các lỗi của tệp app.component.spec.ts cũng được hiển thị.
Master Yoda

1
Đó là bởi vì tất cả các mã đang được đánh giá (nếu không, nó sẽ không biết rằng có các mô tả trong các thử nghiệm của bạn) - fdescribe chỉ giới hạn các thử nghiệm thực hiện kết quả. Bạn vẫn cần sửa lỗi cú pháp / bản in trong các tệp khác.
Tomek Sułkowski

3
Tôi nghĩ mặc dù OP đã chấp nhận câu trả lời này nhưng câu hỏi được đặt ra là làm thế nào để chỉ đánh giá một tệp spec: P
roberto tomás

4
Đây không phải là câu trả lời. @iislucas có câu trả lời dưới đây.
Ben Racicot

Tôi có thể đặt một số cờ trong môi trường CI của mình sẽ không gặp phải fdescribehay xdescribekhông? Tôi không muốn một người đánh giá cẩu thả (tôi) hợp nhất một PR mà bỏ qua tất cả các bài kiểm tra của tôi.
ILikeFood

80

Cấu hình test.tstập tin bên trong srcthư mục:

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

Thay thế /\.spec\.ts$/bằng tên tập tin bạn muốn kiểm tra. Ví dụ:/app.component\.spec\.ts$/

Điều này sẽ chạy thử nghiệm chỉ cho app.component.spec.ts.


8
nên được chấp nhận câu trả lời, cách tiếp cận này sẽ loại bỏ một lượng đầu ra gumpfy trong các bản ghi - không giống như fdescribe là verbose
danday74

3
giải pháp dễ dàng :) tiết kiệm rất nhiều thời gian.
Detoxic-Soul 19/07/18

Điều này sẽ khớp các thành phần với bất kỳ thứ gì trước 'ứng dụng' vì vậy 'sản phẩm-app.component.spec.ts' hoặc 'order-app.component.spec.ts' cũng sẽ phù hợp. Tôi không phải là người giỏi nhất với regx. Có cách nào để nhắm mục tiêu cụ thể 'app.component.spec.ts' không?
hanesjw

Tôi đã thử / nôm na.component\.spec\.ts$/ nhưng không có may mắn. Có vẻ như để làm việc trong một thử nghiệm regex nhưng ng test không thích nó vì một số lý do; tạo ra một lỗi.
hanesjw

nên là câu trả lời được đề xuất
Anil Vangari

55

Bạn chỉ có thể kiểm tra tệp cụ thể với Angular CLI ( nglệnh) như thế này:

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

Các tài liệu khác có tại https://angular.io/cli/test

Lưu ý rằng trong khi điều này hoạt động cho các tệp thư viện độc lập, nó sẽ không hoạt động cho các thành phần / dịch vụ góc cạnh, v.v. Điều này là do các tệp góc có phụ thuộc vào các tệp khác (cụ thể là src/test.tstrong Angular 7). Đáng buồn là --maincờ không có nhiều đối số.


2
Đây là một gợi ý tuyệt vời và nó hoạt động. Cảm ơn bạn! Ngoài ra, đáng lưu ý rằng nếu chúng tôi thử và trỏ nó vào một component.spec.tstệp được tạo tự động , chúng tôi sẽ thấy rằng các thử nghiệm không bao giờ bắt đầu: 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... Tôi chắc chắn rằng cách khắc phục khác có thể bị hack cùng nhau nhưng đó là điều cần lưu ý bởi vì thiết lập được thực hiện trong src/main.tsvà nhập khẩu của nó không có sẵn trong trường hợp này.
pulkitsinghal

Khi tôi chạy toàn bộ các bài kiểm tra bằng cách sử dụng lệnh ng t, bài kiểm tra tôi đang viết nhưng khi tôi chạy tệp cụ thể thì nó báo lỗi. LoạiError: Không thể đọc thuộc tính 'getComponentFromError' của null tại TestBedViewEngine._init IfNeeded (node_modules/@angular/core/fesm2015/testing.js: 3112: 1) tại TestBedViewEm 3230: 1) tại Function.get (node_modules/@angular/core/fesm2015/testing.js: 2960: 1) tại UserContext. <Anonymous> (src / app / timebar.service.spec.ts: 14: 45) "
canbax

1
Câu trả lời này cũng có tác dụng với Angular 8. Đây phải là câu trả lời được chấp nhận vì nó sẽ chạy chính xác một tệp spec thử nghiệm.

2
Đối với Angular 9, tôi nhận được tùy chọn không xác định "- chính" :(
rmcsharry

6

Nếu bạn muốn có thể kiểm soát tập tin nào được chọn từ dòng lệnh, tôi đã quản lý để làm điều này cho Angular 7.

Tóm lại, bạn cần cài đặt @angular-devkit/build-angular:browservà sau đó tạo một plugin webpack tùy chỉnh để vượt qua regex tệp thử nghiệm thông qua. Ví dụ:

angular.json - thay đổi trình xây dựng thử nghiệm từ @angular-devkit/build-angular:browservà đặt tệp cấu hình tùy chỉnh:

...

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

Extra-webpack.config.js - tạo cấu hình webpack đọc regex từ dòng lệnh:

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 - chỉnh sửa thông số kỹ thuật

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

Sau đó sử dụng như sau để ghi đè mặc định:

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

Tôi đã ghi lại các câu chuyện lạc hậu ở đây , xin lỗi trước về các loại và liên kết sai. Tín dụng cho câu trả lời ở trên của @ Aish-Anu vì đã chỉ cho tôi đi đúng hướng.


4

Điều này làm việc với tôi trong Angular 7. Nó dựa trên tùy chọn --main của lệnh ng. Tôi không chắc chắn nếu tùy chọn này không có giấy tờ và có thể thay đổi, nhưng nó hoạt động với tôi. Tôi đặt một dòng trong tệp pack.json trong phần script. Ở đó, sử dụng tùy chọn --main của lệnh ng test, tôi chỉ định đường dẫn đến tệp .spec.ts mà tôi muốn thực thi. Ví dụ

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

Bạn có thể chạy tập lệnh khi bạn chạy bất kỳ tập lệnh nào. Tôi chạy nó trong Webstorm bằng cách nhấp vào "test 1" trong phần npm.


3

Tôi đã giải quyết vấn đề này cho bản thân bằng cách sử dụng grunt. Tôi có kịch bản grunt dưới đây. Những gì tập lệnh thực hiện là lấy tham số dòng lệnh của thử nghiệm cụ thể để chạy và tạo một bản sao của test.ts và đặt tên thử nghiệm cụ thể này vào đó.

Để chạy cái này, trước tiên hãy cài đặt grunt-cli bằng cách sử dụng:

npm install -g grunt-cli

Đặt các phụ thuộc lẩm cẩm dưới đây trong gói.json của bạn:

"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"

Để chạy nó, hãy lưu tệp grunt dưới đây dưới dạng Gruntfile.js trong thư mục gốc của bạn. Sau đó, từ dòng lệnh chạy nó như:

grunt --target=app.component

Điều này sẽ chạy app.component.spec.ts.

Tập tin Grunt như sau:

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

};

Nhìn vào giải pháp được chấp nhận, tôi không nghĩ cách này được khuyến nghị
Drenai 17/12/17

2
@Brian - Giải pháp của tôi tránh phải sửa đổi mã nguồn và do đó ngăn ngừa các lỗi tiềm ẩn trong việc kiểm tra tệp. Giải pháp của tôi cho phép chỉ định tên thử nghiệm trên dòng lệnh bằng cách tự động hóa các bước thủ công.
vanval

Vâng, đó thực sự là một điểm tốt. Có một cơ hội tốt mà bạn có thể quên xóa xdescribe hoặc fdescribe - và bài kiểm tra của bạn sẽ được xóa hoàn toàn!
Drenai

3
@Ryan bạn có thể cài đặt / cấu hình quy tắc tslint-jasmine để kiểm tra các cuộc gọi fdescribe / fit / xdescribe / xit và không chạy tslint của bạn; nếu đây là một phần của bước khởi đầu, nó sẽ ngăn bạn vô tình kiểm tra các bài kiểm tra của mình hoặc tập trung hoặc bị vô hiệu hóa.
Neil Menzies

1

Thêm vào điều này cho những người như tôi, những người đang tìm cách chạy một thông số kỹ thuật duy nhất trong Angular và tìm thấy SO này.

Theo các tài liệu Angular mới nhất (v9.0.6 tại thời điểm viết), ng testlệnh có một --includetùy chọn trong đó bạn có thể chỉ định một thư mục của *.spec.(ts|tsx)các tệp hoặc chỉ một.spec.(ts|tsx) tệp .

https://angular.io/cli/test


0

Chỉ cần thay đổi nhỏ trong test.tstệp trong thư mục src:

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

Đây, test-example là tên tệp chính xác mà chúng ta cần chạy

Theo cách tương tự, nếu bạn chỉ cần kiểm tra tệp dịch vụ, bạn có thể thay thế tên tệp như "/test-example.service"


0

Điều này làm việc cho tôi trong mọi trường hợp:

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

Tuy nhiên, tôi thường nhận được "TypeError: Không thể đọc thuộc tính 'ngModule' của null" cho điều này:

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

Phiên bản @ angular / cli 10.0.4

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.