SlideShare a Scribd company logo
1 of 34
Download to read offline
Javascript Unit
Testing
PRESENTED BY
Joerg Reichert
Licensed under cc-by v3.0 (any
jurisdiction)
Einführung
Was sind Unit Tests?
http://xunitpatterns.com/Goals of Test Automation.html
http://xunitpatterns.com/Test Automation Framework.html
Einführung
● Teile der Implementierung (Units) isoliert ausführen
● Ihre Ausführung ist wiederholt, automatisiert möglich
● Spezifizieren und verifizieren erwartetes Input-Output-Verhalten
dieser Units (sind dadurch ein Stück weit Dokumentation (erklärt
allerdings nur das was, nicht das warum)
● Vertrauen in die Richtigkeit der Implementierung erhöhen (Tests
können nur die Existenz von Fehlern belegen, nicht aber deren
Fehlen) und ermöglichen damit angstfreies Refactoring und
Weiterentwicklung ermöglichen (Sicherheitsnetz)
● Ergänzen statische Code-Analyse-Tools und Style-Checker (Linter)
Was sind Unit Tests?
http://tryqa.com/what-are-the-principles-of-testing/
Einführung
https://en.wikipedia.org/wiki/Test-driven_development
Einführung
● Ansatz Test-first / Test-early
● Bessere Modularisierung durch Fokus auf Testbarkeit des Codes
● Sich vorher Gedanken über das gewünschte (auch verkettete)
Eingabe-Ausgabe-Verhalten machen (z.B. Ausgabe der ersten Unit
ist Eingabe der zweiten Unit), gleiches gilt für Ausgangszustände
die durch die Eingaben in Endzustände transformiert werden
● Minimalismus: „Write only code that make the test green“
● Welche Szenarien, Sonderfälle gibt es? Für jede wird ein eigener
Test geschrieben, Äquivalenzklassenbildung mit jeweils einen
Vertreter aus jeder Klasse als Input in einem Test verwendet wird
Test-Driven-Design (TDD)
Einführung
● Minimal: Jeweils nur einen Aspekt testen und verifizieren, dadurch
leichte Verständlichkeit, nur eine Assertion pro Test
● Isoliert: Keine Abhängigkeiten zu anderen Tests, keine Annahmen
über die Ausführungsreihenfolge
● Deterministisch: Gleiches Testresultat auch bei mehrfachen
Ausführen, also keine Abhängigkeit zu Umgebung / Last / Zeit
● Erwartbar: Vereinbaren und Einhalten von (Namens-)Konventionen
beim Schreiben von Tests, dadurch bessere Verständlichkeit von
Tests, vor allem wenn Test fehlschlägt, soll (mögliche) Ursache
und Quelle des Fehlers ersichtlich sein
Test Prinzipien
https://esj.com/articles/2012/09/24/better-unit-testing.aspx
Einführung
● Einfach: Kein Overengineering von Test, Code-Duplikation bei Tests
kann ok sein, Tests sollten nicht so komplex sein, dass sie selbst
eigentlich wieder Tests benötigen würden
● Black-Box: Keine/wenige Annahmen über die Implementierung
treffen - Eingabe-Ausgabe-Verhalten testen, nicht die konkrete
Implementierung (= Black-Box- vs. White-Box-Testing)
● Angemessen: Nicht alles muss getestet werden, Risiko-vs-
Aufwandabschätzung (auch Aufwand für Pflege der Tests)
● Schnell: Keine lange Ausführungszeit, damit oft ausgeführt,
sofortiges Feedback an Entwickler nach jeder Änderung am Code
Test Prinzipien (2)
https://github.com/ghsukumar/SFDC_Best_Practices/wiki/
F.I.R.S.T-Principles-of-Unit-Testing
Einführung
Sind Unit Tests ausreichend?
Quelle: https://giphy.com/gifs/business-productivity-punctures-WO74HAtUC9I40/media
Einführung
Unit Test
Testpyramide
Module Tests
Integration Tests
Akzeptanz Tests
Eigene Implementierung
Externe Libraries / Frameworks
Infrastruktur (Datenbank, Server, Browser)
Javascript
● Testdefinition: Mocha, Jasmine, Jest, QUnit
● Lesbarkeit: Chai
● Isolation: Sinon, Rewire
● Verbesserung der Testausführung: Karma, Grunt, VSCode-Plugins
● Finden fehlender Testabdeckung: Istanbul, js-mutation-testing, grunt-
mutation-testing
● Spezielle test driver: Selenium (Out-of-scope)
Frameworks
Testdefinition
Einfacher Test mit Mocha
https://mochajs.org/
var assert = require('assert');
describe('Array', function() {
describe('#indexOf()', function() {
it('should return -1 when the value is not present', function() {
assert.equal([1,2,3].indexOf(4), -1);
});
});
});
Import
Gruppieren
Test
Ausgangs-zustand
ErwarteteAusgabe
Impl
Aufruf
mit
Eingabe
Zusicherung über erwartete Eingabe und tatsächliche Ausgabe
Testdefinition
Hooks
https://mochajs.org/
describe('hooks', function() {
before(function() { /* runs before all tests in this block */ });
after(function() { /* runs after all tests in this block */ });
beforeEach(function() { /* runs before each test in this block */ });
afterEach(function() { /* runs after each test in this block */ });
// test cases
});
Testdefinition
Asynchroner Test mit Mocha
https://mochajs.org/
...
it('respond with matching records', function(done) {
db.find({type: 'User'}, function(err, res) {
if (err) return done(err);
assert.equal(res.length(), 3);
done();
});
});
done
Callback
Testdefinition
Spezielles
https://mochajs.org/
● Testausführung überspringen: describe.skip(...) / it.skip(...)
● Nur diesen Test ausführen: describe.only(...) / it.only(…) (seit Mocha
3.0 auch mehrfach verwendbar)
● Noch nicht implementierter Test: it(‘Beschreibung‘); (ohne func also)
● Async-await: it('responds with matching records', async function() {
const users = await db.find({ type: 'User' }); … });
● Bei asynchronen Tests statt done callback direkt ein Promise
zurückgeben (z.B. über chai as promise, später erklärt)
Test-Zusicherungen
Chai
https://www.chaijs.com/
● 3 Stile zur Auswahl, um Erwartungen auszudrücken
● Lesbarkeit durch Fluent API und Verkettungs-Möglichkeit
Test-Zusicherungen
Chai Beispiele
https://www.chaijs.com/api/bdd/
● expect({a: 1}).to.deep.equal({a: 1});
aber: expect({a: 1}).to.not.equal({a: 1})
alternativ: expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1});
● expect([{a: 1}]).to.deep.include({a: 1});
aber: expect([{a: 1}]).to.not.include({a: 1});
● expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
aber: expect({x: {a: 1}}).to.not.include({x: {a: 1}});
● expect([{a: 1}]).to.have.deep.members([{a: 1}]);
aber: expect([{a: 1}]).to.not.have.members([{a: 1}]);
Test-Zusicherungen
Chai Beispiele (2)
https://www.chaijs.com/api/bdd/
● expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
● expect({a: 3}).to.have.property('a', 3);
● expect('foo').to.be.a('string'); // Typvergleich
● expect('foobar').to.include('foo') / expect([1, 2, 3]).to.include(2)
● expect(true).to.be.true; / expect(false).to.be.false; /
expect(null).to.be.null; / expect([]).to.be.empty;
● expect('foo').to.have.lengthOf(3);
● expect('foobar').to.match(/^foo/);
● expect(badFn).to.throw(err, 'salmon')
● expect.fail("custom error message");
Test-Zusicherungen
Behavior driven design (BDD)
https://en.wikipedia.org/wiki/Behavior-driven_development
Story vs. Specification
Testen in Isolation
● Wann einsetzen?: Zum Testen von Funktionen, die Seiteneffekte
verursachen, d.h. die während der Ausführung weitere
Funktionen aufruft, die wir aber nicht (weil externe Bibliothek)
oder separat testen wollen (da Teil einer anderen Unit)
● Spy: verifizieren, ob, wie oft und mit welchen Argumenten eine
abhängige Funktion während der Ausführung aufgerufen wurde,
die original Funktion wird dabei nicht ausgetauscht
● Stub: abhängige Funktion wird durch einen Dummy ausgetauscht,
um z.B. den Aufruf der Datenbank im Test zu verhindern
● Mock: wie Stub, kann aber fixierte Eingaben-Ausgaben festlegen
Spys, Stubs, Mocks
https://semaphoreci.com/community/tutorials/best
-practices-for-spies-stubs-and-mocks-in-sinon-js
Testen in Isolation
Spys, Stubs, Fakes, Mocks (2)
http://xunitpatterns.com/Mocks, Fakes, Stubs and Dummies.html
Testen in Isolation
const sinon = require('sinon');
it('should call save once', function() {
const saveSpy = sinon.spy(Database, 'save');
funcToTest(saveSpy)
saveSpy.restore();
sinon.assert.calledOnce(saveSpy);
const call = saveSpy.getCall(0);
expect(call.args[0]).to.equal(expectedUser);
});
Sinon Spy
https://sinonjs.org/
Import
Spy at property save
of object Database
Pass spy as parameter
Remove spy
First call to save
First argumentof that first call
https://sinonjs.org/releases/v7.2.2/spies/
Testen in Isolation
const sinon = require('sinon');
it('should call save once', function() {
const saveStub = sinon.stub(Database, 'save');
funcToTest(saveSpy)
saveStub.restore();
sinon.assert.calledOnce(saveStub);
const saveStub2 = sinon.stub(Database, 'save');
saveStub2.throws(new Error('oops'));
funcToTest(saveStub2)
});
Sinon Stub
https://sinonjs.org/releases/v7.2.2/stubs/
Import
Stub property save of
object Database
Pass stub as parameter
Remove stub
Use stub to issueerror when called and
assert behavior
Testen in Isolation
const sinon = require('sinon');
it('should call save once', function() {
const dbMock = sinon.mock(Database);
dbMock.expects('save').once().withArgs(expectedUser);
funcToTest(dbMock)
dbMock.verify();
dbMock.restore();
});
Sinon Mock
https://sinonjs.org/releases/v7.2.2/mocks/
Import
Mock object Database
Pass mock as parameter
Remove mock
Mock call to save
Verify expected call
Testen in Isolation
const sinon = require('sinon');
it('should fake it', function() {
const fake = sinon.fake.returns('apple pie');
expect(fake()).to.equal('apple pie');
expect(fake.callCount).to.equal(1);
var fake2 = sinon.fake.returns('42');
sinon.replace(console, 'log', fake2);
console.log('apple pie'); // prints ‚42‘
sinon.restore();
});
Sinon Fake
https://sinonjs.org/releases/v7.2.2/fakes/
Import
Create fake
Remove replacement
with fake
Call to fake returns stringFake grabs its call count
Replace existing property with fake
Testen in Isolation
const fs = require(‘fs‘);
...
„Rewire“ module dependencies in tests
https://github.com/jhnns/rewire
const rewire = require("rewire");
const myModule = rewire("../path/to/myModule.js");
const fsMock = ...
myModule.__set__("fs", fsMock);
myModule.js
myModuleTest.js
Testabdeckung
● instrumentiert ES5 und ES2015+ JavaScript code mit
Zeilennummeriung, so dass nachvollzogen werden kann, wie gut
die bestehenden Tests die
Implementierung abdecken
Istanbul
Testabdeckung
● Code coverage != Assertion coverage: kann also Tests schreiben,
die den gesamten Code ausführen, ohne die produzierten
(Zwischen-)Zustände und Ausgabe zu prüfen
● Dateien, für die gar keine Tests existieren, wirken sich nicht
negativ auf Code coverage aus (Javascript feature)
● Mutation testing injiziert Fehler in die
Codebasis (z.B. durch Kippen von
Boolean-Ausdrücken) und prüft, ob
diese Änderungen durch bestehende
Tests gefunden werden, die dann
fehlschlagen sollten
Mutation testing
https://en.wikipedia.org/wiki/Mutation_testing
https://www.researchgate.net/figure/Mutation-testing-procedure_fig1_279174620
Testabdeckung
● Code coverage != Assertion coverage: kann also Tests schreiben,
die den gesamten Code ausführen, ohne die produzierten
(Zwischen-)Zustände und Ausgabe zu prüfen
● Dateien, für die gar keine Tests existieren, wirken sich nicht
negativ auf Code coverage aus (Javascript feature)
● Mutation testing injiziert Fehler in die
Codebasis (z.B. durch Kippen von
Boolean-Ausdrücken) und prüft, ob
diese Änderungen durch bestehende
Tests gefunden werden, die dann
fehlschlagen sollten
Mutation testing
https://en.wikipedia.org/wiki/Mutation_testing
https://www.researchgate.net/figure/Mutation-testing-procedure_fig1_279174620
Erweiterte Testausführung
● Tests in a loop: Tests sofort bei jedem Speichern einer Datei im
Projekt ausführen (in Javascript ist das initialen Laden aller
Testdateien ziemlich langsam)
● Testen in verschiedenen Browsern / Plattformen
● Vorbereitende Aktionen ausführen, bevor die Tests ausgeführt
werden (z.B. Browser starten, Telegram Anwendung starten)
● https://blog.mayflower.de/4333-Karma-Testrunner-Einfuehrung.ht
ml
● https://www.npmjs.com/search?q=keywords:karma-plugin
Karma
https://github.com/karma-runner/karma
https://karma-runner.github.io/latest/index.html
Integration in VSCode
Plugins
ID Name
sourcegraph.javascript-typescript JavaScript and TypeScript IntelliSense
leizongmin.node-module-intellisense Node.js Modules Intellisense
xabikos.javascriptsnippets JavaScript (ES6) code snippets
christian-kohler.npm-intellisense npm Intellisense
christian-kohler.path-intellisense Path Intellisense
IntelliSense / Code snippets
Sonstiges
ID Name
dai-shi.vscode-es-beautifier es-beautifier
fabiospampinato.vscode-git-history Git File History
https://marketplace.visualstudio.com/search?term=javascript&t
arget=VSCode&category=All categories&sortBy=Relevance
Integration in VSCode
Plugins
ID Name
spoonscen.es6-mocha-snippets ES6 Mocha Snippets
hbenl.vscode-test-explorer Test Explorer UI
hbenl.vscode-mocha-test-adapter Mocha Test Explorer
rintoj.chai-spec-generator Test Spec Generator
markis.code-coverage Code Coverage
Testen
ID Name
dbaeumer.vscode-eslint ESLint
chenxsan.vscode-standardjs StandardJS - JavaScript Standard Style
Lint
Integration in VSCode
https://github.com/eisc/fancy_LVB_Telegram_Bot
Zusammenfassung
● Tests einfach halten
● Black Box Tests bevorzugen gegenüber White-Box-Tests
● Vermeiden von Interacting Tests durch Zurücksetzen von
Zuständen und Mocks in before, beforeEach, afterEach und/oder
after mit sinon.resetAll oder reset am gestubten/gemockten
Objekt
● Tests im automatisierten Build (z.B. über TravisCI) mitlaufen
lassen, nur Release bauen und releasen, wenn alle Tests grün
sind
Best practices
http://tryqa.com/what-are-the-principles-of-testing/
Zusammenfassung
● Äquivalenz-Klassen bilden, z.B. jeweils Stellvertreter-Eingaben
finden, bei der z.B. die Teilbedingungen von if-Statements im
getesteten Code in allen Kombinationen durchlaufen werden
(Zeilen-, Zweig-, Pfad-Abdeckung)
● immer mit Kopien bei Expectations und Eingaben arbeiten, damit
man nicht versehentlich die durch die Implementierung
veränderte Eingabe als erwarteten Vergleichswert nutzt
● Spread-Operator nutzen, um neue Varianten von Testdaten zu
erzeugen
● Komplexe Testdaten aus JSON-Datei in Tests importieren
Best practices (2)
https://developer.mozilla.org/de/docs/Web/Java
Script/Reference/Operators/Spread_operator

