AngularJS unit testen met Karma & Jasmine

⚡ Slimme samenvatting

AngularJS unit testen met Karma en Jasmine verifieert controllers, directives en services geïsoleerd. Karma voert specificaties uit in echte browsers, Jasmine levert de assertiesyntaxis en angular-mocks injecteert afhankelijkheden zonder een live server.

  • 🧱 Gereedschapsverdeling: Karma is de testrunner, Jasmine is het specificatiekader en angular-mocks levert hulpmiddelen voor dependency injection.
  • ⚙️ Installatiepad: Installeer karma, karma-chrome-launcher, karma-jasmine en karma-cli via npm en genereer vervolgens karma.conf.js.
  • 📁 Configuratieregel: De array met bestanden moet de volgende bestanden bevatten, in die volgorde: angular.js, angular-mocks.js, de broncode van de applicatie en de testmap.
  • ️ Controller testen: Injecteer de $controller-service, geef een mock $scope-object door en controleer vervolgens de waarden die de controller toewijst.
  • 🧩 Richtlijntesten: Gebruik `$compile` met `$rootScope`, roep `$digest` aan en inspecteer de gerenderde markup die door de directive wordt geretourneerd.
  • 🌐 Eind-tot-eindlaag: ProtracTor stuurt een draaiende applicatie aan en telt de herhaalde rijen die door ng-repeat worden geproduceerd.
  • 📌 Ondersteuningsstatus: AngularJS heeft op 31 december 2021 het einde van zijn levenscyclus bereikt, dus beschouw deze workflow als kennis voor het onderhoud van verouderde software.

AngularJS unit testen met Karma en Jasmine

Een van de meest briljante eigenschappen van AngularJS is de Testen aspect. Wanneer de ontwikkelaars bij Google Bij de ontwikkeling van AngularJS hielden ze rekening met testen en zorgden ze ervoor dat het hele AngularJS-framework testbaar was.

In AngularJS wordt testen doorgaans uitgevoerd met behulp van Karma (framework). Het testen van AngularJS kan ook zonder Karma, maar het Karma-framework biedt zulke briljante functionaliteit voor het testen van AngularJS-code dat het zinvol is om dit framework te gebruiken.

  • In AngularJS kunnen we presteren Testen van een eenheid afzonderlijk voor controllers en richtlijnen.
  • Wij kunnen ook uitvoeren end-to-end testen van AngularJS, wat neerkomt op testen vanuit het perspectief van de gebruiker.

⚠️ Versie-opmerking: AngularJS (versie 1.x) heeft op 31 december 2021 officieel het einde van zijn levenscyclus bereikt, en ProtracTor is in augustus 2023 uitgefaseerd. De workflow op deze pagina blijft geldig voor het onderhouden van bestaande AngularJS 1.x-applicaties. Nieuwe projecten dienen gebruik te maken van een moderne Angular-versie met een momenteel ondersteunde runner.

Introductie en installatie van het Karma-framework

Karma is een automatiseringstool voor testen gemaakt door het AngularJS-team bij GoogleDe eerste stap om Karma te gebruiken is het installeren ervan. Karma wordt geïnstalleerd via npm (een pakketbeheerder waarmee modules eenvoudig op een lokale machine kunnen worden geïnstalleerd).

Installatie van Karma

De installatie van Karma via npm gebeurt in een proces van twee stappen.

Stap 1) Voer de onderstaande regel uit vanaf de opdrachtregel

npm install karma karma-chrome-launcher karma-jasmine --save-dev

Waarin,

  1. npm is het commandoregelprogramma voor de Node Package Manager, waarmee je aangepaste modules op elke machine kunt installeren. Het wordt meegeleverd met Node Package Manager. Node.js.
  2. De install-parameter geeft aan het opdrachtregelprogramma npm aan dat installatie vereist is.
  3. Er worden 3 bibliotheken gespecificeerd op de opdrachtregel die nodig zijn om met karma te werken.
    • karma is de kernbibliotheek die voor testdoeleinden zal worden gebruikt.
    • karma-chrome-launcher is een aparte bibliotheek waarmee karma-opdrachten door de Chrome-browser kunnen worden herkend.
    • karma-jasmijn – Hiermee wordt jasmijn geïnstalleerd, een afhankelijk raamwerk voor Karma.

