Wenn man als Java-Entwickler in den JavaScript-Kosmos eintaucht, dann kann die Auswahl an Test-Bibliotheken für JavaScript etwas verwirrend sein. Im Java-Umfeld sind beispielsweise oft diese Kombination verbreitet:
- JUnit & Mockito: Unit-Tests und Mock-Bibliothek auf Java-Basis
- Cucumber & Selenium: Akzeptanztests nach BDD-Spezifikation (Behavior Driven Development)
- Spock & Geb: Unit-Tests und Akzeptanztests auf Groovy-Basis
Bei JavaScript erscheint mir die Auswahl wegen den unterschiedlichen Umgebungen und JavaScript-Standards schwieriger. Falls das eingesetzte Framework (z.B. Angular) noch keine Standard-Testbibliothek eingebunden hat, können folgende Kriterien für die Auswahl relevant sein:
- handelt es sich um Browser- oder Server-Tests?
- Unterstützung für eingesetze Entwicklungsumgebung vorhanden?
- Unterstützung für das Testen von asynchronen Programmcode nötig?
- wird Unterstützung von Testduplikaten (Stub, Mock, Spy) geboten?
- schnellere Ausführung von Tests durch Parallelisierung möglich?
- bevorzugte Test-Styles (Assert-Style oder BDD-Style) wird unterstützt?
JavaScript Testing Framework
Die Basis für JavaScript-Tests bildet stets ein JavaScript Testing Framework, das zumeist sehr modular aufgebaut ist und für verschiedene Zwecke (z.B. Assertions, Testduplikate, Test-Runner) spezielle Bibliotheken einbindet. Die bekanntesten sind momentan:
- Jasmine (Ursprung: Pivotal Labs, 2011, 15K Github-Stars )
- Jest (Ursprung: Facebook, 2014, 32K Github-Stars)
- Mocha (Ursprung: 2012, 20K Github-Stars )
- QUnit (Ursprung: JQuery-Team, 2010, 4K Github-Stars )
- Ava (Ursprung: 2014, 18K Github-Stars )
Eine schnelle Übersicht zwischen der Kandidaten bietet NPM-Compare, wobei der automatisierte Vergleich nur die NPM-Pakete und Github-Daten vergleichen kann.
Assertion Library
In der Test-Welt haben sich unterschiedliche Schreibstile etabliert, wie ein Test geschrieben und die Werte überprüft werden (Assertion). Die Stile werden von sogenannten Assertion Librarys zur Verfügung gestellt und teilweise von den JavaScript Testing Frameworks verwendet. Bekannte Assertion Librarys sind: Chai, should.js, expect.js und better-assert.

Testduplikate
Testduplikate ersetzen Abhängigkeiten zu anderen Komponenten oder Systemen. Durch den Einsatz von Stubs, Spys oder Mocks werden Tests vereinfacht und ggfs. die Ausführungsgeschwindigkeit beschleunigt. Bekannt Vertreter sind: sinon, testdouble, Jest.fn().
Test Runner
Test Runner sind für die eigentliche Ausführung der Tests verantwortlich. Die angegebenen JavaScript Testing Frameworks bringen die Funktionalität eines Test Runners bereits mit, indem sie die Tests in einer Node-Umgebung oder im Browser ausführen. Um Tests innerhalb von vielen unterschiedlichen Browsern auszuführen, bietet sich der weit verbreitete Test Runner Karma an.
end-to-end Test (E2E-Tests)
Mit end-to-end Tests werden im JavaScript-Umfeld zumeist Tests bezeichnet, in denen eine Applikation im Browser ferngesteuert und überprüft wird. Im Hintergrund sorgt manchmal Selenium/Webdriver für die Steuerung des Browsers, was ein Pro- oder Kontra-Argument für die jeweilige Bibliothek sein kann. Verbreitete E2E-Bibliotheken sind: cypress, TestCafé, Protractor.
Sonstige Bibliotheken
Außerdem gibt es sehr viele Bibliotheken für speziellere Zwecke, die abhängig vom jeweiligen Projekt sehr nützlich sein können:
- Testabdeckung (Test Coverage): Istanbul mit nyc als CLI
- Erzeugung von vielen Fake-Daten: faker.js
- Mutation testing: Stryker
- HTTP-API von Node-Servern: SuperTest
- Mocking ausgehender Anfragen des Node-Servers: Nock
- Consumer driven contract: Pact JS
- Property based testing: JSverify
Welche Bibliotheken soll ich denn jetzt nutzen?
Die Auswahl der passenden Test-Bibliotheken finde ich bei Projektstart zunächst eher zweitrangig und würde einen Kandidaten nehmen, mit dem ich leicht und schnell starten kann. Umstellungen auf andere Bibliotheken sollten später bei Bedarf problemlos möglich sein.
Falls mein eingesetztes Application-Framework entsprechende Bibliotheken bereits mitliefert, würde ich die benutzen. Und ansonsten verwende ich gerne Starter-Projekte mit vorgefertigten und getesten Konfiguration:
- z.B. Angular-Anwendung: Jasmine, Karma, Protractor
- JavaScript: Hackathon-Starter (mit Mocha, Chai, Sinon, Supertest, nyc)
- TypeScript: TypeScript-Starter (mit Jest, Chai)
Wer sich dem Thema „Testen mit JavaScript“ weiter nähern möchte, dem empfehle die folgenden Richtlinien: JavaScript Testing Best Practices