More Related Content

What's hot

Testing untestable code - PHPUGFFM 01/11
Testing untestable code - PHPUGFFM 01/11Testing untestable code - PHPUGFFM 01/11
Testing untestable code - PHPUGFFM 01/11Stephan Hochdörfer
 
Unit Tests für Totalverweigerer
Unit Tests für TotalverweigererUnit Tests für Totalverweigerer
Unit Tests für TotalverweigererPeter Hauke
 
Test-driven Development mit TYPO3
Test-driven Development mit TYPO3Test-driven Development mit TYPO3
Test-driven Development mit TYPO3Oliver Klee
 
OSMC 2014: Plugin Entwicklung für Einsteiger | Alexander Wirt
OSMC 2014: Plugin Entwicklung für Einsteiger | Alexander WirtOSMC 2014: Plugin Entwicklung für Einsteiger | Alexander Wirt
OSMC 2014: Plugin Entwicklung für Einsteiger | Alexander WirtNETWAYS
 
TYPO3 5.0 - Der aktuelle Stand der Zukunft
TYPO3 5.0 - Der aktuelle Stand der ZukunftTYPO3 5.0 - Der aktuelle Stand der Zukunft
TYPO3 5.0 - Der aktuelle Stand der ZukunftJochen Rau
 
Feige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-UmfeldFeige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-Umfeldgedoplan
 