Stap 2) De volgende stap is het installeren van het karma-opdrachtregelhulpprogramma. Dit is vereist voor het uitvoeren van karmalijnopdrachten. Het karmalijnhulpprogramma zal worden gebruikt om de karma-omgeving te initialiseren voor testen.

Om het opdrachtregelhulpprogramma te installeren, voert u de onderstaande regel uit vanaf de opdrachtregel

npm install -g karma-cli
  • Karma-cli wordt gebruikt om de commandoregelinterface voor Karma te installeren, waarmee Karma-commando's in de commandoregel kunnen worden ingevoerd. De vlag -g installeert het globaal, zodat het Karma-commando vanuit elke map beschikbaar is.

Configuratie van het Karma-framework

De volgende stap is het configureren van karma, wat gedaan kan worden via de opdracht

karma init

Nadat de bovenstaande stap is uitgevoerd, zal karma een karma.conf.js-bestand maken. Het bestand zal er waarschijnlijk uitzien als het onderstaande fragment

files: [
  'node_modules/angular/angular.js',
  'node_modules/angular-mocks/angular-mocks.js',
  'lib/app.js',
  'tests/*.js'
]

De bovenstaande configuratiebestanden vertellen de karma runtime engine het volgende

  1. hoekig.js Dit laat Karma weten dat je applicatie afhankelijk is van de kernmodules in AngularJS.
  2. angular-mocks.js Dit geeft Karma de opdracht om de unit-testfunctionaliteit voor AngularJS uit het bestand angular-mocks.js te gebruiken.
  3. Alle hoofdtoepassings- of bedrijfslogicabestanden zijn aanwezig in de map lib van uw toepassing.
  4. De testmap bevat alle unittests.

💡Tip: De volgorde van de bestanden in de array is belangrijk. angular.js moet vóór angular-mocks.js geladen worden, en beide moeten geladen worden vóór je applicatiecode. Anders is de injector niet beschikbaar wanneer de specificaties worden uitgevoerd.

Om te controleren of karma werkt, maakt u een bestand met de naam Sample.js, voert u de onderstaande code in en plaatst u deze in de testmap.

describe('Sample test', function() {
  it('Condition is true', function() {
    expect('AngularJS').toBe('AngularJS');
  });
});

De bovenstaande code heeft de volgende aspecten

  1. De beschrijven functie wordt gebruikt om een ​​beschrijving van de test te geven. In ons geval geven wij de omschrijving 'Voorbeeldtest' aan onze test.
  2. De 'it'-functie wordt gebruikt om de test een naam te geven. In ons geval geven we de naam van onze test als 'Voorwaarde is waar'. De naam van de test moet betekenisvol zijn.
  3. De combinatie van het trefwoord 'expect' en 'toBe' geeft aan wat de verwachte en werkelijke waarde van het testresultaat is. Als de werkelijke en de verwachte waarde hetzelfde zijn, zal de test slagen, anders mislukt deze.

Wanneer u de volgende regel uitvoert bij de opdrachtprompt, wordt het bovenstaande testbestand uitgevoerd

karma start

De onderstaande uitvoer is afkomstig van de IDE Webstorm waarin bovenstaande stappen zijn uitgevoerd.

Configuratie van het Karma-framework

  1. De uitvoer komt binnen in de Karma-verkenner Webstorm. Dit venster toont de uitvoering van alle tests die in het karma-raamwerk zijn gedefinieerd.
  2. Hier kunt u zien dat de beschrijving van de uitgevoerde test wordt weergegeven, namelijk “Voorbeeldtest”.
  3. Vervolgens kunt u zien dat de test zelf, die de naam “Voorwaarde is waar” heeft, wordt uitgevoerd.
  4. Houd er rekening mee dat bij alle tests het groene pictogram 'Ok' ernaast staat, wat symboliseert dat alle tests zijn geslaagd.

Wat is Jasmine in AngularJS unit-testen?

Karma bepaalt waar tests worden uitgevoerd, terwijl Jasmine bepaalt hoe ze worden geschreven. Jasmine is een gedragsgestuurd specificatiekader dat de terminologie levert die in elk voorbeeld op deze pagina wordt gebruikt. Daarom wordt de karma-jasmine-adapter samen met de testrunner geïnstalleerd.

