#vuejs #vuecember2020

Testing mit Zufallswerten

TLDR; In Tests können Bibliotheken wie z.B. Casual zufällige Werte generieren. Das hilft verbessert die Lesbarkeit und reduziert Kopplung.

In Unit-Tests verwenden wir Platzhalter-Werte als Eingabe-Parameter oder Mocks und erwarten im Testverlauf entsprechende Rückgabewerte oder Seiteneffekte.

Häufig werden ähnliche Platzhalter-Werte in einer Vielzahl von Tests verwendet.
Es bietet sich dann an, deren Generierung in sogenannte Factories auszulagern.
Eine Factory ist dabei schlicht eine Funktion, die Objekte generiert.

Gerade, wenn der Code zur Erzeugung von Platzhalter-Werten und der Code für die Tests getrennt sind, ist es wichtig, dass diese nicht unerwartet gegeneinander koppeln.
Das kann leicht passieren, wenn eine Factory keine zufälligen, sondern immer gleiche Werte erzeugt.

Werden diese Werte dann im Test wiederholt, fängt der Test an gegen Details der Factory zu koppeln.
Das merkt man leicht daran, dass man die Factory nicht mehr einfach ändern kann, ohne dass der Test failed.

Ein vereinfachtes Beispiel:

// userFactory.js
function createUser() %7B
  return %7B
    id: 1,
    name: 'Someone'
  %7D
%7D

// user.js
function userLabel(user) %7B
  return `$%7Buser.name%7D ($%7Buser.id%7D)`
%7D

// user.spec.js
it('should display the users name', () => %7B
  expect(userLabel(createUser())).toMatch('Someone')
%7D)

Eine Kopplung ist hier durch die doppelte Verwendung von 'Someone' entstanden.
In größeren Applikationen können sich solche Abhängigkeiten über eine Vielzahl von Dateien verteilen. Sie werden komplexer und schwerer zu entdecken.

Durch die Generierung von Zufallsdaten in der obigen Factory, können wir dem vorbeugen.

// userFactory.js
function createUser() %7B
  return %7B
    id: 1,
    name: casual.name
  %7D
%7D

Tests mit einer Kopplung gegen den vorher in der Factory verwendeten Namen failen zwar, können aber leicht migriert werden:

// user.spec.js
it('should display the users name', () => %7B
  const user = createUser()
  expect(userLabel(user)).toMatch(user.name)
%7D)

Wenn in der Factory in Zukunft angepasst wird, reagiert der Test robuster.

Neben der reduzierten Kopplung hat die Verwendung von Zufallsdaten auch noch den Vorteil, dass wir uns keine Testdaten wie "Hello World" ausdenken müssen.
Das macht dann nicht nur die Tests robuster, sondern den Code auch intuitiver verständlich 😀.

Ressourcen