Puppet - Entwicklungsworkflow und Basismodule
Puppet - Entwicklungsworkflow und BasismodulePuppet - Entwicklungsworkflow und Basismodule
Puppet - Entwicklungsworkflow und Basismoduleinovex GmbH
 
Ausweg aus der Kommunikationskrise oder das Ende von „Bei mir funktioniert’s“?
Ausweg aus der Kommunikationskrise oder das Ende von „Bei mir funktioniert’s“?Ausweg aus der Kommunikationskrise oder das Ende von „Bei mir funktioniert’s“?
Ausweg aus der Kommunikationskrise oder das Ende von „Bei mir funktioniert’s“?Nico Orschel
 
JSF Testing - Tools und Technics
JSF Testing - Tools und TechnicsJSF Testing - Tools und Technics
JSF Testing - Tools und Technicsadesso AG
 
Was ist neu in Java 6, 7, 8, ...
Was ist neu in Java 6, 7, 8, ...Was ist neu in Java 6, 7, 8, ...
Was ist neu in Java 6, 7, 8, ...Andreas Schreiber
 
Automatisierter Software-Test unter Java
Automatisierter Software-Test unter JavaAutomatisierter Software-Test unter Java
Automatisierter Software-Test unter JavaGFU Cyrus AG
 
Was Software-Archive erzählen
Was Software-Archive erzählenWas Software-Archive erzählen
Was Software-Archive erzählenThomas Zimmermann
 
