Programování

První testovací vývoj s FitNesse

Během posledních několika let jsem pracoval ve všech rolích testovacího procesu, používal jsem na straně serveru JavaScript, Perl, PHP, Struts, Swing a architektury založené na modelech. Všechny projekty se lišily, ale všechny měly určité společné rysy: lhůty běžely pozdě a projekty měly potíže s realizací toho, co zákazník opravdu potřeboval.

Každý projekt měl nějaký druh požadavku, některé byly velmi podrobné, jiné, jen pár stránek dlouhé. Tyto požadavky obvykle prošly třemi fázemi:

  • Byly napsány (buď zákazníkem, nebo dodavatelem) a byly nějakým způsobem oficiálně přijaty
  • Testeři se pokusili s požadavky pracovat a shledali je víceméně nedostatečnými
  • Projekt vstoupil do fáze akceptačního testování a zákazník si najednou vzpomněl na všechny druhy věcí, které software potřeboval udělat dodatečně / jinak

Poslední fáze vedla ke změnám, které vedly ke zmeškaným termínům, což kladlo důraz na vývojáře, což vedlo k dalším chybám. Počet chyb začal rychle stoupat a celková kvalita systému klesala. Zní povědomě?

Uvažujme, co se ve výše popsaných projektech pokazilo: Zákazník, vývojář a tester nepracovali společně; předali požadavky, ale každá role měla jiné potřeby. Kromě toho vývojáři obvykle vyvinuli nějaký druh automatizovaných testů a testeři se také pokusili automatizovat některé testy. Obvykle nemohli dostatečně koordinovat testování a mnoho položek bylo testováno dvakrát, zatímco jiné (obvykle tvrdé části), vůbec ne. A zákazník neviděl žádné testy. Tento článek popisuje způsob řešení těchto problémů kombinací požadavků s automatizovanými testy.

Zadejte FitNesse

FitNesse je wiki s některými dalšími funkcemi pro spouštění testů JUnit. Pokud jsou tyto testy kombinovány s požadavky, slouží jako konkrétní příklady, čímž jsou požadavky ještě jasnější. Kromě toho jsou testovací data logicky uspořádána. Nejdůležitější věcí na používání FitNesse je však idea to znamená, že se ukázalo, že požadavky jsou psány (částečně) jako testy, díky čemuž jsou testovatelné, a proto je jejich splnění ověřitelné.

Pomocí FitNesse může vývojový proces vypadat takto: Inženýr požadavků zapíše požadavky do FitNesse (namísto Wordu). Snaží se zapojit zákazníka co nejvíce, ale to obvykle nelze dosáhnout denně. Tester opakovaně prohlíží dokument a klade obtížné otázky od prvního dne. Protože tester uvažuje jinak, nemyslí si: „Co software udělá?“ ale „Co se může pokazit? Jak to mohu zlomit?“ Vývojář uvažuje spíše jako inženýr požadavků; chce vědět: „Co musí software dělat?“

Tester začíná psát své testy brzy, když ještě nejsou splněny požadavky. A zapíše je do požadavků. Testy se stávají součástí nejen požadavků, ale také procesu kontroly / přejímky požadavků, který má některé důležité výhody:

  • Zákazník se nad testy zamyslí také. Obvykle se dokonce podílí na jejich tvorbě (možná vás překvapí, kolik zábavy s tím může mít).
  • Specifikace se stává mnohem podrobnější a přesnější, protože testy jsou obvykle přesnější než pouhý text.
  • Včasné přemýšlení o reálných scénářích, poskytování testovacích dat a výpočet příkladů vede k mnohem jasnějšímu pohledu na software - jako prototyp, jen s více funkcemi.

Nakonec jsou požadavky předány vývojáři. Nyní má jednodušší práci, protože je méně pravděpodobné, že by se specifikace změnila, a to kvůli všem zahrnutým příkladům. Pojďme se podívat na to, jak tento proces usnadňuje práci vývojáře.

Implementace nejprve na test

Nejtěžší částí zahájení vývoje test-first je obvykle to, že nikdo nechce trávit tolik času psaním testů, jen aby našel způsob, jak je nechat fungovat. Pomocí postupu popsaného výše obdrží vývojář funkční testy jako součást své smlouvy. Jeho úkoly se mění z „Sestavte to, co chci, a vy jste hotovi, dokud nezkoumám vaši práci a neprovedete změny“ na „Nechte tyto testy fungovat a máte hotovo.“ Nyní mají všichni lepší představu o tom, co mají dělat, kdy mají být práce dokončeny a kde stojí projekt.

