Potyczki z Selenium część 1

W tej odsłonie bloga chciałbym się podzielić doświadczeniami z uruchamianiem automatycznych testów. W kwestii technicznej używamy SpecFlow wraz z Selenium do tworzenia BDD i chcieliśmy dołączyć uruchamianie testów automatycznych do naszej ciągłej integracji. W części 1 opiszę naszą drogę do uzyskania środowiska wraz ze ślepymi uliczkami które sprawdziliśmy nie wnikając bardzo w techniczną stronę zagadnienia. W 2 części wpisu podzielę się również skryptami power shell i konfiguracją, której używamy finalnie.

W sumie początki wydawały się proste i obiecujące – choć nie bezbolesne. Na początku dało nam się we znaki stworzenie driver-a we frameworku do testów jako statycznej zmiennej. To bardzo szybko wywołało konieczność większego refactoring-u bo uniemożliwiało uruchamianie równoległe testów (wtedy jeszcze nie wiedzieliśmy, że temat równoległości zajmie nas na dłuższy czas).

Używane technologie

Używamy SpecFlow (v2.2.1) do BDD, Selenium WebDrivera (v3.5.2) i oparte to jest na NUnit runnerze (3.7.0). Numery wersji podaję, bo okazało się to ważne (szczegóły dalej w tekście). Testowane oprogramowanie używa React/Redux, ale to akurat z punktu widzenia testów jest mniej istotne.

Historia uruchamiania

Testy powstawały w ramach rozwoju produktu i powstała konieczność zintegrowania ich z ciągłą integracją. Uruchomienie wymagało drobnych zmian aby przenieść ustawienia środowiska z app.config do pliku .runsettings aby można było sterować wykonaniem testów z poziomu definicji build-a. Nic wielkiego, jest dużo tutoriali, poszło szybko.

Następnym problemem do ominięcia stało się uruchomienie Selenium Hub-a wraz z node-ami do uruchamiania testów automatycznych. Wtedy pojawiły się pierwsze schody związane z bezobsługowością rozwiązania. Ponieważ chcialiśmy testować na kilku przeglądarkach (Internet Explorer, Edge, Chrome i FireFox) wyborem na node była stacja z Windows 10. Ale od razu pojawiły się problemy z Hub-em i Node-em.

W pierwszym podejściu próbowaliśmy uruchomić Hub-a i Node-a jako serwisy Windows (wydawało się to naturalnym wyborem). NSSM („The Non-Sucking Service Manager”) i Hub działa. Ale od razu okazało się, że w przypadku Node’a to nie zadziała. O ile w przypadku Hub-a serwis sprawdzał się całkowicie, o tyle w przypadku Node-a Internet Explorer i Edge odmówiły zdecydowanie współpracy. Chyba Chrom i FireFox działały, choć na 100% trudno mi w tej chwili zawyrokować – ze względu na konieczność wspierania innych przeglądarek musieliśmy zrezygnować z tego rozwiązania. Wiadomo – problem Sesji 0 w Windows. Poszukiwania rozwiązania nie doprowadziły do sukcesu. A więc nie tędy droga.

Następnym krokiem stał się uruchomienie Node’ów w trybie zalogowanym do Windows – ze względu na policy w naszej domenie musieliśmy użyć softu do „poruszania” myszką co chwila, ale normalnie powinno wystarczyć wyłączenie wszelkich power options lub użycie softu do utrzymywania Windowsa w stanie zalogowanym lub wreszcie autologin Windows przy starcie (u nas też nie działa ze względu na domenowe policy).

Uff, jest, działa, mamy Hub-a i 2 Node’y i gra muzyka. Czy faktycznie? Testów coraz więcej, czas wykonywania wszystkiego zaczyna puchnąć. Mamy 2 Node’y więc sensowne wydaje się użycie równoległości. No i od razu trafiamy na rafy. Pojawiło się ich kilka, postaram się je opisać kolejno – niekoniecznie pojawiały się w tej kolejności, ale ważniejsze jest zgrupowanie tematyczne niż chronologia.

Równoległość w NUNit runner

NUnit runner w wersji nowszej niż 3.7.0 ma problemy z równoległym uruchamianiem testów. Wyszło po długich bojach, ale objawia się to losowymi błędami podczas równoległego uruchamiania testów (nie można pobrać następnego kroku). Oczywiście dodatkowo w samym frameworku SpecFlow trzeba zmienić odwołania do ScenarioContext ale to jest opisywane w dokumentacji do SpecFlow więc nie będę tutaj rozszerzał tematu. Konfigurację samego assembly opiszę w drugiej części artykułu.

Internet Explorer

Kiedy już udało się uruchomić testy równolegle pojawił się problem równoległej pracy przeglądarek na Node’ach Selenium. O ile Chrome i FireFox działały bezbłędnie nawet w kilku instancjach o tyle Internet Explorer zaczął stawiać opór. Po wielu testach okazało się, że problemem jest Focus, a raczej jego przenoszenie do innych przeglądarek. Ten sam test uruchomiony indywidualnie działał, ale jego równoległe uruchomienie z testem np. na Chrome powodowało, że fokus z IE znikał, a driver nie był już w stanie odnaleźć elementów strony (choć były one dostępne). Rozwiązaniem okazało się połączenie 2 rozwiązań:
1) Użycie 64-bitowego IE WebDriver-a wraz z 64-bitową przeglądarką + konfiguracja opisana dla IE WebDriver-a (wpisy w rejestrze)
2) Użycie Headless IE Selenium

FireFox

Z FireFox okazało się, że wersja WebDriver-a która działa lokalnie nie działa na Node-ach i odwrotnie. Na ten moment używamy najnowszej wersji WebDriver-a i używamy Node-ów również do lokalnego wykonywania testów.

Edge

Tu niestety dobre wieści się kończą. Edge zmusił nas do wywieszenia białej flagi. Generalnie testy działają, ale czasami (zupełnie losowo, a przynajmniej bez jasnej przyczyny) test potrafi się zawiesić na dłuższy czas. Po kilku próbach zmuszenia Edge-a do współpracy zrezygnowaliśmy i dopóki nie pojawi się nowsza wersja WebDriver-a zrezygnowaliśmy z testowania na Edge.

Podsumowanie

Na ten moment mamy uruchomione testy automatyczne w konfiguracji 2 Node i Hub. Na Nod’ach mamy po kilka instancji Chrome, FireFox i IE i działa to stabilnie (oczywiście mamy skrypty powershell do resetowania Node’ów – opiszę w 2 części wpisu). W przyszłości liczymy na pojawienie się stabilnej wersji WebDriver-a do Edge i poprawienia błedów w NUnit runnerze, aby możliwe było użycie nowszej wersji.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

This site uses Akismet to reduce spam. Learn how your comment data is processed.