Lösungsorientierte Fehlerbehandlung
Lösungsorientierte FehlerbehandlungLösungsorientierte Fehlerbehandlung
Lösungsorientierte Fehlerbehandlungroskakori
 
PL SQL Unit Tests mit SQL Developer
PL SQL Unit Tests mit SQL DeveloperPL SQL Unit Tests mit SQL Developer
PL SQL Unit Tests mit SQL DeveloperTrivadis
 

What's hot (17)

Testing untestable code - PHPUGFFM 01/11
Testing untestable code - PHPUGFFM 01/11Testing untestable code - PHPUGFFM 01/11
Testing untestable code - PHPUGFFM 01/11
 
Unit Tests für Totalverweigerer
Unit Tests für TotalverweigererUnit Tests für Totalverweigerer
Unit Tests für Totalverweigerer
 
Automatisierungmit NANT
Automatisierungmit NANTAutomatisierungmit NANT
Automatisierungmit NANT
 
Test-driven Development mit TYPO3
Test-driven Development mit TYPO3Test-driven Development mit TYPO3
Test-driven Development mit TYPO3
 
OSMC 2014: Plugin Entwicklung für Einsteiger | Alexander Wirt
OSMC 2014: Plugin Entwicklung für Einsteiger | Alexander WirtOSMC 2014: Plugin Entwicklung für Einsteiger | Alexander Wirt
OSMC 2014: Plugin Entwicklung für Einsteiger | Alexander Wirt
 
Test-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetpro
Test-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetproTest-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetpro
Test-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetpro
 
TYPO3 5.0 - Der aktuelle Stand der Zukunft
TYPO3 5.0 - Der aktuelle Stand der ZukunftTYPO3 5.0 - Der aktuelle Stand der Zukunft
TYPO3 5.0 - Der aktuelle Stand der Zukunft
 
Feige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-UmfeldFeige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-Umfeld
 
Testing tools
Testing toolsTesting tools
Testing tools
 
Puppet - Entwicklungsworkflow und Basismodule
Puppet - Entwicklungsworkflow und BasismodulePuppet - Entwicklungsworkflow und Basismodule
Puppet - Entwicklungsworkflow und Basismodule
 
Ausweg aus der Kommunikationskrise oder das Ende von „Bei mir funktioniert’s“?
Ausweg aus der Kommunikationskrise oder das Ende von „Bei mir funktioniert’s“?Ausweg aus der Kommunikationskrise oder das Ende von „Bei mir funktioniert’s“?
Ausweg aus der Kommunikationskrise oder das Ende von „Bei mir funktioniert’s“?
 
JSF Testing - Tools und Technics
JSF Testing - Tools und TechnicsJSF Testing - Tools und Technics
JSF Testing - Tools und Technics
 
Was ist neu in Java 6, 7, 8, ...
Was ist neu in Java 6, 7, 8, ...Was ist neu in Java 6, 7, 8, ...
Was ist neu in Java 6, 7, 8, ...
 
Automatisierter Software-Test unter Java
Automatisierter Software-Test unter JavaAutomatisierter Software-Test unter Java
Automatisierter Software-Test unter Java
 
Was Software-Archive erzählen
Was Software-Archive erzählenWas Software-Archive erzählen
Was Software-Archive erzählen
 
Lösungsorientierte Fehlerbehandlung
Lösungsorientierte FehlerbehandlungLösungsorientierte Fehlerbehandlung
Lösungsorientierte Fehlerbehandlung
 
PL SQL Unit Tests mit SQL Developer
PL SQL Unit Tests mit SQL DeveloperPL SQL Unit Tests mit SQL Developer
PL SQL Unit Tests mit SQL Developer
 

Similar to Unit testing mit Javascript

AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTddjlink
 
Testgetriebene Softwareentwicklung
Testgetriebene SoftwareentwicklungTestgetriebene Softwareentwicklung
Testgetriebene Softwareentwicklungjlink
 
Der Tod der Testpyramide? – Frontend-Testing mit Playwright
Der Tod der Testpyramide? – Frontend-Testing mit PlaywrightDer Tod der Testpyramide? – Frontend-Testing mit Playwright
Der Tod der Testpyramide? – Frontend-Testing mit PlaywrightQAware GmbH
 
Einführung Vorgehensmodelle und Agile Software Entwicklung
Einführung Vorgehensmodelle und Agile Software EntwicklungEinführung Vorgehensmodelle und Agile Software Entwicklung
Einführung Vorgehensmodelle und Agile Software EntwicklungChristian Baranowski
 
96% macoun 2013
96% macoun 201396% macoun 2013
96% macoun 2013Maxim Zaks
 
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017Torsten Kleiber
 
BASTA 2016 - Alternativen zu Visual-Studio-Testtools: Wann lohnt es sich auch...
BASTA 2016 - Alternativen zu Visual-Studio-Testtools: Wann lohnt es sich auch...BASTA 2016 - Alternativen zu Visual-Studio-Testtools: Wann lohnt es sich auch...
BASTA 2016 - Alternativen zu Visual-Studio-Testtools: Wann lohnt es sich auch...Marc Müller
 
Softwarequalitätssicherung mit Continuous Integration Tools
 Softwarequalitätssicherung mit Continuous Integration Tools Softwarequalitätssicherung mit Continuous Integration Tools
Softwarequalitätssicherung mit Continuous Integration Toolsgedoplan
 
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10Ralf Sigmund
 
Besseren Java Code mit Type Annotations
Besseren Java Code mit Type AnnotationsBesseren Java Code mit Type Annotations
Besseren Java Code mit Type Annotationsdzuvic
 
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?Marc Müller
 
Die nächste Generation des Unit Testing
Die nächste Generation des Unit TestingDie nächste Generation des Unit Testing
Die nächste Generation des Unit TestingDaniel Lehner
 
Ringvorlesung ITmitte.de : Vortrag der FIO SYSTEMS AG über Unit Tests und TDD
Ringvorlesung ITmitte.de : Vortrag der FIO SYSTEMS AG über Unit Tests und TDDRingvorlesung ITmitte.de : Vortrag der FIO SYSTEMS AG über Unit Tests und TDD
Ringvorlesung ITmitte.de : Vortrag der FIO SYSTEMS AG über Unit Tests und TDDCommunity ITmitte.de
 
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?Marc Müller
 
