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.