Automatiseer Angular Component Testing met Unit Tests en e2e Tests
description
Met deze prompt kan de gebruiker een robuust testproces voor Angular componenten opzetten, wat helpt fouten vroeg te detecteren, de stabiliteit van de applicatie verhoogt en onderhoud makkelijker maakt. Het biedt concrete voorbeelden en uitleg, waardoor het sneller en effectiever is dan zelf uitzoeken.
prompt
Help me met het opzetten van een geautomatiseerd testproces voor mijn Angular componenten. Leg uit hoe ik unit tests kan schrijven met Jasmine en Karma, en hoe ik end-to-end (e2e) tests co ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een overzicht en voorbeeldconfiguraties voor het opzetten van geautomatiseerde tests voor jouw Angular formuliercomponent, inclusief unit tests met Jasmine en Karma, en e2e tests met Cypress of Protractor.
---
### 1. Unit Tests met Jasmine en Karma
**Stap 1: Setup**
Bij een Angular project wordt meestal Jasmine en Karma al gebruikt voor unit testing. Controleer of je project `@angular/cli` heeft geïnstalleerd met de juiste dependencies.
**Stap 2: Testbestand maken**
Voor jouw component, bijvoorbeeld `registration-form.component.ts`, maak een bestand `registration-form.component.spec.ts`.
**Stap 3: Voorbeeld unit test**
```typescript
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { RegistrationFormComponent } from './registration-form.component';
describe('RegistrationFormComponent', () => {
let component: RegistrationFormComponent;
let fixture: ComponentFixture<RegistrationFormComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [RegistrationFormComponent],
imports: [ReactiveFormsModule]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(RegistrationFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('formulier moet valid zijn met correcte invoer', () => {
const form = component.registrationForm;
form.controls['name'].setValue('Jan Jansen');
form.controls['email'].setValue('jan@example.com');
form.controls['password'].setValue('SterkWachtwoord123');
expect(form.valid).toBeTrue();
});
it('moet foutmeldingen tonen bij ongeldige invoer', () => {
const form = component.registrationForm;
form.controls['email'].setValue('ongeldige-email');
form.controls['password'].setValue('kort');
expect(form.invalid).toBeTrue();
expect(form.controls['email'].errors).toBeTruthy();
expect(form.controls['password'].errors).toBeTruthy();
});
});
```
**Stap 4: Testen van gebruikersinteractie**
Gebruik `DebugElement` en `By` om DOM-elementen te simuleren:
```typescript
import { By } from '@angular/platform-browser';
it('moet de submit knop activeren bij geldige invoer', () => {
const nameInput = fixture.debugElement.query(By.css('input[name="name"]')).nativeElement;
const emailInput = fixture.debugElement.query(By.css('input[name="email"]')).nativeElement;
const passwordInput = fixture.debugElement.query(By.css('input[name="password"]')).nativeElement;
const submitButton = fixture.debugElement.query(By.css('button[type="submit"]')).nativeElement;
nameInput.value = 'Jan Jansen';
nameInput.dispatchEvent(new Event('input'));
emailInput.value = 'jan@example.com';
emailInput.dispatchEvent(new Event('input'));
passwordInput.value = 'SterkWachtwoord123';
passwordInput.dispatchEvent(new Event('input'));
fixture.detectChanges();
expect(submitButton.disabled).toBeFalse();
});
```
---
### 2. End-to-End Tests met Cypress of Protractor
#### Optie A: Cypress
**Stap 1: Installatie**
```bash
npm install cypress --save-dev
```
**Stap 2: Configuratie**
Maak een testbestand, bijvoorbeeld `registration.spec.js` in `cypress/e2e/`.
**Voorbeeld Cypress E2E test:**
```javascript
describe('Gebruiker registratie formulier', () => {
beforeEach(() => {
cy.visit('http://localhost:4200/registration'); // pas aan naar je URL
});
it('vult het formulier in en verzendt', () => {
cy.get('input[name="name"]').type('Jan Jansen');
cy.get('input[name="email"]').type('jan@example.com');
cy.get('input[name="password"]').type('SterkWachtwoord123');
cy.get('button[type="submit"]').should('not.be.disabled').click();
// Controleer of de bevestigingspagina of boodschap verschijnt
cy.contains('Registratie voltooid').should('be.visible');
});
});
```
**Stap 3: Run Cypress**
```bash
npx cypress open
```
---
#### Optie B: Protractor
Angular CLI ondersteunt standaard Protractor, maar het wordt minder aanbevolen omdat het in onderhoud is. Als je Protractor wilt gebruiken:
**Stap 1: Configuratie**
In `protractor.conf.js`, stel je de baseUrl en specs in.
**Stap 2: Testvoorbeeld**
```javascript
describe('Registratie formulier', () => {
it('vult en verzendt het formulier', () => {
browser.get('http://localhost:4200/registration');
element(by.name('name')).sendKeys('Jan Jansen');
element(by.name('email')).sendKeys('jan@example.com');
element(by.name('password')).sendKeys('SterkWachtwoord123');
const submitButton = element(by.css('button[type="submit"]'));
expect(submitButton.isEnabled()).toBe(true);
submitButton.click();
// Controleer of de bevestiging verschijnt
const successMsg = element(by.cssContainingText('.success', 'Registratie voltooid'));
expect(successMsg.isPresent()).toBe(true);
});
});
```
---
### Samenvatting
- **Unit tests** (Jasmine + Karma): controleer logica, validatie en gebruikersinteractie binnen componenten.
- **E2E tests** (Cypress of Protractor): simuleer volledige gebruikersstromen, inclusief DOM-interacties en navigatie.
Wil je meer specifieke voorbeelden of hulp bij de configuratie?
provider: deepseek
model: deepseek-chat
Zeker! Ik help je bij het opzetten van een geautomatiseerd testproces voor je Angular registratiecomponent. Hier is een complete uitleg:
## 1. Unit Tests met Jasmine en Karma
### Configuratie
Jasmine en Karma zijn standaard geconfigureerd in nieuwe Angular projecten. Controleer je `karma.conf.js`:
```javascript
module.exports = function (config) {
config.set({
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
]
});
};
```
### Testvoorbeeld voor Registratie Component
```typescript
// registratie.component.spec.ts
import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { RegistratieComponent } from './registratie.component';
describe('RegistratieComponent', () => {
let component: RegistratieComponent;
let fixture: ComponentFixture<RegistratieComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [RegistratieComponent],
imports: [ReactiveFormsModule]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(RegistratieComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// Test 1: Component wordt correct aangemaakt
it('moet component aanmaken', () => {
expect(component).toBeTruthy();
});
// Test 2: Formulier initialisatie
it('moet formulier initialiseren met lege waarden', () => {
expect(component.registratieForm.value).toEqual({
naam: '',
email: '',
wachtwoord: ''
});
});
// Test 3: Validatie van verplichte velden
it('moet validatiefouten tonen bij lege velden', () => {
const form = component.registratieForm;
expect(form.valid).toBeFalse();
const naamControl = form.get('naam');
naamControl.setValue('');
expect(naamControl.hasError('required')).toBeTrue();
});
// Test 4: Email validatie
it('moet ongeldige email afkeuren', () => {
const emailControl = component.registratieForm.get('email');
emailControl.setValue('ongeldig-email');
expect(emailControl.hasError('email')).toBeTrue();
});
// Test 5: Geldige email accepteren
it('moet geldige email accepteren', () => {
const emailControl = component.registratieForm.get('email');
emailControl.setValue('test@voorbeeld.nl');
expect(emailControl.valid).toBeTrue();
});
// Test 6: Formulier indienen
it('moet onSubmit aanroepen bij geldig formulier', fakeAsync(() => {
spyOn(component, 'onSubmit');
// Vul formulier in
component.registratieForm.setValue({
naam: 'Jan Jansen',
email: 'jan@voorbeeld.nl',
wachtwoord: 'wachtwoord123'
});
// Trigger submit
const form = fixture.debugElement.query(By.css('form'));
form.triggerEventHandler('submit', null);
tick();
expect(component.onSubmit).toHaveBeenCalled();
}));
// Test 7: Wachtwoord minimum lengte
it('moet wachtwoordlengte valideren', () => {
const wachtwoordControl = component.registratieForm.get('wachtwoord');
wachtwoordControl.setValue('kort');
expect(wachtwoordControl.hasError('minlength')).toBeTrue();
});
});
```
## 2. End-to-End Tests met Cypress
### Installatie
```bash
npm install -D cypress
npx cypress open
```
### Cypress Testvoorbeeld
```javascript
// cypress/e2e/registratie.cy.js
describe('Registratie Formulier', () => {
beforeEach(() => {
cy.visit('/registratie');
});
it('moet registratieformulier correct weergeven', () => {
cy.get('form').should('exist');
cy.get('#naam').should('be.visible');
cy.get('#email').should('be.visible');
cy.get('#wachtwoord').should('be.visible');
cy.get('button[type="submit"]').should('be.visible');
});
it('moet validatiefouten tonen bij lege velden', () => {
cy.get('button[type="submit"]').click();
cy.get('.error-message').should('be.visible');
cy.contains('Naam is verplicht').should('exist');
});
it('moet succesvol registreren bij geldige gegevens', () => {
cy.get('#naam').type('Jan Jansen');
cy.get('#email').type('jan@voorbeeld.nl');
cy.get('#wachtwoord').type('veiligWachtwoord123');
cy.get('button[type="submit"]').click();
cy.url().should('include', '/succes');
cy.contains('Registratie succesvol').should('be.visible');
});
it('moet ongeldige email afkeuren', () => {
cy.get('#email').type('ongeldig-email');
cy.get('#email').blur();
cy.contains('Ongeldig email formaat').should('be.visible');
});
});
```
### Cypress Configuratie
```javascript
// cypress.config.js
const { defineConfig } = require('cypress');
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:4200',
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});
```
## 3. Test Commands
Voeg toe aan je `package.json`:
```json
{
"scripts": {
"test": "ng test",
"test:watch": "ng test --watch",
"test:ci": "ng test --watch=false --browsers=ChromeHeadless",
"e2e": "ng e2e",
"e2e:cypress": "cypress open"
}
}
```
## 4. Test Coverage
Voeg coverage toe aan `karma.conf.js`:
```javascript
coverageReporter: {
dir: require('path').join(__dirname, './coverage'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
}
```
## 5. Best Practices
1. **Test Isolation**: Elke test moet onafhankelijk zijn
2. **Arrange-Act-Assert**: Duidelijke teststructuur
3. **Meaningful Names**: Beschrijvende testnamen
4. **Async Handling**: Gebruik `fakeAsync` en `tick()` voor async operaties
5. **UI Tests**: Test zowel functionaliteit als gebruikersinteractie
## 6. Uitvoeren
```bash
# Unit tests
npm test
# E2E tests met Cypress
npm run e2e:cypress
# Tests in CI modus
npm run test:ci
```
Deze setup geeft je een complete testomgeving voor je registratiecomponent met zowel unit tests als end-to-end tests!