Testování Javascriptových projektů III

od aichi E-mail

V minulých dílech 1 a 2 jsme se zaěřili na JSUnit, nyní je na čase představit horkou novinku v testování Javascriptu. Touto novinkou je framework Jasmine, který ideově vychází z frameworku Screw a obecně z RSpec a dalších Ruby frameworku.

...

Možná si kladete otázku, proč je treba nový framework, když JSUnit postihuje vetšinu našich potřeb. Pak vězte, že Jasmine se odlišuje v tom, že ke své činnosti nepotrebuje DOM a tudíž je možné ho používat s node.js - Javascriptem na serverové straně, nebo např. při psaní iPhone aplikací pomocí Titanium Appceleratoru.

Testovací prostředí Jasmine se snaží připodobnit psané angličtině a tak i samotné motto Jasmine je zapsáno ve formě unit testu:

describe("Jasmine", function() {
  it("makes testing JavaScript awesome!", function() {
    expect(yourCode).toBeLotsBetter();
  });
});

Na příkladu vidíme, že naše testy jsou vykonávány voláním funkce expect a použitím tzv. Matcher funkce pro ověření výsledku. V našem případě je matcherem funkce toBeLotsBetter.

Testy uzavíráme do takzvaných specifikací, které reprezentuje metoda it. Její název evokuje začátek věty popisující co testujeme a proto popis vetšinou začínáme slovesem should.

Jednotlivé specifikace vkládáme do Suite (sad), které představují metody describe. Metody describe můžeme do sebe libovolně vnořovat.

Instalace

Pojďme se podívat jak připravit testovací prostředí, abychom si mohli vytvořit a spustit první test.

Pokud nepoužíváte Ruby, dejte prednost standalone verzi, kterou mužete stáhnout na download stránce. Obsah staženého archivu rozbalte do libovolného adresáře. Po rozbalení se vám zobrazí tři adresáře a jeden soubor:

lib
spec
src
SpecRunner.html

Nyní se musíte rozhodnout nad strukturou projektu, zda budete testy ukládat do adresáre spec a zdrojové kódy do src, nebo si vše upravíte dle svých potřeb. Já si v projektu se svým zdrojovým kódem zakládám adresář tests a do nej kopíruji adresáre lib a spec a také soubor SpecRunner.html. Tím pádem nepotřebuji adresář pro zdrojové kódy, ty najdu o úroven výše.

Soubor SpecRunner.html je nutný pouze pro zobrazení výsledku testu v prohlížeči, nicméně je to dobrý výchozí bod, proto jej využijeme i my pro zobrazení výsledků.

Konfigurace souboru SpecRuner.html

Obsah souboru vypadá velice podobně jako při použití JSUnit. V hlavičce načteme všechny potřebné Javascriptové soubory a poté testy spustíme:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Jasmine Test Runner
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  //nacteni knihovny Jasmine
  <link rel="stylesheet" type="text/css" href="lib/jasmine.css">
  <script type="text/javascript" src="lib/jasmine.js"></script>
  <script type="text/javascript" src="lib/jasmine-html.js"></script>
  
  //nacteni testovanych knihoven
  <script type="text/javascript" src="../jquery.js"></script>
  
  //soubory s testy
  <script type="text/javascript" src="spec/myTestSpec.js"></script>
  

</head>
<body>

<script type="text/javascript">
  jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
  jasmine.getEnv().execute();
</script>

</body>
</html>

Psaní testů

Jak jsme si již v úvodu rozebrali, testy dělíme do sad (metoda describe) a specifikací (metoda it). Vlastní testy začínají metodou expect. Struktura testo opět odpovídá struktuře anglické věty: expect(yourCode).toBeLotsBetter();. V překladu tedy: Očekáváme, že váš kód bude mnohem lepší.

Již jsme si řekli, že metoda toBeLotsBetter je takzvaný Matcher. Je to tedy metoda, která porovnává stav předaný metodě expect se stavem předaným jí samé, či jiným interním stavem. V dokumentaci se dozvíme o všech porovnávacích funkcích, které Jasmine nabízí. Nejběžnější jsou toEqual a toBe.

Metoda toEqual testuje zda se objekty shodují trojrovnítkově ===, nebo pokud jsou objekty čísla a řetězce, že se shodují dvojrovnítkově, pokud jsou datumy, tak se shodují v počtu milisekund od počátku roku 1970 a nebo pokud jsou obě proměnné objekty a tyto objekty mají stejné vlastnosti.

Metoda toBe je velice striktní a testuje pouze trojrovnítkovou shodu předaných objektů.

Vše si vyskoušíme na testu jQuery stejně jako v minulých dílech. Tedy vytvoříme si soubor spec/myTestSpec.js s tímto obsahem:

describe("jQuery tests", function(){
			var div;
			
      beforeEach(function() {
				div = document.createElement('div');
				div.id = 'testDiv';
				div.name = 'zZz';
				document.body.appendChild(div);
			});

			afterEach(function(){
				document.body.removeChild(div);
				delete div;
			});

			it('should return created div element', function() {
				var jdiv = $("#testDiv");
				expect(jdiv).not.toBeNull();
				expect(jdiv[0]).toBe(div);

				var jdiv2 = $("#div");
				expect(jdiv2).not.toBeNull();
				expect(jdiv2[0]).not.toBeDefined();
			});
	
			it('should return the name attribute of our div', function(){
				var jdiv = $("#testDiv");
				expect(jdiv.attr("name")).toEqual(div.name);
			});
});

Pokud spustíme soubor SpecRunner.html uvidíme v prohlížeči dvě řádky. První růžovou se záhlavým a druhou zelenou, která nás informuje, e byly spuštěny 2 specifikace (funkce it) a nenastaly žádné chyby.

Pojďme si nakonec tohoto dílu probrat co jsme použili v tomto testu. Náš testovací soubor se skládá z jedné testovací sady, která obsahuje dvě volání metody it a také volání metod beforeEach a afterEach. Funkce předané těmto metodám budou vykonány před a po každé metodě it v dané funkci describe.

Jelikož můžeme funkce describe zanořovat, můžeme pro každou describe funkci definovat i metody beforeEach a afterEach a tudíž tvořit jakousi kaskádu přípravných metod, ale držme se pravidla, čím méně tím lépe. Tyto metody jsou vlastně ekvivalentem metod setUp a tearDown v testovacím frameworku JSUnit.

Dále v testech krom popsaných metod toEqual a toBe používáme další porovnávací metodu a to toBeNull a toBeDefined. První jmenovaná testuje atribut předaný metodě expect na hodnotu null, druhá zda je atribut definován, tedy neni undefined.

Všimněme si také řádků 17, 21 a 22, kde je před porovnávací metodu předřazen objekt negace not. Tento objekt můžeme použít mezi kteroukoli porovnávací metodou a metodou expect a vždy bude znamenat negaci testu.

Závěr

V tomto díle jsme si vysvětlili základy frameworku Jasmine a v dalším díle si ukážeme jak testovat asynchronní kód a také jak používat tzv. špióny, kterí nám pomohou sledovat vnitřní stav objektů.

Adresy zpětných odkazů pro tento příspěvek:

Trackback URL (right click and copy shortcut/link location)

Zatím žádná reakce

Napsat komentář


Vaše e-mailová adresa nebude zveřejněna.

Adresa Vašich WWW stránek bude zveřejněna.
(Konce řádku budou převedeny na <br />)
(Jméno, email a webová stránka)
(Dovolí ostatním uživatelům kontaktovat Vás prostřednictvím formuláře pro zprávy (Vaše e-mailová adresa NEBUDE zveřejněna.))