Come eseguire solo una specifica di prova con angular-cli


143

Ho compilato il progetto Angular2 con Angular-CLI (beta 20).

Esiste un modo per eseguire i test su un solo file di specifiche selezionato?

Avevo un progetto basato sull'avvio rapido di Angular2 e potevo aggiungere manualmente le specifiche al file jasmine. Ma non so come impostarlo al di fuori dei test del karma o come limitare i test del karma a file specifici con build Angular-CLI.

Risposte:


224

Ognuno dei tuoi .spec.tsfile ha tutti i suoi test raggruppati in describeblocchi come questo:

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

Puoi facilmente eseguire solo questo singolo blocco, prefissando il describenome della funzione con f:

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

Se si dispone di tale funzione, non describeverranno eseguiti altri blocchi. Btw. puoi fare cose simili con it=> fite c'è anche una versione "blacklist" - x. Così:

  • fdescribee fitfa funzionare solo le funzioni contrassegnate in questo modo
  • xdescribee xitfa sì che tutte le funzioni tranne quelle contrassegnate in questo modo vengano eseguite

1
Ho usato fdescribe nel mio file helloworld.component.spec.ts ma vengono anche mostrati gli errori del file app.component.spec.ts.
— Master Yoda,

1
Questo perché tutto il codice viene valutato (altrimenti non saprebbe che ci sono fdescribes nei tuoi test) - fdescribe limita solo l'esecuzione dei risultati dei test. È necessario correggere errori di sintassi / dattiloscritto in altri file.
— Tomek Sułkowski,

3
Penso che sebbene l'OP abbia accettato questa risposta, la domanda era in realtà come valutare un solo file di specifiche: P
— roberto tomás,

4
Questa non è la risposta @iislucas ha la risposta qui sotto.
— Ben Racicot,

Posso impostare alcuni flag nel mio ambiente CI che non riescono a incontrarsi fdescribeo xdescribe? Non voglio che un recensore sciatto (io) unisca un PR che salta tutti i miei test.
— ILikeFood,

82

Configura test.tsfile all'interno della srccartella:

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

Sostituire /\.spec\.ts$/ con il nome del file che desideri testare. Per esempio:/app.component\.spec\.ts$/

Questo eseguirà il test solo per app.component.spec.ts.


8
dovrebbe essere accettata la risposta, questo approccio rimuove un carico di output gumpfy nei registri - a differenza di fdescribe che è
— prolisso

3
soluzione semplice :) risparmiato molto tempo.
— Detoxic-Soul

Questo abbinerà i componenti con qualsiasi cosa prima dell '"app", quindi anche "product-app.component.spec.ts" o "order-app.component.spec.ts" corrisponderebbero. Non sono il massimo con regx. Esiste un modo per indirizzare in modo specifico "app.component.spec.ts"?
— Hanesjw,

Ho provato /^app.component\.spec\.ts$/ ma senza fortuna. Sembra funzionare in un tester regex ma ng test non piace per qualche motivo; produce un errore.
— Hanesjw,

dovrebbe essere la risposta raccomandata
— Anil Vangari

55

Puoi testare solo file specifici con la CLI angolare (il ngcomando) in questo modo:

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

Ulteriori documenti sono disponibili su https://angular.io/cli/test

Si noti che mentre funziona per file di libreria autonomi, non funzionerà per componenti / servizi / ecc. Angolari. Questo perché i file angolari hanno dipendenze da altri file (in particolare src/test.tsin Angular 7). Purtroppo la --mainbandiera non accetta più argomenti.


2
Questo è un ottimo suggerimento e funziona. Grazie! Inoltre, vale la pena sapere che se proviamo a indicarlo su un component.spec.tsfile generato automaticamente , vedremo che i test non iniziano mai: 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... Sono sicuro che ulteriori soluzioni alternative possono essere hackerate insieme ma è qualcosa di cui essere consapevoli di perché l'installazione eseguita all'interno src/main.tse le sue importazioni non sono disponibili in questo caso.
— pulkitsinghal

Quando eseguo interi test usando il comando ng til test che sto scrivendo passa ma quando eseguo il file specifico dà errore. TypeError: impossibile leggere la proprietà 'getComponentFromError' di null su TestBedViewEngine._initIfNeeded (node_modules/@angular/core/fesm2015/testing.js: 3112: 1) su TestBedViewEngine.get (node_modules/@angular/core/fesjs015/tes.01) 3230: 1) su Function.get (node_modules/@angular/core/fesm2015/testing.js: 2960: 1) su UserContext. <anonymous> (src / app / timebar.service.spec.ts: 14: 45) "
— canbax,

