# De applicatie testen met de ingebouwde testrunner

> Schrijf een test.js die de app start, tests registreert met Test.push(), resultaten controleert met Test.print() en eindigt met een code ongelijk aan nul wanneer er een mislukt.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: nl
Content-SHA256: 1bfc5a3400c131d6b585bd5d2978f9eb80cde32f6bd3045ec1e79465e1899ed1
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

Total.js heeft een kleine testrunner, `total5/test`. Een testbestand is een gewoon Total.js-script: het laadt het framework en de runner, start de applicatie en registreert zijn tests zodra die `ready` is. `Test.push(name, fn)` voegt een test toe; `fn(next)` doet zijn werk en roept `next()` aan om met de volgende verder te gaan. `Test.print(message, error)` meldt één controle: geef `null` als `error` voor succes (`[OK]` wordt afgedrukt) of een bericht voor falen (`[FAIL]` wordt afgedrukt en het proces eindigt met code 1). `Test.run()` voert de geregistreerde tests in volgorde uit en eindigt aan het einde met code 0.

Omdat falen het proces met een code ongelijk aan nul beëindigt, kan het bestand worden aangeroepen door `npm test` en door elke CI-dienst. Wacht na `ready` even (ongeveer 500 ms) voor het eerste verzoek: een direct verstuurd verzoek kan nog een 404 krijgen. Gebruik `RESTBuilder` (of `REQUEST`) tegen de lokale server om routes te testen en roep acties rechtstreeks aan met `ACTION()`.

```js controllers/sum.js
exports.install = function() {
	ROUTE('GET /sum/{a}/{b}/', sum);
	ROUTE('GET /dir/', dir);
};

function sum($) {
	$.json({ total: +$.params.a + +$.params.b });
}

function dir($) {
	$.json({ dir: PATH.root() });
}
```

```js test.js
require('total5');
require('total5/test');

// Another port than the application uses, so both can run
Total.run({ port: 8765, release: false, watcher: false });

ON('ready', function() {

	// A request sent in the same tick as "ready" can still get a 404, so give the routes a moment
	setTimeout(runtests, 500);
});

function runtests() {

	Test.push('The sum route', function(next) {
		RESTBuilder.GET('http://127.0.0.1:8765/sum/2/3/').exec(function(err, response) {
			Test.print('2 + 3 = 5', response && response.total === 5 ? null : 'Expected 5, got ' + JSON.stringify(response));
			next();
		});
	});

	Test.push('Unknown route', function(next) {
		RESTBuilder.GET('http://127.0.0.1:8765/missing/').exec(function(err, response, output) {
			Test.print('/missing/ answers 404', output.status === 404 ? null : 'Expected 404, got ' + output.status);
			next();
		});
	});

	Test.run();
}
```
