Paragraf dla niewtajemniczonych:
Mówimy dziś o testach jednostkowych w JS. A dokładnie o bibliotece Chai, która umożliwia pisanie asercji (warunków do spełnienia). To ta, która jednym tchem jest wymieniana po frameworku Mocha. Nie będę zagłębiać się w szczegóły. Nie dziś.
Dziś krótko o podstawowych różnicach między trzema stylami, interfejsami w bibliotece Chai: assert, expect, should.
Pierwsza różnica – TDD vs. BDD.
Assert jest stworzone do pisania testów TDD, z kolei should oraz expect – BDD. O różnicach pomiędzy TDD a BDD możecie poczytać moim artykule tutaj: KLIK!
Kolejne różnice omówię na przykładach, ekhm, głównie z dokumentacji. Przepraszam, ale bez sensu wymyślać koło na nowo
SHOULD
chai.should();
foo.should.be.a('string');
foo.should.equal('bar');
foo.should.have.lengthOf(3);
tea.should.have.property('flavors').with.lengthOf(3);
EXPECT
var expect = chai.expect;
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.lengthOf(3);
expect(tea).to.have.property('flavors').with.lengthOf(3);
expect(foo, "foo should be true").to.be.true;
ASSERT
var assert = chai.assert;
assert.typeOf(foo, 'string');
assert.equal(foo, 'bar');
assert.lengthOf(foo, 3)
assert.property(tea, 'flavors');
assert.lengthOf(tea.flavors, 3);
assert.isTrue(foo, "foo should be true");
Druga różnica – jak skorzystać z danego interfejsu?
import chai from 'chai';
chai.should();
//LUB
import 'chai/should';
Trzecia różnica – modyfikacja Object.prototype
Assert oraz expect nie modyfikują Object.prototype
, z kolei should – modyfikuje. O Object.prototype
, jeszcze kiedyś napiszę. Sama różnica ma istotny wpływ na wybór interfesju. Logiczne – należy wybrać assert albo expect wtedy, kiedy nie chcemy zmieniać Object.prototype.
Kolejne różnice – składnia
W kwestii składni – zarówno should, jak i expect (jako interfejsy BDD) wydają się sensownie, w prosty sposób opisywać istotę testu. Assert jako interfejs TDD wymaga ciut więcej wysiłku mózgu, aby pojąć działanie danego warunku. W jego przypadku testy nie tworzą logicznych zdań, które rozumie się poprzez jedno spojrzenie od lewej do prawej. Ścieżka rozkminiania poszczególnych asercji jest nieco bardziej zawiła.
Co więcej – łatwo można zauważyć, że expect oraz should są tzw. chainable. To znaczy – możemy łączyć wywołania metod na tym samym obiekcie za pomocą kropki. Assert nie jest chainable.
Kolejna składniowa, bardziej konkretna różnica – should nie daje możliwości wypisania komentarza do testów zakończonych niepowodzeniem. Expect oraz assert z kolei przyjmują jako opcjonalny parametr właśnie taki komentarz. Uwaga – jeśli nie podamy dodatkowego parametru dla expect/assert – w razie niepowodzenia wyplują one taki sam komunikat, jak should.
KIEDY CO UŻYWAĆ?
- assert/expect wtedy, kiedy nie chcemy zmieniać
Object.prototype
- assert wtedy, kiedy testujemy zgodnie z TDD
- expect/should wtedy, kiedy testujemy zgodnie z BDD
- assert/expect wtedy, kiedy chcemy ustawiać komunikaty o niepowodzeniu testu
- expect/should wtedy, kiedy chcemy, aby nasze testy były przyjemniejsze do czytania
Poza powyższymi – wybór pomiędzy trzema interfejsami to głównie kwestia gustu
Do poczytania: