Obsah
1. Univerzální testovací nástroj Robot Framework
2. Instalace nástroje Robot Framework
3. Nejjednodušší testovací scénář aneb „Hello world“ pro Robot Framework
4. Základní formát testovacího scénáře
5. Další možný formát testovacího scénáře
6. Zvýraznění tabulkového formátu testů
8. Testovací scénář s větším množstvím test casů
9. Přepis předchozího scénáře do „tabulkového“ formátu
10. Testovací scénář s testem, který skončí s chybou
11. Klíčové slovo Repeat Keyword
12. Implementace vlastního klíčového slova v Pythonu
13. Klíčové slovo vytvořené v Pythonu způsobující pád testu
14. Klíčová slova realizovaná formou metod
15. Různé typy logovacích zpráv
16. Zajištění pádu testu s využitím aserce
17. První skutečný testovací scénář – test funkce kalkulačky
18. Korektní práce s parametry klíčových slov
19. Repositář s demonstračními příklady
1. Univerzální testovací nástroj Robot Framework
Na stránkách serveru root.cz jsme se seznámili již s několika různými knihovnami a frameworky určenými pro tvorbu a spouštění softwarových testů. Připomeňme si, že pro prakticky každý moderní programovací jazyk existuje minimálně jedna knihovna použitelná pro psaní jednotkových testů (unit test); ve skutečnosti ovšem těchto knihoven bude pro daný jazyk pravděpodobně existovat hned několik. Ovšem jednotkové testy tvoří jen jedinou vrstvu (základnu) takzvané „testovací pyramidy“. Nad nimi se nachází funkční testy, integrační testy, různé formy benchmarků, BDD testy, testy grafického uživatelské rozhraní atd. Z již popsaných nástrojů pro tvorbu těchto testů zmiňme například knihovnu Behave (BDD testy psané v Pythonu), Godog (BDD testy psané v Go), knihovnu Frisby (testy REST API, implementace pro Go), různé varianty knihovny expect (testování aplikací s příkazovou řádkou) atd. Knihovny a frameworky pro testování je však možné používat i u méně mainstreamových jazyků, například v Clojure [1] [2] [3] apod.
Dnes se – prozatím ovšem ve stručnosti – seznámíme s některými vlastnostmi nástroje nazvaného Robot Framework, který je naprogramován v Pythonu, ovšem lze ho použít společně s dalšími programovacími jazyky (ať již přímo či nepřímo, což si vysvětlíme příště). Jedná se o nástroj použitelný mj. pro psaní akceptačních testů (které tvoří vlastní testovací pyramidu používanou paralelně s klasickou testovací pyramidou), ovšem lze ho použít i pro zápis BDD testů, testů grafického uživatelského rozhraní (založeného například na webových technologiích) atd. Robot Framework je navržen velmi obecně, což sice zajišťuje jeho velkou flexibilitu, ovšem na druhou stranu nemusí být zpočátku zřejmé, jakým způsobem je ho vlastně možné použít. Z tohoto důvodu si dnes ukážeme jak základní formát zápisu testovacích scénářů, tak i způsob implementace jednotlivých klíčových slov (keyword) v Pythonu (klíčová slova vlastně přestavují základní stavební kameny implementace testovacích scénářů).
Obrázek 1: Logo nástroje Robot Framework.
2. Instalace nástroje Robot Framework
Nástroj Robot Framework je navržen modulárním způsobem. Obsahuje jádro představované (z pohledu uživatele) spustitelnými soubory robot a rebot. Toto jádro je doplněno o několik standardních knihoven se sadou základních klíčových slov. Doinstalovat je možné i další knihovny (moduly), například modul zajišťující testování webových aplikací přes Selenium (SeleniumLibrary) atd. Dnes si ovšem vystačíme „pouze“ s jádrem Robot Frameworku a se základními klíčovými slovy, která rozšíříme pomocí kódu napsaného v Pythonu.
Samotná instalace jádra Robot Frameworku je snadná a můžeme pro ni použít nástroj pip či pip3. Pro jednoduchost je v tomto článku instalace provedena pouze pro aktivního uživatele, stejně dobře je však možné použít virtuální prostředí Pythonu (virtualenv), provést instalaci do systémových adresářů atd.:
$ pip3 install --user robotframework
Instalace by měla být velmi krátká, protože samotné jádro frameworku je relativně malé a kompaktní. Po dokončení instalačního procesu si zkontrolujte, zda je na PATH dostupný spustitelný soubor robot:
$ which robot /home/tester/.local/bin/robot
A následně je možné tento soubor spustit:
$ robot --version Robot Framework 3.1.2 (Python 3.7.4 on linux)
$ echo $PATH /home/tester/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/tester/bin:/home/tester/.local/bin/:/opt/go/bin:/home/tester/go/bin
3. Nejjednodušší testovací scénář aneb „Hello world“ pro Robot Framework
Podívejme se nyní na zcela nejjednodušší, ovšem plně funkční testovací scénář, který obsahuje test nazvaný „Demo“ s jediným krokem – vytištěním řetězce „Hello world“ do automaticky vytvářeného logovacího souboru. Scénář je uložen v souboru pojmenovaném „test01.robot“ a má následující obsah:
*** Test Cases *** Demo Log Hello world
Tento test je možné bez dalších nastavování spustit, a to bez nutnosti připravovat adresář s projektem atd. Spuštění se provede příkazem:
$ robot test01.robot
Po spuštění by se měly do terminálu vypsat informace o spuštěných a úspěšně dokončených testech, včetně informace o tom, že byly vytvořeny i soubory s výsledky testu i se zprávami poslanými do logu. Cesta k těmto souborům je zobrazena v absolutní podobě, což je rozumné, protože adresářová struktura s testy a pomocnými knihovnami může být v reálných projektech i dosti složitá; navíc dokážou některé terminály takto zapsanou cestu zvýraznit ve formě aktivního odkazu pro otevření v prohlížeči:
============================================================================== Test01 ============================================================================== Demo | PASS | ------------------------------------------------------------------------------ Test01 | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
Podrobnější výsledky spuštěných testů nalezneme ve výše zmíněných vygenerovaných HTML stránkách, které lze například (v případě spuštění na CI) uložit do artefaktu atd., protože samotné stránky obsahují všechna potřebná data (CSS + pomocné JavaScriptové funkce). Základem je soubor report.html se shrnutými výsledky spuštěných testů:
Obrázek 2: Shrnuté výsledky spuštěných testů ve vygenerované HTML stránce.
K dispozici jsou ovšem i logovací informace, které jsou rozděleny podle jednotlivých scénářů a případů (stránka obsahuje rozklikávací bloky):
Obrázek 3: Logovací informace získané po spuštění testů. Samotný text „Hello world“ naleznete na screenshotu zcela dole.
4. Základní formát testovacího scénáře
V předchozí kapitole jsme si řekli, že v samotné implementaci testu je nutné mezi slovo „Log“ a „Hello“ vložit minimálně dvě mezery, tedy že poslední řádek textového souboru s testem má vypadat takto:
Log Hello world
Je tomu tak z toho důvodu, že testovací scénáře mají formát připomínající tabulku a tím pádem je nutné rozlišit mezery umístěné v jedné buňce tabulky („Hello world“ je z tohoto pohledu jediná buňka) a mezery použité pro oddělení jednotlivých buněk tabulky. Ostatně i mezery na začátku řádku, tedy před slovem „Log“, slouží pro specifikaci prázdné buňky v prvním sloupci pomyslné tabulky.
Ostatně si můžeme snadno vyzkoušet, co se stane ve chvíli, kdy namísto dvou (či více) mezer mezi slovy „Log“ a „Hello“ použijeme mezeru jedinou:
*** Test Cases *** Demo Log Hello world
Pokusíme se spustit takto upravený test:
$ robot test02.robot
Tentokrát je ovšem nahlášena chyba, a to v samotném formátu testu:
============================================================================== Test02 ============================================================================== Demo | FAIL | No keyword with name 'Log Hello world' found. ------------------------------------------------------------------------------ Test02 | FAIL | 1 critical test, 0 passed, 1 failed 1 test total, 0 passed, 1 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
5. Další možný formát testovacího scénáře
Ve skutečnosti existují i další možné formáty zápisů testovacího scénáře. Můžeme například pro oddělení jednotlivých buněk pomyslné tabulky použít znak Tab, pochopitelně tehdy, pokud máte správně nastavený textový editor (aby Taby neexpandoval na mezery). V následujícím výpisu je mezi slova „Log“ a „Hello“ vložena právě tabelační zarážka (což je naznačeno vloženým řádkem):
*** Test Cases *** Demo Log Hello world ^
V textovém editoru Vim je možné si nechat zobrazit řídicí znaky volbou:
:set list
S následujícím výsledkem (řídicí znaky jsou zvýrazněny tučným písmem):
*** Test Cases ***$ Demo$ Log^IHello world$
6. Zvýraznění tabulkového formátu testů
Poměrně často se setkáme s tím, že se tabulkový formát testů zvýrazňuje přímo v testovacím scénáři s využitím znaků |. Právě na tomto formátu je nejlépe patrné, že i hlavičky jednotlivých sekcí (zde *** Test Cases ***) jsou vlastně pouhými buňkami tabulky. Taktéž je zřejmé, že klíčové slovo „Log“ má parametr „Hello world“:
| *** Test Cases *** | | | | Demo | | | | | Log | Hello world |
| *** Test Cases *** | | | Demo | | | | Log Hello world |
Význam a určitá elegance tohoto způsobu zápisu vynikne zejména ve chvíli, kdy bude scénář obsahovat větší množství sekcí, více testovaných případů atd.:
| *** Settings *** | | | | Library | Test16.py | | | | | | | *** Test Cases *** | | | | Adder #1 | | | | | Add | 1 | 2 | | Result should be | 3 | | | | | | Adder #2 | | | | | Add | 0 | 0 | | Result should be | 0 | | | | | | Adder #3 | | | | | Add | 1 | -1 | | Result should be | 0 |
Alternativně:
| *** Settings *** | | | | Library | Test16.py | | | *** Test Cases *** | | | | Adder #1 | | | | | Add | 1 | 2 | | Result should be | 3 | | | Add | 2 | 3 | | Result should be | 5 | | | Add | 4 | 5 | | Result should be | 9 | | Adder #2 | | | | | Add | 0 | 0 | | Result should be | 0 | | Adder #3 | | | | | Add | 1 | -1 | | Result should be | 0 |
7. Formát založený na TSV
Dalším formátem testů podporovaných Robot Frameworkem je formát odvozený od TSV neboli Tab-separated values. Jedná se o jeden z nejjednodušších formátů – textový soubor, v němž každý řádek představuje jeden řádek tabulky a jednotlivé buňky na řádku jsou odděleny znakem Tab. Speciální znaky (včetně samotných tabů a konců řádků v buňkách) jsou uloženy v podobě známé například z céčkovské větve programovacích jazyků – \n, \t, \\ atd. Povšimněte si, že se jedná o jednodušeji implementovatelný formát, než je tomu v případě CSV s jeho mnoha variantami, ne vždy stoprocentně dodržovaným standardem, problematickým znakem konce řádku atd.
V případě použití TSV může vypadat testovací scénář takto. Na posledním řádku jsou naznačeny konce tabelačních zarážek (ty lze v mnoha editorech nastavit na zvolené indexy znaků):
*** Test Cases *** Demo Log Hello world ^ ^
Nepatrně složitější testovací scénář může vypadat následovně. Taby (nikoli mezery) jsou zvýrazněny zeleným pozadím:
Obrázek 4: Testovací scénář uložený v souborech typu TSV.
Výhoda použití TSV (pochopitelně v některých situacích) začne být zřejmá, pokud si uvědomíme, že soubory tohoto typu lze snadno vytvářet a editovat v prakticky každém tabulkovém procesoru:
Obrázek 5: Předchozí soubor, tentokrát otevřený v tabulkovém procesoru.
8. Testovací scénář s větším množstvím test casů
V dalším demonstračním příkladu je ukázáno, jakým způsobem lze zapsat testovací scénář s trojicí test casů (případů). Jednotlivé casy není zapotřebí oddělovat, protože rozlišení mezi krokem testu a začátkem nového test casu je provedeno na základě odsazení řádků (dvě či více mezer == přechod na další buňku pomyslné tabulky):
*** Test Cases *** Case1 Log Case#1 Case2 Log Case#2 Case3 Log Case#3
Pochopitelně nám ovšem nikdo nebrání vložit do testovacího scénáře oddělovací prázdné řádky:
*** Test Cases *** Case1 Log Case#1 Case2 Log Case#2 Case3 Log Case#3
Po spuštění testu příkazem robot by se měla zobrazit tabulka s výsledky všech testů, které byly provedeny:
$ robot test06.robot
V tomto případě všechny testy proběhnou v pořádku, protože jediným příkazem je Log:
============================================================================== Test06 ============================================================================== Case1 | PASS | ------------------------------------------------------------------------------ Case2 | PASS | ------------------------------------------------------------------------------ Case3 | PASS | ------------------------------------------------------------------------------ Test06 | PASS | 3 critical tests, 3 passed, 0 failed 3 tests total, 3 passed, 0 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
Ve webovém prohlížeči si můžeme prohlédnout vygenerované soubory s výsledky:
Obrázek 6: Přehled s výsledky testovacího scénáře. Zelená barva naznačuje, že všechny testy skončily korektně.
Obrázek 7: Podrobnější pohled na jednotlivé kroky testu.
Obrázek 8: Podrobnější pohled na jednotlivé kroky testu, informace z logovacího souboru.
9. Přepis předchozího scénáře do „tabulkového“ formátu
Jen pro úplnost si ukažme, jak se předchozí test může přepsat do „tabulkového“ formátu. Je to ve skutečnosti velmi snadné:
| *** Test Cases *** | | | | | | | | Case1 | | | | | Log | Case#1 | | | | | | Case2 | | | | | Log | Case#2 | | | | | | Case3 | | | | | Log | Case#3 | | | | |
10. Testovací scénář s testem, který skončí s chybou
Můžeme si pochopitelně vyzkoušet i testovací scénář, ve kterém jeden test skončí s chybou; zde konkrétně zajištěnou použitím standardního klíčového slova Fail. Scénář bude vypadat následovně:
*** Test Cases *** Case1 Log Case#1 Case2 Fail Failure!!! Case3 Log Case#3
Test spustíme standardním způsobem:
$ robot test08.robot
Výsledky nyní budou podle očekávání odlišné, což je patrné již při pohledu na tabulku zobrazenou v průběhu testování nástrojem robot:
============================================================================== Test08 ============================================================================== Case1 | PASS | ------------------------------------------------------------------------------ Case2 | FAIL | Failure!!! ------------------------------------------------------------------------------ Case3 | PASS | ------------------------------------------------------------------------------ Test08 | FAIL | 3 critical tests, 2 passed, 1 failed 3 tests total, 2 passed, 1 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
To, že alespoň jeden test skončil s chybou, je patrné již při prvním pohledu na vytvořenou stránku, která je nyní červená:
Obrázek 9: Přehled s výsledky testovacího scénáře. Červená barva naznačuje pád alespoň jednoho testu.
Obrázek 10: Podrobnější pohled na jednotlivé kroky testu.
Obrázek 11: Podrobnější pohled na jednotlivé kroky testu, informace z logovacího souboru (červeně jsou označena problémová místa).
11. Klíčové slovo Repeat Keyword
V sadě standardních klíčových slov nalezneme mj. i slovo Repeat Keyword, které slouží, jak ostatně jeho název naznačuje, pro opakování jiného klíčového slova neboli opakování jednoho kroku testu. Opakování je možné specifikovat více způsoby – počtem opakování, celkovou dobou trvání opakování atd. Ukažme si, jak lze zajistit zápis pěti stejných vět do logovacího souboru:
*** Test Cases *** Repeated message demo Repeat Keyword 5 times Log Hello world
- Slovem Repeat Keyword
- Specifikací počtu opakování 5 times
- Slovem, které se má opakovat Log
- Parametrem opakovaného slova Hello world
Zkusme si nyní tento test spustit:
$ robot test09.robot
Průběh testu – vypíše se pouze jediný krok!:
============================================================================== Test09 ============================================================================== Repeated message demo | PASS | ------------------------------------------------------------------------------ Test09 | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
Teprve při pohledu na obsah logu je patrné, že skutečně došlo k opakovanému vypsání zprávy „Hello world“:
Obrázek 12: Podrobnější pohled na jednotlivé kroky testu, informace z logovacího souboru
12. Implementace vlastního klíčového slova v Pythonu
Existence standardních klíčových slov samozřejmě nebude pro tvorbu skutečných akceptačních testů dostatečná, takže musíme mít k dispozici mechanismus pro vytvoření nových klíčových slov. Ve skutečnosti je to mnohdy až triviálně snadné, o čemž se přesvědčíme v této kapitole i v kapitolách navazujících. Vytvoříme testovací scénář, v němž se bude používat nové klíčové slovo test definované ve zdrojovém souboru Test10.py. V testovacím scénáři je nutné specifikovat použití nové knihovny, a to v sekci settings:
*** Settings *** Library Test10.py *** Test Cases *** Demo test
Jak vlastně vypadá definice nového klíčového slova v Pythonu? V tom nejjednodušším možném případě se může jednat o běžnou funkci, jejíž název odpovídá klíčovému slovu (případná podtržítka pak oddělují jednotlivé části klíčového slova):
def test(): print("TEST")
To je vše – není zapotřebí provádět žádné importy, používat dekorátory atd. atd. (do funkcí lze předávat parametry, ovšem tuto problematiku si vysvětlíme později). O tom, že test bude moci být spuštěn, se přesvědčíme snadno:
$ robot test10.robot
S výsledkem:
============================================================================== Test10 ============================================================================== Demo | PASS | ------------------------------------------------------------------------------ Test10 | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
13. Klíčové slovo vytvořené v Pythonu způsobující pád testu
Vzhledem k tomu, že nová klíčová slova naprogramovaná například v Pythonu (popřípadě v Javě) tvoří základ testů, musíme znát způsob, jak dát Robot Frameworku najevo, že dané slovo (tedy jeden krok testu) zhavaroval. K tomuto účelu lze použít buď běžnou asserci (vyhazující výjimku), nebo výjimku vyhodit explicitně:
def test(): raise Exception("fatal error")
Testovací scénář upravíme takovým způsobem, aby používal nový modul Test11.py:
*** Settings *** Library Test11.py *** Test Cases *** Demo test
Upravený scénář spustíme:
$ robot test11.robot
A ze zobrazené tabulky ihned zjistíme, že k pádu testu skutečně došlo, podle našich předpokladů:
============================================================================== Test11 ============================================================================== Demo | FAIL | fatal error ------------------------------------------------------------------------------ Test11 | FAIL | 1 critical test, 0 passed, 1 failed 1 test total, 0 passed, 1 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article_01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article_01/log.html Report: /home/tester/src/Python/robot-framework-examples/article_01/report.html
14. Klíčová slova realizovaná formou metod
V předchozích dvou kapitolách jsme si ukázali, že nová klíčová slova lze definovat formou běžných Pythonovských funkcí. Jedná se o nejjednodušší způsob, který však má jednu zásadní nevýhodu – funkce nemá implicitně přístup ke kontextu, v němž je spuštěna. A kontext je většinou nutné si nějakým způsobem zapamatovat (například mezi několika kroky testu). Proto si v dalším příkladu ukážeme, jak lze nové klíčové slovo realizovat metodou. Je to prakticky stejně snadné:
class Test12: def __init__(self): print("INIT") def test(self): print("TEST")
V případě, že je třída Test12 uložena v souboru pojmenovaném Test12.py (Javovská konvence), není zapotřebí testovací scénář žádným zásadním způsobem modifikovat:
*** Settings *** Library Test12.py *** Test Cases *** Demo test
Spuštění testu bude probíhat stejným způsobem, jako tomu bylo u předchozích demonstračních příkladů.
15. Různé typy logovacích zpráv
Do logovacího souboru lze ukládat zprávy různých typů, což ostatně není žádná specialita Robot Frameworku. Pro logování lze i v Robot Frameworku použít standardní Pythonovskou knihovnu logging a v ní deklarované funkce info, debug, warn/warning, error či critical. Vytvořme si nyní novou funkci s několika metodami (a tedy i několika klíčovýmii slovy):
from logging import debug, error, info, warn class Test13: def __init__(self): print("INIT") def try_logging_module_info(self): info("info message") def try_logging_module_debug(self): debug("debug message") def try_logging_module_warning(self): warn("warning message") def try_logging_module_error(self): error("error message")
Testovací scénář bude obsahovat tři test casy, z nichž každý bude volat jinou kombinaci klíčových slov:
*** Settings *** Library Test13.py *** Test Cases *** Log1 Try Logging Module Info Try Logging Module Debug Log2 Try Logging Module Debug Try Logging Module Warning Log3 Try Logging Module Debug Try Logging Module Error
Výsledky běhu testu:
============================================================================== Test13 ============================================================================== Log1 | PASS | ------------------------------------------------------------------------------ Log2 | PASS | ------------------------------------------------------------------------------ Log3 | PASS | ------------------------------------------------------------------------------ Test13 | PASS | 3 critical tests, 3 passed, 0 failed 3 tests total, 3 passed, 0 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
Všimněte si, že všechny testy proběhly v pořádku (PASS), protože i zavolání funkce logging.error je jen zápis informace do logu a nikoli pád:
Obrázek 13: Různé typy zpráv zapsaných do logovacího souboru jsou zvýrazněny různými barvami.
16. Zajištění pádu testu s využitím aserce
Jen pro úplnost si ukažme, jak lze zajistit pád testu s využitím příkazu assert. Při nesplnění podmínky uvedené za tímto klíčovým slovem se vyhodí výjimka:
from logging import debug, error, info, warn class Test14: def __init__(self): print("INIT") def try_logging_module_info(self): info("info message") def try_logging_module_debug(self): debug("debug message") def try_logging_module_warning(self): warn("warning message") def try_logging_module_error(self): error("error message") assert False
Samotný testovací scénář mohl zůstat prakticky nezměněn, bylo nutné pouze modifikovat jméno zdrojového souboru s definicí nových klíčových slov:
*** Settings *** Library Test14.py *** Test Cases *** Log1 Try Logging Module Info Try Logging Module Debug Log2 Try Logging Module Debug Try Logging Module Warning Log3 Try Logging Module Debug Try Logging Module Error
Po spuštění testů je již sémantika vylepšena – za zprávou vypsanou do logu pomocí funkce logging.error skutečně následuje pád daného test casu:
============================================================================== Test14 ============================================================================== Log1 | PASS | ------------------------------------------------------------------------------ Log2 | PASS | ------------------------------------------------------------------------------ Log3 | FAIL | AssertionError ------------------------------------------------------------------------------ Test14 | FAIL | 3 critical tests, 2 passed, 1 failed 3 tests total, 2 passed, 1 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
Obrázek 14: Pohled na výsledky běhu testu.
Obrázek 15: Podrobnější pohled na test case, který zhavaroval.
17. První skutečný testovací scénář – test funkce kalkulačky
Předchozí příklady byly poměrně umělé, protože jsme si potřebovali ukázat základní vlastnosti Robot Frameworku. Ukažme si tedy nyní první skutečný testovací scénář, v němž budeme testovat operátor součtu. Pro tento účel budou vytvořena dvě klíčová slova Add a Result Should Be. První klíčové slovo bude akceptovat dva parametry, které sečte a uloží do kontextu (ten je představován vlastní instancí třídy Test16). Druhé klíčové slovo porovná vypočtený výsledek s očekávaným výsledkem a v případě neshody způsobí pád příslušného test casu:
class Test15: def __init__(self): print("INIT") def add(self, x, y): self.result = x + y def result_should_be(self, expected): assert self.result == expected, "{} != {}".format(self.result, expected)
Testovací scénář bude rozsáhlejší, protože v něm budeme zjišťovat výsledky tří operací součtu:
*** Settings *** Library Test15.py *** Test Cases *** Adder #1 Add 1 2 Result should be 3 Adder #2 Add 0 0 Result should be 0 Adder #3 Add 1 -1 Result should be 0
Spuštění tohoto scénáře může být zklamáním, protože všechny tři test casy zhavarují:
============================================================================== Test15 ============================================================================== Adder #1 | FAIL | 12 != 3 ------------------------------------------------------------------------------ Adder #2 | FAIL | 00 != 0 ------------------------------------------------------------------------------ Adder #3 | FAIL | 1-1 != 0 ------------------------------------------------------------------------------ Test15 | FAIL | 3 critical tests, 0 passed, 3 failed 3 tests total, 0 passed, 3 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
Z vygenerovaných chybových zpráv lze snadno odvodit, kde nastala chyba: parametry byly do metod předány jako řetězce a operátorem + došlo ke spojení těchto řetězců, nikoli k součtu.
Obrázek 16: Celkový pohled na výsledky testů.
Obrázek 17: Podrobnější pohled na výsledky testů.
Celý testovací scénář můžeme zapsat i ve formě tabulky, což může být v mnoha případech lepší způsob. Povšimněte si, že parametry klíčových slov musí být umístěny do zvláštních sloupců:
| *** Settings *** | | | | Library | Test16.py | | | *** Test Cases *** | | | | Adder #1 | | | | | Add | 1 | 2 | | Result should be | 3 | | | Add | 2 | 3 | | Result should be | 5 | | | Add | 4 | 5 | | Result should be | 9 | | Adder #2 | | | | | Add | 0 | 0 | | Result should be | 0 | | Adder #3 | | | | | Add | 1 | -1 | | Result should be | 0 |
18. Korektní práce s parametry klíčových slov
Úprava námi vytvořených klíčových slov takovým způsobem, aby se jejich parametry zpracovávaly jako celá čísla (popř. čísla s plovoucí řádovou čárkou), je v Pythonu relativně přímočará. Použijeme konverzní funkci int a ponecháme na této funkci, aby v případě špatného vstupu vyhodila výjimku typu ValueError:
class Test16: def __init__(self): pass print("INIT") def add(self, x, y): self.result = int(x) + int(y) def result_should_be(self, expected): assert self.result == int(expected), "{} != {}".format(self.result, expected)
Samotný testovací scénář zůstane prakticky nezměněn:
*** Settings *** Library Test16.py *** Test Cases *** Adder #1 Add 1 2 Result should be 3 Adder #2 Add 0 0 Result should be 0 Adder #3 Add 1 -1 Result should be 0
Výsledky ovšem již budou odpovídat tomu, že skutečně testujeme funkci operátoru pro součet dvou čísel a nikoli pro spojení dvou řetězců:
============================================================================== Test16 ============================================================================== Adder #1 | PASS | ------------------------------------------------------------------------------ Adder #2 | PASS | ------------------------------------------------------------------------------ Adder #3 | PASS | ------------------------------------------------------------------------------ Test16 | PASS | 3 critical tests, 3 passed, 0 failed 3 tests total, 3 passed, 0 failed ============================================================================== Output: /home/tester/src/Python/robot-framework-examples/article01/output.xml Log: /home/tester/src/Python/robot-framework-examples/article01/log.html Report: /home/tester/src/Python/robot-framework-examples/article01/report.html
Obrázek 18: Celkový pohled na výsledky testů.
Obrázek 19: Podrobnější pohled na výsledky testů.
19. Repositář s demonstračními příklady
Zdrojové kódy všech dnes použitých demonstračních příkladů byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/robot-framework-examples (stále na GitHubu :-). V případě, že nebudete chtít klonovat celý repositář, můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:
20. Odkazy na Internetu
- Stránka projektu Robot Framework
https://robotframework.org/ - GitHub repositář Robot Frameworku
https://github.com/robotframework/robotframework - Robot Framework (Wikipedia)
https://en.wikipedia.org/wiki/Robot_Framework - Tutoriál Robot Frameworku
http://www.robotframeworktutorial.com/ - Robot Framework Documentation
https://robotframework.org/robotframework/ - Robot Framework Introduction
https://blog.testproject.io/2016/11/22/robot-framework-introduction/ - robotframework 3.1.2 na PyPi
https://pypi.org/project/robotframework/ - Robot Framework demo (GitHub)
https://github.com/robotframework/RobotDemo - Robot Framework web testing demo using SeleniumLibrary
https://github.com/robotframework/WebDemo - Robot Framework for Mobile Test Automation Demo
https://www.youtube.com/watch?v=06LsU08slP8 - Selenium
https://selenium.dev/ - SeleniumLibrary
https://robotframework.org/ - The Practical Test Pyramid
https://martinfowler.com/articles/practical-test-pyramid.html - Acceptance Tests and the Testing Pyramid
http://www.blog.acceptancetestdrivendevelopment.com/acceptance-tests-and-the-testing-pyramid/ - Programovací jazyk Clojure – testování s využitím knihovny Expectations
https://www.root.cz/clanky/programovaci-jazyk-clojure-testovani-s-vyuzitim-knihovny-expectations/ - Programovací jazyk Clojure – některé užitečné triky použitelné (nejenom) v testech
https://www.root.cz/clanky/programovaci-jazyk-clojure-nektere-uzitecne-triky-pouzitelne-nejenom-v-testech/ - Použití jazyka Gherkin při tvorbě testovacích scénářů pro aplikace psané v Clojure
https://www.root.cz/clanky/pouziti-jazyka-gherkin-pri-tvorbe-testovacich-scenaru-pro-aplikace-psane-v-nbsp-clojure/ - Tab-separated values
https://en.wikipedia.org/wiki/Tab-separated_values - A quick guide about Python implementations
https://blog.rmotr.com/a-quick-guide-about-python-implementations-aa224109f321 - Python 2.7 will retire in…
https://pythonclock.org/