Jasmine draagt ​​vier bouwstenen bij:

  • beschrijven(): Groepeert gerelateerde specificaties in een suite en accepteert een leesbare beschrijving van de te testen eenheid.
  • Het(): Hiermee wordt één enkele specificatie gedefinieerd. De naam moet het te verifiëren gedrag aangeven, en niet de aangeroepen methode.
  • expect() met matchers: Vergelijkt een werkelijke waarde met een verwachte waarde. Veelgebruikte vergelijkingsmethoden zijn onder andere toBe, toEqual, toContain en toBeDefined.
  • beforeEach() en afterEach(): Voer de setup- en teardown-procedure uit vóór en na elke specificatie, zodat elke test onafhankelijk blijft.

Jasmine biedt ook spies. Een spie vervangt een echte functie door een opgenomen vervanging, zodat een controller kan worden getest zonder een live HTTP-eindpunt aan te roepen. Omdat Jasmine geen DOM en geen eigen assertiebibliotheek nodig heeft, blijft de combinatie van Karma en Jasmine de meest efficiënte manier om AngularJS te gebruiken. JavaScript-unit tests.

AngularJS-controllers testen

Het karmatestframework heeft ook de functionaliteit om Controllers van begin tot eind te testen. Dit omvat het testen van het object $scope dat binnen Controllers wordt gebruikt.

Laten we eens kijken naar een voorbeeld van hoe we dit kunnen bereiken.

In ons voorbeeld

We zouden eerst een controller moeten definiëren. Deze controller zou de onderstaande stappen uitvoeren

  1. Maak een ID-variabele en wijs hieraan de waarde 5 toe.
  2. Wijs de ID-variabele toe aan het object $scope.

Onze test zal het bestaan ​​van deze controller testen en ook testen of de ID-variabele van het $scope-object is ingesteld op 5.

Eerst moeten we ervoor zorgen dat aan de volgende voorwaarde is voldaan

Installeer de angular-mocks-bibliotheek via npm. Dit kan door de volgende regel in de opdrachtprompt uit te voeren.

npm install angular-mocks --save-dev

Vervolgens moet u het karma.conf.js-bestand aanpassen om ervoor te zorgen dat de juiste bestanden voor de test worden opgenomen. Het onderstaande segment toont alleen het bestandengedeelte van karma.conf.js dat moet worden gewijzigd

files: ['lib/angular.js', 'lib/angular-mocks.js', 'lib/index.js', 'test/*.js']
  • De parameter 'files' vertelt Karma feitelijk alle bestanden die nodig zijn voor het uitvoeren van de tests.
  • De bestanden angular.js en angular-mocks.js zijn vereist om AngularJS-unit tests uit te voeren.
  • Het index.js-bestand bevat onze code voor de controller
  • De testmap zal al onze AngularJS-tests bevatten

Hieronder staat onze AngularJS-code, die als bestand Index.js in de testmap van onze applicatie wordt opgeslagen.

De onderstaande code doet gewoon het volgende

  1. Maak een AngularJS-module genaamd voorbeeldApp
  2. Maak een controller met de naam AngularJSController
  3. Maak een variabele met de naam ID, geef deze de waarde 5 en wijs deze toe aan het $scope-object
var sampleApp = angular.module('sampleApp', []);
sampleApp.controller('AngularJSController', function($scope) {
  $scope.ID = 5;
});

Zodra de bovenstaande code met succes is uitgevoerd, is de volgende stap het maken van een Testgeval om ervoor te zorgen dat de code correct is geschreven en uitgevoerd.

De code voor onze test is zoals hieronder weergegeven.