Real Application Testing - DOAG SIG Database 2010 - Simon Dickmeiß
Real Application Testing - DOAG SIG Database 2010 - Simon DickmeißReal Application Testing - DOAG SIG Database 2010 - Simon Dickmeiß
Real Application Testing - DOAG SIG Database 2010 - Simon DickmeißOPITZ CONSULTING Deutschland
 
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)Florian Wolters
 
130605 blog - drools
130605   blog - drools130605   blog - drools
130605 blog - droolsjava-pe
 
Objektvalidierung mit dem Bean Validation Api
Objektvalidierung mit dem Bean Validation ApiObjektvalidierung mit dem Bean Validation Api
Objektvalidierung mit dem Bean Validation Apigunnarmorling
 

Similar to Unit testing mit Javascript (20)

AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTdd
 
Testgetriebene Softwareentwicklung
Testgetriebene SoftwareentwicklungTestgetriebene Softwareentwicklung
Testgetriebene Softwareentwicklung
 
Der Tod der Testpyramide? – Frontend-Testing mit Playwright
Der Tod der Testpyramide? – Frontend-Testing mit PlaywrightDer Tod der Testpyramide? – Frontend-Testing mit Playwright
Der Tod der Testpyramide? – Frontend-Testing mit Playwright
 
Einführung Vorgehensmodelle und Agile Software Entwicklung
Einführung Vorgehensmodelle und Agile Software EntwicklungEinführung Vorgehensmodelle und Agile Software Entwicklung
Einführung Vorgehensmodelle und Agile Software Entwicklung
 
96% macoun 2013
96% macoun 201396% macoun 2013
96% macoun 2013
 
Agiles Testen - Überblick
Agiles Testen - ÜberblickAgiles Testen - Überblick
Agiles Testen - Überblick
 
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
Plsql drum test automatisiere, wer sich sich ewig bindet! - DOAG 2017
 
BASTA 2016 - Alternativen zu Visual-Studio-Testtools: Wann lohnt es sich auch...
BASTA 2016 - Alternativen zu Visual-Studio-Testtools: Wann lohnt es sich auch...BASTA 2016 - Alternativen zu Visual-Studio-Testtools: Wann lohnt es sich auch...
BASTA 2016 - Alternativen zu Visual-Studio-Testtools: Wann lohnt es sich auch...
 
Softwarequalitätssicherung mit Continuous Integration Tools
 Softwarequalitätssicherung mit Continuous Integration Tools Softwarequalitätssicherung mit Continuous Integration Tools
Softwarequalitätssicherung mit Continuous Integration Tools
 
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
Wjax integrationsprojekte auf dem weg zur continuous delivery 2011 11-10
 
Besseren Java Code mit Type Annotations
Besseren Java Code mit Type AnnotationsBesseren Java Code mit Type Annotations
Besseren Java Code mit Type Annotations
 
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
 
Die nächste Generation des Unit Testing
Die nächste Generation des Unit TestingDie nächste Generation des Unit Testing
Die nächste Generation des Unit Testing
 
Ringvorlesung ITmitte.de : Vortrag der FIO SYSTEMS AG über Unit Tests und TDD
Ringvorlesung ITmitte.de : Vortrag der FIO SYSTEMS AG über Unit Tests und TDDRingvorlesung ITmitte.de : Vortrag der FIO SYSTEMS AG über Unit Tests und TDD
Ringvorlesung ITmitte.de : Vortrag der FIO SYSTEMS AG über Unit Tests und TDD
 
Property Based Testing
Property Based TestingProperty Based Testing
Property Based Testing
 
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
 
Real Application Testing - DOAG SIG Database 2010 - Simon Dickmeiß
Real Application Testing - DOAG SIG Database 2010 - Simon DickmeißReal Application Testing - DOAG SIG Database 2010 - Simon Dickmeiß
Real Application Testing - DOAG SIG Database 2010 - Simon Dickmeiß
 
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
Automatisiertes Testen von Software in C++ (mit dem Test Framework Google Test)
 
130605 blog - drools
130605   blog - drools130605   blog - drools
130605 blog - drools
 
Objektvalidierung mit dem Bean Validation Api
Objektvalidierung mit dem Bean Validation ApiObjektvalidierung mit dem Bean Validation Api
Objektvalidierung mit dem Bean Validation Api
 

More from joergreichert

OKLab Leipzig - 2023 Update
OKLab Leipzig - 2023 UpdateOKLab Leipzig - 2023 Update
OKLab Leipzig - 2023 Updatejoergreichert
 
SDGs und wo sind die Daten?
SDGs und wo sind die Daten?SDGs und wo sind die Daten?
SDGs und wo sind die Daten?joergreichert
 
Gieß a bit more the Bäume
Gieß a bit more the BäumeGieß a bit more the Bäume
Gieß a bit more the Bäumejoergreichert
 
Leipzig Giesst (Dezember 2020)
Leipzig Giesst (Dezember 2020)Leipzig Giesst (Dezember 2020)
Leipzig Giesst (Dezember 2020)joergreichert
 
OKLab Leipzig - Schwerpunkt Mobilität
OKLab Leipzig - Schwerpunkt MobilitätOKLab Leipzig - Schwerpunkt Mobilität
OKLab Leipzig - Schwerpunkt Mobilitätjoergreichert
 
Die Stadt als Schule der Demokratie
Die Stadt als Schule der DemokratieDie Stadt als Schule der Demokratie
Die Stadt als Schule der Demokratiejoergreichert
 
OKLab Leipzig (2019 Update)
OKLab Leipzig (2019 Update)OKLab Leipzig (2019 Update)
OKLab Leipzig (2019 Update)joergreichert
 
A Pattern Language - Patterns for Javascript
A Pattern Language - Patterns for JavascriptA Pattern Language - Patterns for Javascript
A Pattern Language - Patterns for Javascriptjoergreichert
 
OkLab Leipzig (2018 Update)
OkLab Leipzig (2018 Update)OkLab Leipzig (2018 Update)
OkLab Leipzig (2018 Update)joergreichert
 
OkLab Leipzig (state: 2017)
OkLab Leipzig (state: 2017)OkLab Leipzig (state: 2017)
OkLab Leipzig (state: 2017)joergreichert
 
Mongo DB schema design patterns
Mongo DB schema design patternsMongo DB schema design patterns
Mongo DB schema design patternsjoergreichert
 
