วิธีดำเนินการทดสอบ spec เพียงหนึ่งเดียวด้วย angular-cli


143

ฉันมีโครงการสร้าง Angular2 ด้วย Angular-CLI (เบต้า 20)

มีวิธีเรียกใช้การทดสอบกับไฟล์ spec เพียงไฟล์เดียวที่เลือกหรือไม่

ฉันเคยมีโครงการตามการเริ่มต้นอย่างรวดเร็วของ Angular2 และฉันสามารถเพิ่มรายละเอียดลงในไฟล์จัสมินด้วยตนเอง แต่ฉันไม่ทราบวิธีตั้งค่านอกการทดสอบกรรมหรือวิธี จำกัด การทดสอบกรรมให้กับไฟล์เฉพาะด้วย Angular-CLI builds

คำตอบ:


224

.spec.tsไฟล์ของคุณแต่ละไฟล์มีการทดสอบทั้งหมดที่จัดกลุ่มเป็นdescribeบล็อกดังนี้:

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

คุณสามารถเรียกใช้เพียงบล็อกเดียวนี้ได้อย่างง่ายดายโดยนำหน้าdescribeชื่อฟังก์ชันด้วยf:

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

หากคุณมีฟังก์ชั่นดังกล่าวจะไม่มีการdescribeบล็อกอื่น ๆ Btw คุณสามารถทำสิ่งที่คล้ายกันกับit=> fitและยังมีรุ่น "บัญชีดำ" x- ดังนั้น:

  • fdescribeและfitทำให้เกิดเฉพาะฟังก์ชันที่ทำเครื่องหมายด้วยวิธีนี้เพื่อให้ทำงานได้
  • xdescribeและxitทำให้ทั้งหมดยกเว้นฟังก์ชั่นที่ทำเครื่องหมายด้วยวิธีนี้ในการทำงาน

1
ฉันใช้ fdescribe ในไฟล์ helloworld.component.spec.ts ของฉันแล้ว แต่ข้อผิดพลาดของไฟล์ app.component.spec.ts ก็แสดงขึ้นเช่นกัน
ปริญญาโทโยดา

1
นั่นเป็นเพราะรหัสทั้งหมดจะถูกประเมิน (มิฉะนั้นจะไม่ทราบว่ามี fdescribes ในการทดสอบของคุณ) - fdescribe จำกัด การดำเนินการผลการทดสอบเท่านั้น คุณยังต้องแก้ไขข้อผิดพลาดทางไวยากรณ์ / ตัวพิมพ์ในไฟล์อื่น ๆ
Tomek Sułkowski

3
ฉันคิดว่าถึงแม้ว่า OP ยอมรับคำตอบนี้คำถามก็คือวิธีการประเมินไฟล์ spec เพียงไฟล์เดียว: P
roberto tomás

4
นี่ไม่ใช่คำตอบ @iislucas มีคำตอบด้านล่าง
Ben Racicot

ฉันสามารถตั้งค่าสถานะบางอย่างในสภาพแวดล้อม CI ของฉันที่จะล้มเหลวในการเผชิญหน้าfdescribeหรือxdescribe? ฉันไม่ต้องการให้ผู้วิจารณ์เลอะเทอะ (ฉัน) รวม PR ที่ข้ามการทดสอบทั้งหมดของฉัน
ILikeFood

81

กำหนดค่าtest.tsไฟล์ภายในsrcโฟลเดอร์:

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

แทนที่/\.spec\.ts$/ด้วยชื่อไฟล์ที่คุณต้องการทดสอบ ตัวอย่างเช่น:/app.component\.spec\.ts$/

app.component.spec.tsนี้จะทำงานเฉพาะสำหรับการทดสอบ


8
ควรได้รับการยอมรับคำตอบวิธีการนี้จะลบโหลดของเอาต์พุต gumpfy ในบันทึก - ซึ่งแตกต่างจาก fdescribe ซึ่งเป็น verbose
danday74

3
วิธีแก้ปัญหาง่าย ๆ :) ประหยัดเวลาได้มาก
Detoxic-Soul

สิ่งนี้จะจับคู่ส่วนประกอบกับสิ่งใด ๆ ก่อน 'แอป' ดังนั้น 'product-app.component.spec.ts' หรือ 'order-app.component.spec.ts' ก็จะเป็นการจับคู่ ฉันไม่ได้ยิ่งใหญ่ที่สุดกับ regx มีวิธีการกำหนดเป้าหมายเป็นพิเศษ 'app.component.spec.ts' หรือไม่
hanesjw

ฉันลอง /^app.component\.spec\.ts$/ แต่ก็ไม่มีโชค ดูเหมือนว่าจะทำงานในผู้ทดสอบ regex แต่การทดสอบ ng ไม่ชอบด้วยเหตุผลบางอย่าง; สร้างข้อผิดพลาด
hanesjw

ควรเป็นคำตอบที่แนะนำ
Anil Vangari

55

คุณสามารถทดสอบเฉพาะไฟล์ได้ด้วยAngular CLI ( ngคำสั่ง) ดังนี้:

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: ไม่สามารถอ่านคุณสมบัติ 'getComponentFromError' เป็นโมฆะที่ TestBedViewEngine._initIfNeeded (node_modules/@angular/core/fesm2015/testing.js: 3112: 1) ที่ TestBedViewEngine.get 3230: 1) ที่ Function.get (node_modules/@angular/core/fesm2015/testing.js: 2960: 1) ที่ UserContext <anonymous> (src / app / timebar.service.spec.ts: 14: 45) "
canbax

