Présentation
Il s’agit de la prise de notes réalisées pendant le suivi de la formation Angular Testing Masterclass
Section 1 : Course Kickoff - Development Environment Setup
- Visual Studio Settings : rien à voir mais bon … c’est galère quand c’est mal configuré. Donc pour que tous les fichiers passent en tab = espace et qu’un tab = 4 espaces (parce que c’est que J’AIME)
"editor.tabSize": 4,
"editor.insertSpaces": true,
"editor.detectIndentation": false,
"[javascript]": {
"editor.tabSize": 4
},
"[typescript]": {
"editor.tabSize": 4
}
- Mise en place d’un espion :
spyOn(logger, 'log');
// [...]
expect(logger.log).toHaveBeenCalledTimes(1);
- Autre version (plus proche du Mock) :
const logger = jasmine.createSpyObj('LoggerService', ['log']);
, - Parce que mon éditeur le trouve pas :
import { TestBed } from '@angular/core/testing';
. - Une phrase que j’aime bien : “Il ne faut pas utiliser des implémentations réelles de dépendances mais des mocks, sinon c’est pas un test unitaire mais un test fonctionnel”,
- RAPPEL : Chaque test doit être indépendant et ne pas dépendre d’un ordre d’exécution,
- Pour désactiver :
- Une suite de tests :
describe
->__x__describe
, - Un test en particulier :
it
-> ->__x__it
, - Bref faut mettre une X,
- Une suite de tests :
- Pour être focus sur un test :
- Pareil mais avec un f,
Section 2 - Angular Service Testing In Depth
(Doc Angular)[https://angular.io/guide/testing#service-tests],
(Doc Angular - Http Testing)[https://angular.io/guide/http#testing-http-requests],
(Testing HttpClient Request In Angular)[https://alligator.io/angular/testing-httpclient/],
Un mock fournit directement par HttpClientTestingModule (import { HttpClientTestingModule } from ‘@angular/common/http/testing’;),
Ne pas oublier la méthode flush :
req.flush([DATA]);
C’est intéressant car souvent l’ordre des actions est : préparation, action et validation. Ici, c’est plus validation/préparation et action.Le type Partial dans TypeScript : pratique mais dangeureux ?
Même si je suis pas un grand fan de cette syntaxe, faut reconnaître que c’est pratique :
req.flush({
...COURSES[12],
...changes
});
- Un point avec lequel je suis pas super à l’aise et que par moment, le test porte finalement sur les données de test plus que le service lui même,
Section 3 : Angular Component Testing In Depth
Presentation Component
- Plutôt que de charger composants par composants : import du module qui va tout charger …
- Pour gérer une fonction asynchrone dans une fonction comme beforeEach : async() qui attend une fonction en paramètre,
- Point d’entrée pour naviguer dans le DOM : DebugElement (
import { DebugElement } from '@angular/core';
) accessible via fixture.debugElement
La formation utilise compileComponents dans la cas de l’initialisation du test. La documentation dans le cas basic n’en fait pas mention. En fait, d’après le (doc)[https://angular.io/guide/testing#calling-compilecomponents] ce n’est que si les tests sont exécutés en dehors de ng test
.
Le composant récupérer par la méthode classique ne donne accès qu’aux propriétés publiques du composants. Pour accéder aux éléments tel que le DOM, agir sur l’interne, il faut passer par le “Debug Element”:
fixture = TestBed.createComponent([ComponenentATester]);
component = fixture.componentInstance;
el = fixture.debugElement;
Smart or Container Component
- Par rapport à un composant de présentation, il récupère “lui-même” ses données via un service alors que le précédente reçoit les données en paramètre,
- Gestion des animations dans les tests : (NoopAnimationsModule)[https://angular.io/api/platform-browser/animations/NoopAnimationsModule] permet d’annuler les animations sans tout casser,
- Sur la gestion des tabs, validation que le tab affiché est le bon :
const title = tabs[0].query(By.css('.mat-tab-label-content')); expect(title.nativeElement.textContent).toBe('Advanced');
Section 4 : Section 4 : Asynchronous Angular Testing In Depth
- Solution 1 : utiliser une
DoneFn
en paramètre du test pour indiquer à Jasmine d’attendre jusqu’à son appel, - Solution 2 : (fakeAsync)[https://angular.io/guide/testing#component-with-async-service]. Composant fournit par Angular et qui propose un mécanisme utilisé par Angular pour détecter les appels asynchrone,
- Créer une zone de test qui détecte les différents appels asynchrones, les enregistre et permet ensuite de débloquer les différentes files d’attente,
- tick(): permet de simuler l’avance du temps !,
- PI : dans le cas de fakeAsync, la fonction setTimeOut est remplacée par une version qui ne fait rien. Pour que le temps avance, il faut faire tick !,
- Par contre tellement c’est simple quand on gère les TimeOut mais pour le reste, comment tu gères le temps ?,
- flush() : gère tous les files d’attente :),
- flushMicrotasks() : uniquement les microtasks (promesse),
- Solution 3 : (async)[https://angular.io/guide/testing#async-test-with-async]. Il s’agit du composant utilisé dans le beforeEach pour gérer l’asynchrone,
- Créer également une zone de test mais semble-t-il différente,
- fixture.whenStable() : au sein d’async tous les appels sont captés et quand ils sont tous finis, whenStable() agit !
- Obligatoire dans le cadre d’un appel http qui n’est pas supporté par fakeAsync,
- Obligatoire aussi si les tests ne s’executent pas avec ng test (les css et autres templates seraient chargés pas une requête http …),
Gestion des tasks et microtasks : le gestionnaire “Event loop” gère les différentes actions en fonction de différentes files d’attente. Il semble que le navigateur puisse venir jouer les troubles fêtes mais c’est à savoir,
* Un (article)[https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/] qui date un peu mais avec de bons exemples,
* Si une promesse est exécutée dans une promesse : elle est ajoutée dans la pile quid d’un setTimeOut ?
Section 5 : Angular E2E (End to End) Testing with Cypress
- (cypress.io)[https://www.cypress.io/],
- Installation :
npm install --only=dev cypress
,
Ayant fait pas mal de Cypress dernièrement : pas grand de neuf. Le chapitre est même un peu léger je trouve. Après ce n’est pas une formation à Cypress.
Section 6 : Section 6 : Preparing an Angular Application for Continuous Integration
Je n’utilise pas Travis et à titre perso, je n’ai pas de CI donc je n’ai fait que suivre.
- (npm-run-all)[https://www.npmjs.com/package/npm-run-all] : A CLI tool to run multiple npm-scripts in parallel or sequential,
- (run-s)[https://github.com/mysticatea/npm-run-all/blob/HEAD/docs/run-s.md] : CLI command to run given npm-scripts sequentially. This command is the shorthand of npm-run-all -s,
- (run-p)[https://github.com/mysticatea/npm-run-all/blob/HEAD/docs/run-p.md] : A CLI command to run given npm-scripts in parallel. This command is the shorthand of npm-run-all -p.
- (start-server-and-test)[https://www.npmjs.com/package/start-server-and-test] : Starts server, waits for URL, then runs test command; when the tests end, shuts down server,