Using openArchitectureWare 4.0 in domain "registration"
Using openArchitectureWare 4.0 in domain "registration"Using openArchitectureWare 4.0 in domain "registration"
Using openArchitectureWare 4.0 in domain "registration"joergreichert
 

More from joergreichert (20)

OKLab Leipzig - 2023 Update
OKLab Leipzig - 2023 UpdateOKLab Leipzig - 2023 Update
OKLab Leipzig - 2023 Update
 
SDGs und wo sind die Daten?
SDGs und wo sind die Daten?SDGs und wo sind die Daten?
SDGs und wo sind die Daten?
 
Gieß a bit more the Bäume
Gieß a bit more the BäumeGieß a bit more the Bäume
Gieß a bit more the Bäume
 
OKLab Leipzig 2022
OKLab Leipzig 2022OKLab Leipzig 2022
OKLab Leipzig 2022
 
FAIRe Sensordaten
FAIRe SensordatenFAIRe Sensordaten
FAIRe Sensordaten
 
OKLab Leipzig 2021
OKLab Leipzig 2021OKLab Leipzig 2021
OKLab Leipzig 2021
 
Leipzig Giesst (Dezember 2020)
Leipzig Giesst (Dezember 2020)Leipzig Giesst (Dezember 2020)
Leipzig Giesst (Dezember 2020)
 
Road to mauAR
Road to mauARRoad to mauAR
Road to mauAR
 
OKLab Leipzig - Schwerpunkt Mobilität
OKLab Leipzig - Schwerpunkt MobilitätOKLab Leipzig - Schwerpunkt Mobilität
OKLab Leipzig - Schwerpunkt Mobilität
 
Die Stadt als Schule der Demokratie
Die Stadt als Schule der DemokratieDie Stadt als Schule der Demokratie
Die Stadt als Schule der Demokratie
 
OKLab Leipzig (2019 Update)
OKLab Leipzig (2019 Update)OKLab Leipzig (2019 Update)
OKLab Leipzig (2019 Update)
 
A Pattern Language - Patterns for Javascript
A Pattern Language - Patterns for JavascriptA Pattern Language - Patterns for Javascript
A Pattern Language - Patterns for Javascript
 
damals.in/leipzig
damals.in/leipzigdamals.in/leipzig
damals.in/leipzig
 
OkLab Leipzig (2018 Update)
OkLab Leipzig (2018 Update)OkLab Leipzig (2018 Update)
OkLab Leipzig (2018 Update)
 
Map technologies
Map technologiesMap technologies
Map technologies
 
OkLab Leipzig (state: 2017)
OkLab Leipzig (state: 2017)OkLab Leipzig (state: 2017)
OkLab Leipzig (state: 2017)
 
Mongo DB schema design patterns
Mongo DB schema design patternsMongo DB schema design patterns
Mongo DB schema design patterns
 
MOOCs
MOOCsMOOCs
MOOCs
 
Log4j2
Log4j2Log4j2
Log4j2
 
Using openArchitectureWare 4.0 in domain "registration"
Using openArchitectureWare 4.0 in domain "registration"Using openArchitectureWare 4.0 in domain "registration"
Using openArchitectureWare 4.0 in domain "registration"
 