1
คำตอบนี้ใช้ได้กับ Angular 8 ด้วย นี่ควรเป็นคำตอบที่ได้รับการยอมรับเพราะมันจะเรียกใช้ไฟล์ทดสอบหนึ่งไฟล์

2
สำหรับ Angular 9 ฉันได้รับตัวเลือกที่ไม่รู้จัก "- หลัก" :(
rmcsharry

6

หากคุณต้องการควบคุมไฟล์ที่เลือกจากบรรทัดคำสั่งฉันสามารถจัดการกับ Angular 7 ได้

โดยสรุปคุณจะต้องติดตั้ง@angular-devkit/build-angular:browserและสร้างปลั๊กอินเว็บแพ็คที่กำหนดเองเพื่อส่งไฟล์ทดสอบ 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ที่อ่าน regex จากบรรทัดคำสั่ง:

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 ที่นี่ขอโทษล่วงหน้าสำหรับประเภทและลิงค์ผิด ๆ ให้เครดิตกับคำตอบข้างต้นโดย @ Aish-Anu เพื่อชี้ให้ฉันไปในทิศทางที่ถูกต้อง


4

สิ่งนี้ใช้ได้กับฉันใน Angular 7 ซึ่งขึ้นอยู่กับตัวเลือก - หลักของคำสั่ง ng ฉันไม่แน่ใจว่าตัวเลือกนี้ไม่มีเอกสารและอาจมีการเปลี่ยนแปลง แต่มันใช้ได้กับฉัน ฉันใส่บรรทัดในไฟล์ package.json ของฉันในส่วนของสคริปต์ มีการใช้ตัวเลือก - หลักของด้วยคำสั่งทดสอบ ng ฉันระบุเส้นทางไปยังไฟล์. spec.ts ฉันต้องการที่จะดำเนินการ ตัวอย่างเช่น

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

คุณสามารถเรียกใช้สคริปต์ในขณะที่คุณเรียกใช้สคริปต์ดังกล่าว ฉันเรียกใช้ใน Webstorm โดยคลิกที่ "ทดสอบ 1" ในส่วน npm


3

ฉันแก้ไขปัญหานี้ด้วยตัวเองโดยใช้เสียงฮึดฮัด ฉันมีสคริปต์เสี้ยงฮึดฮัดแสดงความไม่พอใจด้านล่าง สิ่งที่สคริปต์ทำคือใช้พารามิเตอร์บรรทัดคำสั่งของการทดสอบเฉพาะเพื่อเรียกใช้และสร้างสำเนาของ test.ts และใส่ชื่อการทดสอบนี้ไว้ในนั้น

ในการรันสิ่งนี้ก่อนอื่นให้ติดตั้ง grunt-cli โดยใช้:

npm install -g grunt-cli

ใส่การอ้างอิงเสียงฮึดฮัดด้านล่างใน 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']);

};

ดูวิธีแก้ปัญหาที่ยอมรับฉันไม่คิดว่าวิธีนี้จะแนะนำ
Drenai

2
@Brian - โซลูชันของฉันหลีกเลี่ยงการแก้ไขซอร์สโค้ดดังนั้นจึงป้องกันข้อผิดพลาดที่อาจเกิดขึ้นในการตรวจสอบไฟล์ โซลูชันของฉันเปิดใช้งานเพียงแค่ระบุชื่อทดสอบในบรรทัดคำสั่งโดยทำตามขั้นตอนแบบแมนนวลโดยอัตโนมัติ
vanval

ใช่ว่าเป็นจุดที่ดีจริง มีโอกาสที่ดีที่คุณสามารถลืมที่จะลบ xdescribe หรือ fdescribe - และการทดสอบของคุณจะถูกลบออกอย่างไม่สม่ำเสมอ!
Drenai

3
@Ryan คุณสามารถติดตั้ง / กำหนดค่า tslint-jasmine-rules เพื่อตรวจสอบการโทร fdescribe / fit / xdescribe / xit และล้มเหลวในการรัน tslint ของคุณ; หากนี่เป็นส่วนหนึ่งของขั้นตอน precommit จะเป็นการป้องกันการตรวจสอบโดยไม่ตั้งใจของคุณไม่ว่าจะเป็นแบบมุ่งเน้นหรือปิดการใช้งาน
Neil Menzies

1

การเพิ่มสิ่งนี้สำหรับคนอย่างฉันที่กำลังค้นหาวิธีเรียกใช้ข้อมูลจำเพาะเดี่ยวใน Angular และพบ SO นี้

ตามเอกสาร Angular ล่าสุด (v9.0.6 ณ เวลาที่เขียน) ng testคำสั่งมี--includeตัวเลือกที่คุณสามารถระบุไดเรกทอรีของ*.spec.(ts|tsx)ไฟล์หรือเพียงแค่.spec.(ts|tsx)ไฟล์เดียว

https://angular.io/cli/test


0

ต้องการการเปลี่ยนแปลงเพียงเล็กน้อยในtest.tsไฟล์ภายในโฟลเดอร์ src:

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

นี่test-exampleคือชื่อไฟล์ที่แน่นอนที่เราต้องเรียกใช้

ในทำนองเดียวกันหากคุณต้องการทดสอบไฟล์บริการเพียงอย่างเดียวคุณสามารถแทนที่ชื่อไฟล์เช่น "/test-example.service"


0

สิ่งนี้ใช้ได้กับฉันในทุกกรณี:

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

อย่างไรก็ตามฉันมักจะได้รับ "TypeError: ไม่สามารถอ่านคุณสมบัติ 'ngModule' เป็นโมฆะ" ได้:

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

รุ่นของ @ angular / cli 10.0.4

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.