Ne všechny tyto testy budou automatizovány a ne všechny budou jednotkovými testy. Testy obvykle rozdělíme do následujících kategorií (podrobnosti budou následovat):

  • Testy založené na datech, které je třeba implementovat jako jednotkové testy. Typickým příkladem jsou výpočty.
  • Testy založené na klíčových slovech, které automatizují použití aplikace. Jedná se o testy systému a vyžadují spuštění aplikace. Klikne se na tlačítka, zadají se data a zkontrolují se, zda výsledné stránky / obrazovky obsahují určité hodnoty. Testovací tým tyto testy obvykle implementuje, ale někteří vývojáři z nich také těží.
  • Ruční testy. Tyto testy jsou buď příliš nákladné na automatizaci a možné chyby nejsou dostatečně závažné, nebo jsou natolik zásadní (úvodní stránka se nezobrazí), že by jejich poškození bylo odhaleno najednou.

Když jsem poprvé četl o FitNesse v roce 2004, zasmál jsem se a řekl, že to nikdy nebude fungovat. Myšlenka zapsat mé testy na wiki, která je automaticky proměnila v testy, se zdála příliš absurdní. Ukázalo se, že jsem se mýlil. FitNesse je opravdu tak jednoduchý, jak se zdá být.

Tato jednoduchost začíná instalací. Stačí stáhnout úplnou distribuci FitNesse a rozbalit ji. V následující diskusi předpokládám, že jste rozbalili distribuci do C: \ fitnesse.

Spusťte FitNesse spuštěním run.bat (run.sh na Linuxu) skript v C: \ fitnesse. Ve výchozím nastavení běží FitNesse webový server na portu 80, ale přidáním můžete určit jiný port, řekněme 81 -p 81 na první řádek v dávkovém souboru. To je vše; nyní můžete přistupovat k FitNesse na // localhost: 81.

V tomto článku používám Java verzi FitNesse pro Windows. Příklady však lze použít i pro jiné verze (Python, .Net) a platformy.

Některé testy

Online dokumentace společnosti FitNesse poskytuje několik jednoduchých příkladů (srovnatelných s nechvalně známým příkladem peněz od JUnit), které vám pomohou začít. Jsou v pořádku, když se učí, jak používat FitNesse, ale nejsou dostatečně komplikovaní, aby přesvědčili některé skeptiky. Proto použiji příklad ze skutečného světa z jednoho z mých nedávných projektů. Problém jsem výrazně zjednodušil a kód, který nebyl převzat přímo z projektu, byl napsán pro ilustrativní účely. Tento příklad by přesto měl být dostatečně komplikovaný, aby prokázal sílu jednoduchosti FitNesse.

Předpokládejme, že pracujeme na projektu, který implementuje komplexní podnikový software založený na prostředí Java pro velkou pojišťovnu. Produkt zvládne celé podnikání společnosti, včetně správy zákazníků a smluv a plateb. V našem příkladu se podíváme na malou část této aplikace.

Ve Švýcarsku mají rodiče nárok na jeden příspěvek na dítě. Tento příspěvek dostávají, pouze pokud jsou splněny určité okolnosti, a jeho výše se liší. Následuje zjednodušená verze tohoto požadavku. Začneme s „tradičními“ požadavky a poté je přesuneme do FitNesse.

Existuje několik fází příspěvku na dítě. Nárok začíná prvním dnem měsíce, kdy se dítě narodí, a končí posledním dnem měsíce, kdy dítě dosáhne věkové hranice, dokončí učení nebo zemře.

Po dosažení věku 12 let se nárok zvyšuje na 190 CHF (oficiální symbol měny Švýcarska) počínaje prvním dnem měsíce narození.

Zaměstnání rodičů na plný a částečný úvazek vede k různým nárokům, jak je podrobně uvedeno na obrázku 1.

Aktuální míra zaměstnanosti se počítá z aktivních pracovních smluv. Smlouva musí být platná, a pokud je stanoveno datum ukončení, musí být umístěna do „aktivačního období“. Obrázek 2 ukazuje, na kolik peněz má rodič nárok v závislosti na věku dítěte.

Předpisy upravující tyto platby se upravují každé dva roky.

Při prvním čtení může specifikace znít přesně a vývojář by měl být schopen ji snadno implementovat. Ale jsme si opravdu jistí okrajovými podmínkami? Jak bychom tyto požadavky otestovali?

Okrajové podmínky
Okrajové podmínky jsou situace přímo na, nad a pod okraji tříd ekvivalence vstupu a výstupu. Zkušenosti ukazují, že testovací případy zkoumající okrajové podmínky mají vyšší výplatu než testovací případy, které nikoli. Typickým příkladem jsou nechvalně známé „jednorázové“ smyčky a pole.

Scénáře mohou být velkou pomocí při hledání výjimek a okrajových podmínek, protože poskytují dobrý způsob, jak přimět odborníky na doménu, aby hovořili o podnikání.

Scénáře