De code zal in een apart bestand staan ​​genaamd ControllerTest.js, dat in de testmap zal worden geplaatst. De onderstaande code doet alleen de volgende belangrijke dingen

  1. De `beforeEach`-functie wordt gebruikt om onze AngularJS-module genaamd 'sampleApp' te laden vóór de testuitvoering. Let op: dit is de naam van de module in een `index.js`-bestand.
  2. Het `$controller`-object wordt aangemaakt als een mock-object voor de controller "AngularJSController" die is gedefinieerd in ons `index.js`-bestand. Bij unit-testen vertegenwoordigt een mock-object een dummy-object dat daadwerkelijk voor de test wordt gebruikt. Dit mock-object simuleert het gedrag van onze controller.
  3. beforeEach(inject(function(_$controller_)) – Dit wordt gebruikt om het nepobject in onze test te injecteren, zodat het zich gedraagt ​​als de daadwerkelijke controller.
  4. var $scope = {}; Dit is een nepobject dat wordt gemaakt voor het $scope-object.
  5. var controller = $controller('AngularJSController', { $scope: $scope }); – Hier controleren we of er een controller met de naam 'AngularJSController' bestaat. We kennen hier ook alle variabelen uit ons $scope-object in de controller in het Index.js-bestand toe aan het $scope-object in ons testbestand.
  6. Ten slotte vergelijken we de $scope.ID met 5
describe('AngularJSController', function() {
  beforeEach(module('sampleApp'));

  var $controller;

  beforeEach(inject(function(_$controller_){
    $controller = _$controller_;
  }));

  describe('$scope.ID', function() {
    it('Check the scope object', function() {
      var $scope = {};
      var controller = $controller('AngularJSController', { $scope: $scope });
      expect($scope.ID).toEqual(5);
    });
  });
});

De bovenstaande test wordt uitgevoerd in de karmabrowser en geeft hetzelfde resultaat als in het vorige onderwerp.

AngularJS-richtlijnen testen

Het Karma-testframework biedt ook de mogelijkheid om aangepaste richtlijnen te testen. Dit omvat ook de template.URL's die worden gebruikt binnen aangepaste richtlijnen.

Laten we eens kijken naar een voorbeeld van hoe we dit kunnen bereiken.

In ons voorbeeld zullen we eerst een aangepaste richtlijn definiëren die de volgende dingen doet

  1. Maak een AngularJS-module met de naam sampleApp
  2. Maak een aangepaste instructie met de naam guru99.
  3. Maak een functie die een sjabloon retourneert met een headertag die de tekst 'Dit is AngularJS Testing' weergeeft.
var sampleApp = angular.module('sampleApp', []);
sampleApp.directive('guru99', function () {
  return {
    restrict: 'E',
    replace: true,
    template: '<h1>This is AngularJS Testing</h1>'
  };
});

Zodra de bovenstaande code met succes is uitgevoerd, is de volgende stap het maken van een testcase om er zeker van te zijn dat de code correct is geschreven en uitgevoerd. De code voor onze test is zoals hieronder weergegeven

De code zal in een apart bestand staan ​​met de naam DirectiveTest.js, dat in de testmap zal worden geplaatst. De onderstaande code doet alleen de volgende belangrijke dingen

  1. De `beforeEach`-functie wordt gebruikt om onze AngularJS-module genaamd 'sampleApp' te laden voordat de test wordt uitgevoerd.
  2. De `$compile`-service wordt gebruikt om de directive te compileren. Deze service is verplicht en moet worden gedeclareerd, zodat AngularJS deze kan gebruiken om onze aangepaste directive te compileren.
  3. De `$rootScope` is de primaire scope van elke AngularJS-applicatie. We hebben het `$scope`-object van de controller al in eerdere hoofdstukken gezien. Het `$scope`-object is een subobject van het `$rootScope`-object. De reden dat dit hier wordt gedeclareerd, is omdat we via onze aangepaste directive een wijziging aanbrengen in een daadwerkelijke HTML-tag in de DOM. Daarom moeten we de `$rootScope`-service gebruiken, die luistert naar, oftewel weet, wanneer er een wijziging plaatsvindt in een HTML-document.
  4. var element = $compile(“ ”)($rootScope) – Dit wordt gebruikt om te controleren of onze directive correct wordt geïnjecteerd. De directive is geregistreerd met de camel case-naam guru99, dus AngularJS komt overeen met het element in kleine letters. in de markup. Vandaar dat deze instructie wordt gebruikt om die controle uit te voeren.
  5. expect(element.html()).toContain(“This is AngularJS Testing”) – Dit wordt gebruikt om de expect-functie te instrueren dat deze het element (in ons geval de h1-tag) moet vinden dat de innerHTML-tekst “This is AngularJS Testing” bevat.
describe('Unit testing directives', function() {
  var $compile,
      $rootScope;
  beforeEach(module('sampleApp'));

  beforeEach(inject(function(_$compile_, _$rootScope_){
    $compile = _$compile_;
    $rootScope = _$rootScope_;
  }));

  it('Check the directive', function() {
    // Compile a piece of HTML containing the directive
    var element = $compile("<guru99></guru99>")($rootScope);
    $rootScope.$digest();
    expect(element.html()).toContain("This is AngularJS Testing");
  });
});

De bovenstaande test wordt uitgevoerd in de karmabrowser en geeft hetzelfde resultaat als in het vorige onderwerp.

End-to-end testen van AngularJS-applicaties

Het karma-testframework, samen met een framework genaamd Pro.tracTor biedt de mogelijkheid om een ​​webapplicatie van begin tot eind te testen.

Het is dus niet alleen het testen van richtlijnen en controllers, maar ook het testen van al het andere dat op een HTML-pagina kan verschijnen.

Laten we eens kijken naar een voorbeeld van hoe we dit kunnen bereiken.

In ons voorbeeld hieronder hebben we een AngularJS-applicatie die een gegevenstabel maakt met behulp van de ng-repeat-richtlijn.

  1. We maken eerst een variabele met de naam “tutorial” en wijzen deze in één stap enkele sleutel-waardeparen toe. Elk sleutel-waardepaar wordt gebruikt als gegevens bij het weergeven van de tabel. De tutorialvariabele wordt vervolgens toegewezen aan het scope-object, zodat deze vanuit onze weergave toegankelijk is.
  2. Voor elke rij met gegevens in de tabel gebruiken we de ng-repeat-richtlijn. Deze richtlijn doorloopt elk sleutel-waardepaar in het tutorial-scope-object met behulp van de variabele ptutor.
  3. Tenslotte maken we gebruik van de tag samen met de sleutelwaardeparen (ptutor.Name en ptutor.Description) om de tabelgegevens weer te geven.
<table>
  <tr ng-repeat="ptutor in tutorial">
    <td>{{ ptutor.Name }}</td>
    <td>{{ ptutor.Description }}</td>
  </tr>
</table>
</div>
<script type="text/javascript">
var app = angular.module('DemoApp', []);
app.controller('DemoController', function($scope) {
  $scope.tutorial = [
    {Name: "Controllers", Description: "Controllers in action"},
    {Name: "Models", Description: "Models and binding data"},
    {Name: "Directives", Description: "Flexibility of Directives"}
  ];
});

Zodra de bovenstaande code met succes is uitgevoerd, is de volgende stap het maken van een testcase om er zeker van te zijn dat de code correct is geschreven en uitgevoerd. De code voor onze test is zoals hieronder weergegeven

Onze test gaat feitelijk de ng-repeat-richtlijn testen en ervoor zorgen dat deze 3 rijen met gegevens bevat zoals zou moeten uit het bovenstaande voorbeeld.

Eerst moeten we ervoor zorgen dat aan de volgende voorwaarde is voldaan

Installeer de protracTor-bibliotheek via npm. Dit kan door de onderstaande regel in de opdrachtprompt uit te voeren.

npm install -g protractor

De code voor onze test is zoals hieronder weergegeven.

De code zal in een apart bestand staan ​​met de naam CompleteTest.js , dat in de testmap zal worden geplaatst. De onderstaande code doet alleen de volgende belangrijke dingen

  1. De browserfunctie wordt geleverd door de pro.tracDe Tor-bibliotheek wordt gebruikt en er wordt vanuit gegaan dat onze AngularJS-applicatie (met de bovenstaande code) op onze site draait. URL – http://localhost:8080/Guru99 /
  2. var list = element.all(by.repeater('ptutor in tutorial')); - Deze regel code haalt de ng-repeat-directive op, die gevuld is met de code 'ptutor in tutorial'. `element` en `by.repeater` zijn speciale trefwoorden die door de plugin worden aangeboden.tracTor-bibliotheek waarmee we details van de ng-repeat-richtlijn kunnen verkrijgen.
  3. verwachten(lijst.telling()).toEqual(3); – Ten slotte gebruiken we de functie Expect om te zien dat we inderdaad drie items in onze tabel krijgen ingevuld als resultaat van de ng-repeat-richtlijn.
describe('Unit testing end to end', function() {
  beforeEach(function() {
    browser.get('http://localhost:8080/Guru99/');
  });

  it('Check the ng directive', function() {
    var list = element.all(by.repeater('ptutor in tutorial'));
    expect(list.count()).toEqual(3);
  });
});

De bovenstaande test wordt uitgevoerd in de karmabrowser en geeft hetzelfde resultaat als in het vorige onderwerp.

Karma vs Jasmine vs Protractor: Belangrijkste verschillen

De drie tools die op deze pagina worden gebruikt, worden vaak door elkaar gehaald omdat ze in dezelfde opdrachtregel verschijnen. Elk van deze tools bevindt zich echter op een andere laag van de teststack, zoals de onderstaande tabel duidelijk maakt.

Parameter Karma Jasmijn Protractor
Categorie Testloper Specificatiekader Volledig automatiseringsframework
Hoofdtaak Start browsers en rapporteert de resultaten. Biedt een beschrijving, het, en verwacht Stuurt een live applicatie aan in een echte browser.
Test niveau Eenheid en integratie Eenheid en integratie Van begin tot eind
Vereist een werkende server. Nee Nee Ja
Configuratiebestand karma.conf.js Nee, het loopt binnenin een loper. protractor.conf.js
Huidige status Verouderd, alleen voor onderhoud. Actief onderhouden Met pensioen gegaan in augustus 2023

Kortom, Jasmine schrijft de test, Karma voert hem uit en ProtracTor breidt dezelfde Jasmine-syntaxis uit naar een volledig weergegeven pagina.

Beste werkwijzen voor unit-testen van AngularJS

Een paar eenvoudige gewoontes zorgen ervoor dat een AngularJS-suite snel en betrouwbaar blijft, zelfs naarmate de applicatie groeit.

  1. Test één apparaat tegelijk. Laad alleen de te testen module in beforeEach en simuleer elke samenwerkende module, zodat een fout naar één specifiek bestand verwijst.
  2. Roep nooit een echte backend aan. Gebruik de `$httpBackend`-service van angular-mocks om vooraf gedefinieerde antwoorden te retourneren. Tests worden vervolgens offline uitgevoerd en leveren op elke machine identieke resultaten op.
  3. Houd de specificatienamen gedragsmatig. Een naam zoals "geeft 5 terug wanneer de controller wordt geïnitialiseerd" leest beter in een rapport dan "test1".
  4. Spoel de digestiecyclus altijd door. Roep `$rootScope.$digest()` aan nadat je de scopegegevens hebt gewijzigd, anders worden bindingen en watchers nooit bijgewerkt en mislukken beweringen om de verkeerde reden.
  5. Meet de dekking, maar beoordeel deze zorgvuldig. Voeg karma-coverage toe om ongeteste branches te zien. Een hoge dekking met zwakke beweringen verbergt nog steeds defecten.
  6. Voer de suite uit in een continue integratieomgeving. Gebruik een headless Chrome-launcher, zodat dezelfde specificaties bij elke commit worden uitgevoerd in plaats van alleen op een ontwikkelaarsmachine.

Door deze regels toe te passen, veranderen de bovenstaande voorbeelden van geïsoleerde demonstraties in een vangnet voor regressietests in een bestaande AngularJS-codebasis. Voor een breder overzicht, zie de AngularJS-handleiding series.

Veelgestelde vragen

De module die de provider bevat, is niet geladen. Voeg deze toe binnen `beforeEach(module('yourModule'))` en controleer of `angular-mocks.js` in `karma.conf.js` staat na `angular.js`, anders kan de injector de afhankelijkheid niet vinden.

Installeer karma-chrome-launcher en stel de browseroptie in op ChromeHeadless in karma.conf.js. De suite draait dan binnen continue integratiepipelines en containers waar geen displayserver beschikbaar is.

Ja. AI-codeerassistenten lezen een controller en stellen Jasmine-specificaties op met mock-scopes en matchers. RevBekijk de uitvoer zorgvuldig, want gegenereerde beweringen herhalen vaak de implementatie in plaats van het beoogde gedrag te verifiëren.

Ja. AI-tools vertalen Jasmine-specificaties naar Jest- of Vitest-syntaxis en markeren angular-mocks-aanroepen die geen direct equivalent hebben. Handmatige verificatie blijft essentieel, omdat dependency injection-patronen zelden probleemloos worden omgezet.

De meeste teams streven naar een dekkingsgraad van zeventig tot tachtig procent voor controllers en services. Het nastreven van een hoger percentage betekent meestal het testen van sjablonen en bibliotheken van derden, wat de onderhoudskosten verhoogt zonder dat er daadwerkelijke defecten worden opgespoord.

Vat dit bericht samen met: