Dnešní programátoři používají při své každodenní práci stále více agilních postupů. Jejich přizpůsobení může být přínosné i pro projekty, které se řídí standardním životním cyklem vývoje softwaru. Automatické testování a TDD vnesly do naší práce více jistoty, usnadnily implementaci úprav stávajících funkcí a často nás vedly k lepšímu návrhu kódu. Nyní to však nestačí. Musíme přínosy testů posunout až na hranici možností a to BDD umožňuje. bDD staví na TDD a přidává k jeho postupům mnoho přidané hodnoty. Vnáší do projektu všudypřítomný jazyk, umožňuje lepší komunikaci mezi klientem a vývojáři. Nabízí mnoho pro projektové manažery a vedoucí, ale také značně usnadňuje život vývojářům. Dodržování zásad BDD nám dává jasné požadavky, testy jsou snáze pochopitelné a mohou sloužit jako dokumentace. BDD posouvá zaměření testovaných subjektů a dává nám jistotu, že testujeme to, co bychom testovat měli - chování.
Pokud používáte TDD, začít s BDD bude snadné - je to v podstatě soubor osvědčených postupů. BDD má sadu jednoduchých pravidel, která říkají, jak psát specifikace a co testovat. Specifikace se dělí na tři části: Given (nastavení podmínek testu), When (vyvolání akce na subjektu) a Then (tvrzení). Testy by měly mít popisné názvy a existující testovací rámce umožňují používat metody a aserce, které jsou podobné přirozenému jazyku - to vše dohromady dává nás testy, které jsou čitelné pro technické i netechnické uživatele. Při regresních testech se osvědčují dobré konvence pojmenování.
Součástí BDD je také sada pokynů pro testované subjekty. Na rozdíl od TDD přesouvá důraz z testování implementace na testování chování - a jeho použití vede k lepšímu návrhu a poskytuje větší flexibilitu při zavádění změn. Specifikace by měly být jako napsané a spustitelné požadavky klienta - ty vysokoúrovňové by měly fungovat jako akceptační testy. Cílem je psát testy tak, aby bylo nutné je měnit pouze při změně požadavků. Použití BDD nám dává jistotu, že testujeme to, co je skutečně třeba pokrýt, a je to pragmatičtější přístup než TDD.
Pokud chcete vidět BDD v akci, doporučujeme vám. Ruby. Je to výkonný a zábavný jazyk s vynikající sadou nástrojů pro BDD.
Okurka
Cucumber je nejoblíbenější framework pro BDD v jazyce Ruby. Zavádí speciální jazyk zvaný Gherkin, ve kterém budete psát své testy. Na rozdíl od RSpec jsou funkce popsané v Gherkinu prostým textem, ne kóda jako takový může - a měl by - být srozumitelný komukoli, především klientovi.
Funkce Cucumber vypadá takto (příklad převzat z wiki Cucumber):
Funkce: Nějaký stručný, ale popisný text toho, co je požadováno.
Textový popis obchodní hodnoty této funkce
Obchodní pravidla, kterými se řídí rozsah funkce
Jakékoli další informace, které usnadní pochopení funkce.
Scénář: Určitá určitelná obchodní situace
Vzhledem k nějaké předběžné podmínce
A nějaká další předběžná podmínka
Když nějaká akce aktéra
A nějaká jiná akce
A ještě jiná akce
Pak je dosaženo nějakého testovatelného výsledku
A stane se i něco dalšího, co můžeme zkontrolovat
Scénář: Jiná situace
...
Funkce budou podrobně popsány později.
Použití Cucumber v Ruby on Rails
Instalace
První krok k použití okurky ve vašem projekt je jeho instalace. Stačí přidat tyto dva drahokamy do souboru Gemfile:
group :test do
gem 'cucumber-rails', :require => false
gem 'database_cleaner'
end
Svažte je spuštěním instalace svazkua vygenerujte skripty a adresáře Cucumberu pomocí následujícího příkazu:
Tím se vytvoří config/cucumber.yml, script/cucumber a funkce/ adresář, který bude obsahovat .feature a také definice kroků a podpůrné soubory. Chcete-li spustit své funkce, použijte nový příkaz rake:
hrábě na okurky
Funkce
Podívejme se blíže na funkce. Funkce je něco, co vaše aplikace má nebo dělá - například pravidelně zasílá newsletter nebo umožňuje uživateli veřejně sdílet své fotografie. Jedna funkce se skládá z více scénářů, které popisují, jak tato funkce funguje v různých kontextech.
Abychom si ukázali základní použití Cucumberu v systému Rails, napíšeme funkci od začátku. Tato ukázková funkce bude první, kterou napíšeme v aplikaci, kterou si ukážeme v příští druhé části tohoto článku. Tato aplikace umožní uživateli vytvářet položky a obchody (obchody prodávají položky) a následně vytvářet nákupní seznamy.
V nejjednodušší verzi aplikace po sestavení nákupního seznamu ukáže, ve kterých obchodech jsou položky, které uživatel chce, nejlevnější.
Nejprve vytvořte nový soubor s názvem create_item.feature v funkce/ adresář. V horní části adresáře .feature je soubor Funkce klíčové slovo, po kterém následuje jeho krátký popis. Například:
Funkce: Vytváření položek
Na následujících řádcích můžete napsat obchodní cíl, který bude tuto funkci implementovat. Protože Cucumber ignoruje text napsaný před prvním Scénářem, není nutné nic psát, ale rozhodně je to dobrý nápad.
Snadné vytváření nákupních seznamů s položkami prodávanými v okolních obchodech
Jako uživatel
Chci přidat položky do systému
V úryvku výše vidíte poměrně oblíbený vzor, kterým můžete popsat obchodní cíle. Skládá se ze tří částí: proč je daná funkce nutná, kdo ji chce a jaká je. Tento formát samozřejmě dodržovat nemusíte, ale nezapomeňte do popisu zahrnout odpovědi na tyto tři otázky.
Scénáře
Dále napíšeme několik scénářů. Každý scénář začíná klíčovým slovem "Scenario" a obsahuje více kroků.
Scénář: vytvoření jedinečné položky
Vzhledem k tomu, že existuje položka "Mléko"
Když přejdu na hlavní stránku
A vytvořím položku "Chléb"
Pak se mi v seznamu položek zobrazí "Chléb".
Pokud tedy někdo vytvořil položku s názvem Mléko, pak je možné vytvořit položku Chléb, která se objeví v seznamu položek. Neměli bychom testovat vytvoření záznamu v databázi, protože tato skutečnost nemá pro zákazníka žádnou skutečnou hodnotu.
Kroky scénáře používají tři hlavní klíčová slova:
Vzhledem k tomu, že, pro doplnění kontextu scénáře
Když, pro popis akcí
Pak, pro popis výsledků
Je důležité si uvědomit, že Cucumber ignoruje krok klíčového slova, kterým začíná, a porovnává pouze pozdější část. Kroky tedy můžete začínat slovem "A" všude tam, kde vám to přijde přirozené. Jediným pravidlem pro výběr správného klíčového slova je, že Scénář musí být snadno pochopitelný.
Definice kroků
Spuštění nástroje Cucumber nyní poskytne tento výstup:
[...]
Funkce: Vytváření položek
Snadné vytváření nákupních seznamů s položkami prodávanými v okolních obchodech
Jako uživatel
Chci přidat položky do systému
Scénář: vytvoření jedinečné položky # features/create_item.feature:6
Vzhledem k tomu, že existuje položka "Mléko" # features/create_item.feature:7
Nedefinovaný krok: (Cucumber::Undefined): "existuje položka "Milk"" (Cucumber::Undefined)
[...]
Je to proto, že Cucumber neví, co máme na mysli, když řekneme "existuje položka Milk". Chcete-li svým krokům přidat nějaký význam, musíte je definovat v dokumentu step_definitions adresář.
Doporučeným způsobem, jak uspořádat definice kroků, je rozdělit je podle domén. Například většina kroků, které jsme vytvořili, patří do domény Položky. Měli bychom tedy vytvořit soubor s názvem step_definitions/item_steps.rb a umístěte do něj následující kód:
Zadáno "existuje položka "$name"" do |name|
Fabricate :item, name: name
end
Když "Vytvářím položku "$name"" do |name|
v rámci "#new_item" do
fill_in "Name", with: name
klik_na "Vytvořit"
konec
konec
potom "V seznamu položek vidím "$name"" do |name|
v rámci ".items" do
expect(page).to have_content name
end
end
Definice kroků obvykle vycházejí z Capybary. Pokud Capybaru neznáte, určitě se podívejte na odkazy na konci tohoto článku.
Existuje ještě jeden krok, který je třeba definovat a který se do kroků položky nevejde. Mohli byste ho zařadit do main_page_steps.rb:
Když "přejdu na hlavní stránku", udělám
visit root_path
konec
Závěr
Jedná se o velmi jednoduchý příběh pro velmi jednoduchou funkci. Jeho účelem bylo demonstrovat základní koncepty BDD, jak jsou používány v Cucumberu. Psaní dobrých příběhů však vyžaduje trochu víc. Jako vývojář budete muset zcela změnit své myšlení - zapomenout na implementaci a místo toho se zaměřit na obchodní cíle. Cucumber tento přechod usnadňuje díky chytrému používání příběhů v prostém textu.