U většiny projektů předá technik požadavků specifikaci vývojáři, který požadavky prostuduje, položí několik otázek a začne navrhovat / kódovat / testovat. Poté vývojář předá software testovacímu týmu a po několika přepracováních a opravách jej předá zákazníkovi (který pravděpodobně pomyslí na některé výjimky vyžadující změny). Přesunutí textu do FitNesse tento proces nezmění; přidání příkladů, scénářů a testů však bude.

Scénáře jsou obzvláště užitečné k tomu, aby se míč během testování dostal do pohybu. Následuje několik příkladů. Odpověď na otázku, kolik každého z nich má být vypláceno, hodně objasní:

  • Maria je osamělý rodič. Má dva syny (Bob, 2 roky a Peter, 15 let) a pracuje na částečný úvazek (20 hodin týdně) jako sekretářka.
  • Maria přijde o práci. Později pracuje 10 hodin týdně jako prodavačka a dalších 5 hodin jako chůva.
  • Paul a Lara mají dceru (Lisa, 17), která je tělesně postižená, a syna (Frank, 18), který je stále na univerzitě.

Pouhý rozhovor prostřednictvím těchto scénářů by měl pomoci procesu testování. Jejich manuální provedení v softwaru téměř jistě najde nějaké volné konce. Myslíte si, že to nemůžeme udělat, protože ještě nemáme prototyp? Proč ne?

Testování na základě klíčových slov

K simulaci prototypu lze použít testování na základě klíčových slov. FitNesse nám umožňuje definovat testy založené na klíčových slovech (podrobnosti viz „Totally Data-Driven Automated Testing“). I bez softwaru, který by (automaticky) provedl testy, testy založené na klíčových slovech hodně pomohou.

Obrázek 3 ukazuje, jak může vypadat test založený na klíčových slovech. První sloupec představuje klíčová slova z FitNesse. Druhý sloupec představuje metody ve třídě Java (ty píšeme a musí dodržovat omezení kladená na názvy metod v Javě). Třetí sloupec představuje data zadaná do metody z druhého sloupce. Poslední řádek ukazuje, jak může vypadat neúspěšný test (předané testy jsou zelené). Jak vidíte, je docela snadné zjistit, co se stalo.

Vytváření takových testů je snadné a dokonce zábavné. Testeři bez programátorských dovedností je mohou vytvořit a zákazník si je může přečíst (po krátkém úvodu).

Definování testů tímto způsobem, hned vedle požadavku, má oproti tradiční definici testovacích případů několik důležitých výhod, a to i bez automatizace:

  • Kontext je na dosah ruky. Samotný testovací případ lze sepsat s co nejmenším množstvím práce a je stále přesný.
  • Pokud se požadavek změní, je velká šance, že se změní i test (není příliš pravděpodobné, když se použije několik nástrojů).
  • Test lze provést najednou a ukázat, co je třeba opravit, aby tento nový / změněný požadavek fungoval.

Pro automatizaci testu je vytvořena tenká vrstva softwaru, který je delegován na skutečný testovací kód. Tyto testy jsou zvláště užitečné pro automatizaci manuálních testů GUI. Vyvinul jsem testovací rámec založený na HTTPUnit pro automatizaci testování webových stránek.

Zde je kód automaticky provedený FitNesse:

balíček stephanwiesner.javaworld;

import fit.ColumnFixture;

veřejná třída ChildAllowanceFixture rozšiřuje ColumnFixture {public void personButton () {System.out.println ("stisknutí tlačítka osoby"); } public void securityNumber (int number) {System.out.println ("zadání securityNumber" + číslo); } public int childAllowance () {System.out.println ("výpočet přídavku na dítě"); návrat 190; } [...]}

Výstup testů lze zkoumat také ve FitNesse (viz obrázek 4), což výrazně pomáhá při ladění. Na rozdíl od JUnit, kde se nedoporučuje psát ladicí zprávy, považuji je za naprosto nezbytné při práci s automatizovanými webovými testy.

Při testování webové aplikace jsou na stránce FitNesse zahrnuty a zobrazeny chybové stránky, takže ladění je mnohem snazší než práce se soubory protokolu.

Testování na základě dat

Zatímco testování založené na klíčových slovech je pro automatizaci grafického uživatelského rozhraní v pořádku, testování založené na datech je první volbou pro testování kódu, který provádí jakýkoli druh výpočtu. Pokud jste již dříve psali jednotkové testy, co je na těchto testech ta nejotravnější věc? Je pravděpodobné, že myslíte na data. Vaše testy budou plné dat, která se často mění, takže údržba bude noční můrou. Testování různých kombinací vyžaduje různá data, což pravděpodobně dělá vaše testy komplikovanými, ošklivými zvířaty.

$config[zx-auto] not found$config[zx-overlay] not found