Unit testing mit Javascript

  • 1. Javascript Unit Testing PRESENTED BY Joerg Reichert Licensed under cc-by v3.0 (any jurisdiction)
  • 2. Einführung Was sind Unit Tests? http://xunitpatterns.com/Goals of Test Automation.html http://xunitpatterns.com/Test Automation Framework.html
  • 3. Einführung ● Teile der Implementierung (Units) isoliert ausführen ● Ihre Ausführung ist wiederholt, automatisiert möglich ● Spezifizieren und verifizieren erwartetes Input-Output-Verhalten dieser Units (sind dadurch ein Stück weit Dokumentation (erklärt allerdings nur das was, nicht das warum) ● Vertrauen in die Richtigkeit der Implementierung erhöhen (Tests können nur die Existenz von Fehlern belegen, nicht aber deren Fehlen) und ermöglichen damit angstfreies Refactoring und Weiterentwicklung ermöglichen (Sicherheitsnetz) ● Ergänzen statische Code-Analyse-Tools und Style-Checker (Linter) Was sind Unit Tests? http://tryqa.com/what-are-the-principles-of-testing/
  • 5. Einführung ● Ansatz Test-first / Test-early ● Bessere Modularisierung durch Fokus auf Testbarkeit des Codes ● Sich vorher Gedanken über das gewünschte (auch verkettete) Eingabe-Ausgabe-Verhalten machen (z.B. Ausgabe der ersten Unit ist Eingabe der zweiten Unit), gleiches gilt für Ausgangszustände die durch die Eingaben in Endzustände transformiert werden ● Minimalismus: „Write only code that make the test green“ ● Welche Szenarien, Sonderfälle gibt es? Für jede wird ein eigener Test geschrieben, Äquivalenzklassenbildung mit jeweils einen Vertreter aus jeder Klasse als Input in einem Test verwendet wird Test-Driven-Design (TDD)
  • 6. Einführung ● Minimal: Jeweils nur einen Aspekt testen und verifizieren, dadurch leichte Verständlichkeit, nur eine Assertion pro Test ● Isoliert: Keine Abhängigkeiten zu anderen Tests, keine Annahmen über die Ausführungsreihenfolge ● Deterministisch: Gleiches Testresultat auch bei mehrfachen Ausführen, also keine Abhängigkeit zu Umgebung / Last / Zeit ● Erwartbar: Vereinbaren und Einhalten von (Namens-)Konventionen beim Schreiben von Tests, dadurch bessere Verständlichkeit von Tests, vor allem wenn Test fehlschlägt, soll (mögliche) Ursache und Quelle des Fehlers ersichtlich sein Test Prinzipien https://esj.com/articles/2012/09/24/better-unit-testing.aspx
  • 7. Einführung ● Einfach: Kein Overengineering von Test, Code-Duplikation bei Tests kann ok sein, Tests sollten nicht so komplex sein, dass sie selbst eigentlich wieder Tests benötigen würden ● Black-Box: Keine/wenige Annahmen über die Implementierung treffen - Eingabe-Ausgabe-Verhalten testen, nicht die konkrete Implementierung (= Black-Box- vs. White-Box-Testing) ● Angemessen: Nicht alles muss getestet werden, Risiko-vs- Aufwandabschätzung (auch Aufwand für Pflege der Tests) ● Schnell: Keine lange Ausführungszeit, damit oft ausgeführt, sofortiges Feedback an Entwickler nach jeder Änderung am Code Test Prinzipien (2) https://github.com/ghsukumar/SFDC_Best_Practices/wiki/ F.I.R.S.T-Principles-of-Unit-Testing
  • 8. Einführung Sind Unit Tests ausreichend? Quelle: https://giphy.com/gifs/business-productivity-punctures-WO74HAtUC9I40/media
  • 9. Einführung Unit Test Testpyramide Module Tests Integration Tests Akzeptanz Tests Eigene Implementierung Externe Libraries / Frameworks Infrastruktur (Datenbank, Server, Browser)
  • 10. Javascript ● Testdefinition: Mocha, Jasmine, Jest, QUnit ● Lesbarkeit: Chai ● Isolation: Sinon, Rewire ● Verbesserung der Testausführung: Karma, Grunt, VSCode-Plugins ● Finden fehlender Testabdeckung: Istanbul, js-mutation-testing, grunt- mutation-testing ● Spezielle test driver: Selenium (Out-of-scope) Frameworks
  • 11. Testdefinition Einfacher Test mit Mocha https://mochajs.org/ var assert = require('assert'); describe('Array', function() { describe('#indexOf()', function() { it('should return -1 when the value is not present', function() { assert.equal([1,2,3].indexOf(4), -1); }); }); }); Import Gruppieren Test Ausgangs-zustand ErwarteteAusgabe Impl Aufruf mit Eingabe Zusicherung über erwartete Eingabe und tatsächliche Ausgabe
  • 12. Testdefinition Hooks https://mochajs.org/ describe('hooks', function() { before(function() { /* runs before all tests in this block */ }); after(function() { /* runs after all tests in this block */ }); beforeEach(function() { /* runs before each test in this block */ }); afterEach(function() { /* runs after each test in this block */ }); // test cases });
  • 13. Testdefinition Asynchroner Test mit Mocha https://mochajs.org/ ... it('respond with matching records', function(done) { db.find({type: 'User'}, function(err, res) { if (err) return done(err); assert.equal(res.length(), 3); done(); }); }); done Callback
  • 14. Testdefinition Spezielles https://mochajs.org/ ● Testausführung überspringen: describe.skip(...) / it.skip(...) ● Nur diesen Test ausführen: describe.only(...) / it.only(…) (seit Mocha 3.0 auch mehrfach verwendbar) ● Noch nicht implementierter Test: it(‘Beschreibung‘); (ohne func also) ● Async-await: it('responds with matching records', async function() { const users = await db.find({ type: 'User' }); … }); ● Bei asynchronen Tests statt done callback direkt ein Promise zurückgeben (z.B. über chai as promise, später erklärt)
  • 15. Test-Zusicherungen Chai https://www.chaijs.com/ ● 3 Stile zur Auswahl, um Erwartungen auszudrücken ● Lesbarkeit durch Fluent API und Verkettungs-Möglichkeit
  • 16. Test-Zusicherungen Chai Beispiele https://www.chaijs.com/api/bdd/ ● expect({a: 1}).to.deep.equal({a: 1}); aber: expect({a: 1}).to.not.equal({a: 1}) alternativ: expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); ● expect([{a: 1}]).to.deep.include({a: 1}); aber: expect([{a: 1}]).to.not.include({a: 1}); ● expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); aber: expect({x: {a: 1}}).to.not.include({x: {a: 1}}); ● expect([{a: 1}]).to.have.deep.members([{a: 1}]); aber: expect([{a: 1}]).to.not.have.members([{a: 1}]);
  • 17. Test-Zusicherungen Chai Beispiele (2) https://www.chaijs.com/api/bdd/ ● expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); ● expect({a: 3}).to.have.property('a', 3); ● expect('foo').to.be.a('string'); // Typvergleich ● expect('foobar').to.include('foo') / expect([1, 2, 3]).to.include(2) ● expect(true).to.be.true; / expect(false).to.be.false; / expect(null).to.be.null; / expect([]).to.be.empty; ● expect('foo').to.have.lengthOf(3); ● expect('foobar').to.match(/^foo/); ● expect(badFn).to.throw(err, 'salmon') ● expect.fail("custom error message");
  • 18. Test-Zusicherungen Behavior driven design (BDD) https://en.wikipedia.org/wiki/Behavior-driven_development Story vs. Specification
  • 19. Testen in Isolation ● Wann einsetzen?: Zum Testen von Funktionen, die Seiteneffekte verursachen, d.h. die während der Ausführung weitere Funktionen aufruft, die wir aber nicht (weil externe Bibliothek) oder separat testen wollen (da Teil einer anderen Unit) ● Spy: verifizieren, ob, wie oft und mit welchen Argumenten eine abhängige Funktion während der Ausführung aufgerufen wurde, die original Funktion wird dabei nicht ausgetauscht ● Stub: abhängige Funktion wird durch einen Dummy ausgetauscht, um z.B. den Aufruf der Datenbank im Test zu verhindern ● Mock: wie Stub, kann aber fixierte Eingaben-Ausgaben festlegen Spys, Stubs, Mocks https://semaphoreci.com/community/tutorials/best -practices-for-spies-stubs-and-mocks-in-sinon-js
  • 20. Testen in Isolation Spys, Stubs, Fakes, Mocks (2) http://xunitpatterns.com/Mocks, Fakes, Stubs and Dummies.html
  • 21. Testen in Isolation const sinon = require('sinon'); it('should call save once', function() { const saveSpy = sinon.spy(Database, 'save'); funcToTest(saveSpy) saveSpy.restore(); sinon.assert.calledOnce(saveSpy); const call = saveSpy.getCall(0); expect(call.args[0]).to.equal(expectedUser); }); Sinon Spy https://sinonjs.org/ Import Spy at property save of object Database Pass spy as parameter Remove spy First call to save First argumentof that first call https://sinonjs.org/releases/v7.2.2/spies/
  • 22. Testen in Isolation const sinon = require('sinon'); it('should call save once', function() { const saveStub = sinon.stub(Database, 'save'); funcToTest(saveSpy) saveStub.restore(); sinon.assert.calledOnce(saveStub); const saveStub2 = sinon.stub(Database, 'save'); saveStub2.throws(new Error('oops')); funcToTest(saveStub2) }); Sinon Stub https://sinonjs.org/releases/v7.2.2/stubs/ Import Stub property save of object Database Pass stub as parameter Remove stub Use stub to issueerror when called and assert behavior
  • 23. Testen in Isolation const sinon = require('sinon'); it('should call save once', function() { const dbMock = sinon.mock(Database); dbMock.expects('save').once().withArgs(expectedUser); funcToTest(dbMock) dbMock.verify(); dbMock.restore(); }); Sinon Mock https://sinonjs.org/releases/v7.2.2/mocks/ Import Mock object Database Pass mock as parameter Remove mock Mock call to save Verify expected call
  • 24. Testen in Isolation const sinon = require('sinon'); it('should fake it', function() { const fake = sinon.fake.returns('apple pie'); expect(fake()).to.equal('apple pie'); expect(fake.callCount).to.equal(1); var fake2 = sinon.fake.returns('42'); sinon.replace(console, 'log', fake2); console.log('apple pie'); // prints ‚42‘ sinon.restore(); }); Sinon Fake https://sinonjs.org/releases/v7.2.2/fakes/ Import Create fake Remove replacement with fake Call to fake returns stringFake grabs its call count Replace existing property with fake
  • 25. Testen in Isolation const fs = require(‘fs‘); ... „Rewire“ module dependencies in tests https://github.com/jhnns/rewire const rewire = require("rewire"); const myModule = rewire("../path/to/myModule.js"); const fsMock = ... myModule.__set__("fs", fsMock); myModule.js myModuleTest.js
  • 26. Testabdeckung ● instrumentiert ES5 und ES2015+ JavaScript code mit Zeilennummeriung, so dass nachvollzogen werden kann, wie gut die bestehenden Tests die Implementierung abdecken Istanbul
  • 27. Testabdeckung ● Code coverage != Assertion coverage: kann also Tests schreiben, die den gesamten Code ausführen, ohne die produzierten (Zwischen-)Zustände und Ausgabe zu prüfen ● Dateien, für die gar keine Tests existieren, wirken sich nicht negativ auf Code coverage aus (Javascript feature) ● Mutation testing injiziert Fehler in die Codebasis (z.B. durch Kippen von Boolean-Ausdrücken) und prüft, ob diese Änderungen durch bestehende Tests gefunden werden, die dann fehlschlagen sollten Mutation testing https://en.wikipedia.org/wiki/Mutation_testing https://www.researchgate.net/figure/Mutation-testing-procedure_fig1_279174620
  • 28. Testabdeckung ● Code coverage != Assertion coverage: kann also Tests schreiben, die den gesamten Code ausführen, ohne die produzierten (Zwischen-)Zustände und Ausgabe zu prüfen ● Dateien, für die gar keine Tests existieren, wirken sich nicht negativ auf Code coverage aus (Javascript feature) ● Mutation testing injiziert Fehler in die Codebasis (z.B. durch Kippen von Boolean-Ausdrücken) und prüft, ob diese Änderungen durch bestehende Tests gefunden werden, die dann fehlschlagen sollten Mutation testing https://en.wikipedia.org/wiki/Mutation_testing https://www.researchgate.net/figure/Mutation-testing-procedure_fig1_279174620
  • 29. Erweiterte Testausführung ● Tests in a loop: Tests sofort bei jedem Speichern einer Datei im Projekt ausführen (in Javascript ist das initialen Laden aller Testdateien ziemlich langsam) ● Testen in verschiedenen Browsern / Plattformen ● Vorbereitende Aktionen ausführen, bevor die Tests ausgeführt werden (z.B. Browser starten, Telegram Anwendung starten) ● https://blog.mayflower.de/4333-Karma-Testrunner-Einfuehrung.ht ml ● https://www.npmjs.com/search?q=keywords:karma-plugin Karma https://github.com/karma-runner/karma https://karma-runner.github.io/latest/index.html
  • 30. Integration in VSCode Plugins ID Name sourcegraph.javascript-typescript JavaScript and TypeScript IntelliSense leizongmin.node-module-intellisense Node.js Modules Intellisense xabikos.javascriptsnippets JavaScript (ES6) code snippets christian-kohler.npm-intellisense npm Intellisense christian-kohler.path-intellisense Path Intellisense IntelliSense / Code snippets Sonstiges ID Name dai-shi.vscode-es-beautifier es-beautifier fabiospampinato.vscode-git-history Git File History https://marketplace.visualstudio.com/search?term=javascript&t arget=VSCode&category=All categories&sortBy=Relevance
  • 31. Integration in VSCode Plugins ID Name spoonscen.es6-mocha-snippets ES6 Mocha Snippets hbenl.vscode-test-explorer Test Explorer UI hbenl.vscode-mocha-test-adapter Mocha Test Explorer rintoj.chai-spec-generator Test Spec Generator markis.code-coverage Code Coverage Testen ID Name dbaeumer.vscode-eslint ESLint chenxsan.vscode-standardjs StandardJS - JavaScript Standard Style Lint
  • 33. Zusammenfassung ● Tests einfach halten ● Black Box Tests bevorzugen gegenüber White-Box-Tests ● Vermeiden von Interacting Tests durch Zurücksetzen von Zuständen und Mocks in before, beforeEach, afterEach und/oder after mit sinon.resetAll oder reset am gestubten/gemockten Objekt ● Tests im automatisierten Build (z.B. über TravisCI) mitlaufen lassen, nur Release bauen und releasen, wenn alle Tests grün sind Best practices http://tryqa.com/what-are-the-principles-of-testing/
  • 34. Zusammenfassung ● Äquivalenz-Klassen bilden, z.B. jeweils Stellvertreter-Eingaben finden, bei der z.B. die Teilbedingungen von if-Statements im getesteten Code in allen Kombinationen durchlaufen werden (Zeilen-, Zweig-, Pfad-Abdeckung) ● immer mit Kopien bei Expectations und Eingaben arbeiten, damit man nicht versehentlich die durch die Implementierung veränderte Eingabe als erwarteten Vergleichswert nutzt ● Spread-Operator nutzen, um neue Varianten von Testdaten zu erzeugen ● Komplexe Testdaten aus JSON-Datei in Tests importieren Best practices (2) https://developer.mozilla.org/de/docs/Web/Java Script/Reference/Operators/Spread_operator