1
Questa risposta funziona anche per Angular 8. Questa dovrebbe essere la risposta accettata perché eseguirà esattamente un file di specifiche del test.

2
Per Angular 9 ottengo l'opzione sconosciuta "--main" :(
— rmcsharry

6

Se vuoi essere in grado di controllare quali file sono selezionati dalla riga di comando, sono riuscito a farlo per Angular 7.

In breve, è necessario installare @angular-devkit/build-angular:browsere quindi creare un plug-in Webpack personalizzato per passare la regex del file di test. Per esempio:

angular.json - cambia il generatore di test da @angular-devkit/build-angular:browsere imposta un file di configurazione personalizzato:

...

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

extra-webpack.config.js - crea una configurazione webpack che legge la regex dalla riga di comando:

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 - modifica le specifiche

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

Quindi utilizzare come segue per sovrascrivere il valore predefinito:

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

Ho documentato il retroscena qui , mi scuso in anticipo per tipi e collegamenti errati. Ringraziamo la risposta sopra di @ Aish-Anu per avermi indicato nella giusta direzione.


4

Questo funziona per me in Angular 7. Si basa sull'opzione --main del comando ng. Non sono sicuro che questa opzione non sia documentata e possibilmente soggetta a modifiche, ma funziona per me. Ho inserito una riga nel mio file package.json nella sezione script. Lì usando l'opzione --main di con il comando ng test, specifico il percorso del file .spec.ts che voglio eseguire. Per esempio

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

È possibile eseguire lo script mentre si esegue uno di questi script. Lo eseguo in Webstorm facendo clic su "test 1" nella sezione npm.


3

Ho risolto questo problema per me stesso usando il grugnito. Ho lo script grugnito qui sotto. Quello che fa lo script è di eseguire il parametro della riga di comando del test specifico e di creare una copia di test.ts e di inserire questo nome di test specifico.

Per eseguirlo, installa prima grunt-cli usando:

npm install -g grunt-cli

Inserisci le seguenti dipendenze grugnite nel tuo 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"

Per eseguirlo, salva il seguente file grunt come Gruntfile.js nella cartella principale. Quindi dalla riga di comando eseguilo come:

grunt --target=app.component

Questo eseguirà app.component.spec.ts.

Il file Grunt è il seguente:

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

};

Guardando la soluzione accettata, non credo che sia consigliato in questo modo
— Drenai,

2
@Brian - la mia soluzione evita di dover modificare il codice sorgente e quindi impedisce potenziali errori nel controllo del file. La mia soluzione consente semplicemente di specificare il nome del test sulla riga di comando automatizzando i passaggi manuali.
— vanval

Sì, in realtà è un buon punto. C'è una buona possibilità che potresti dimenticare di rimuovere xdescribe o fdescribe - e il tuo test verrà rimosso per sempre!
— Drenai,

3
@Ryan puoi installare / configurare tslint-jasmine-rules per controllare le chiamate fdescribe / fit / xdescribe / xit e fallire la tua esecuzione tslint; se fa parte di una fase di pre-esecuzione, impedisce di controllare accidentalmente i test in modo focalizzato o disabilitato.
— Neil Menzies,

1

Aggiungendo questo per le persone come me che stavano cercando un modo per eseguire una singola specifica in Angular e hanno trovato questo SO.

Secondo gli ultimi documenti angolari (v9.0.6 al momento della scrittura), il ng testcomando ha --includeun'opzione in cui è possibile specificare una directory di *.spec.(ts|tsx)file o solo un singolo .spec.(ts|tsx)file stesso.

https://angular.io/cli/test


0

Solo piccole modifiche sono necessarie nel test.tsfile all'interno della cartella src:

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

Qui, test-example il nome esatto del file che dobbiamo eseguire

Allo stesso modo, se è necessario testare solo il file di servizio, è possibile sostituire il nome del file come "/test-example.service"


0

Questo ha funzionato per me in ogni caso:

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

Tuttavia, di solito ho ricevuto "TypeError: Impossibile leggere la proprietà 'ngModule' di null" per questo:

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

Versione di @ angular / cli 10.0.4

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.