zautomatyzowane testowanie jednostkowe aplikacji internetowej w Pythonie

# Python # Unittest #Selenium # Automation

w tym poście przyjrzymy się, jak testować jednostkowo aplikację internetową w Pythonie w celu sprawdzenia poprawności funkcjonalności. Whoa! To zdanie ma garść żargonu: test jednostkowy, aplikacja internetowa i testowanie funkcjonalności.

przyjrzeliśmy się testom jednostkowym programu Pythona w poprzednim poście. Zachęcamy do zapoznania się z nim, jeśli nie jesteś zaznajomiony z testowaniem jednostkowym.

co to jest test jednostkowy?

jednostka jest najmniejszą testowalną częścią programu lub aplikacji.

tak więc testy jednostkowe są używane do programowego testowania każdego testowanego komponentu.

możesz przetestować program backendowy lub program frontendowy, taki jak aplikacja internetowa.

dla programu backend, napisałbyś test jednostkowy dla każdej funkcji lub metody w kodzie, ponieważ są to logiczne najmniejsze jednostki.

jednak w przypadku interfejsu użytkownika zidentyfikujesz różne funkcjonalności, które chcesz sprawdzić i odpowiednio napisać testy jednostkowe.

w tym poście zamierzamy przetestować program frontendowy, a mianowicie aplikację internetową.

co to jest aplikacja internetowa?

każda aplikacja renderująca w przeglądarce internetowej, takiej jak Chrome, Firefox lub Safari.

wszystkie aplikacje internetowe mają jedną wspólną cechę-są widoczne dla użytkowników końcowych na stronie HTML (Hypertext Markup Language). HTML jest po prostu językiem formatującym opisującym, jak rzeczy powinny być zorganizowane. Jest to po prostu plik tekstowy.

przeglądarki pobierają tę stronę HTML i interpretują znaczniki (np. HEAD, BODY, HREF, TABLE, itd.), aby pokazać ci ładną stronę.

aplikacje internetowe działają w architekturze klient-serwer — gdzie serwer internetowy hostuje treści, do których chcesz uzyskać dostęp, A przeglądarka internetowa działa jako klient.

Architektura sieci klient-serwer

co to jest testowanie funkcjonalności?

jak sama nazwa wskazuje, pisząc kod testowania funkcjonalności, twoim celem jest przetestowanie funkcjonalności aplikacji. Innymi słowy, chcesz mieć pewność, że aplikacja jest zgodna ze specyfikacją funkcjonalną.

istnieją inne rodzaje testów, takie jak testy wydajności, testy bezpieczeństwa (penetracji) i testy akceptacji użytkowników.

napisany przez Ciebie kod testu funkcjonalnego może być zawarty w tak zwanym teście regresji, który jest okresowo wykonywany w celu upewnienia się, że stara funkcjonalność nie jest zepsuta z powodu nowego rozwoju.

pod koniec tego postu zrozumiesz Pełny kod wymieniony poniżej.

nie zniechęcaj się, jeśli uważasz, że to za dużo. Celem tego postu jest przeanalizowanie tego i pokazanie, jak możesz zrozumieć ten kod, a następnie napisać własny!

poniższy diagram przedstawia podejście wysokiego poziomu do automatycznego testowania aplikacji internetowej (strony).

kroki testowania aplikacji webowych

w celu napisania naszych testów używamy frameworka testowego o nazwie unittest. Jest bardzo podobny do junit w Javie lub nunit w .Net.

unittest umożliwia grupowanie kodu inicjalizacyjnego w funkcję setUp i czyszczenie kodu za pomocą funkcji tearddown.

poniższy diagram przedstawia ogólne podejście do badań jednostkowych.

Unit test framework

jak widać na powyższym schemacie, zestaw testów składa się z jednego lub więcej przypadków testowych.

przypadek testowy może mieć jeden lub więcej testów. W tym poście skupimy się na przypadku testowym z jednym testem. Na końcu pokażemy, jak dodać więcej testów do tego samego przypadku testowego, a także utworzyć pakiet testów.

jak wspomniano wcześniej, każdy przypadek testowy ma metody setUp (uruchom na początku) i tearDown (uruchom na końcu) odpowiednio do inicjalizacji i czyszczenia.

struktura jednostkowego przypadku testowego

powyższy fragment kodu pokazuje strukturę jednostkowego przypadku testowego.

linia 1: Import niezbędnych bibliotek. W naszym przypadku korzystamy z bibliotek selenium i unittest.

linia 3: tworzysz klasę o nazwie MyTestCase, która rozszerza unittest.Klasa TestCase. Mówimy, że najbardziej jednostkowy.TestCase jest klasą nadrzędną, a MyTestCase jest klasą podrzędną.

linia 4: dodajemy nasz kod inicjalizacji w metodzie setUp. Musisz użyć dokładnej nazwy metody, aby poinformować unittest, że dodajesz tutaj swój kod inicjalizacyjny. Po uruchomieniu tego przypadku testowego ta metoda zostanie wykonana jako pierwsza.

linia 7: przykładowy test, który chcemy uwzględnić w przypadku testowym.

linia 10: kolejny przykładowy test, który mamy w naszym przypadku testowym.

linia 16: dodajemy nasz kod czyszczenia wewnątrz tej metody tearDown. W przeciwieństwie do metody setUp, metoda tearDown zostanie wykonana jako ostatnia.

tak więc kolejność wywołania metody jest następująca:

setUp > test1 > test2 > … > tearDown

linia 20: to mówi, że główny program zaczyna się od tego miejsca.

linia 21: w ten sposób uruchamiasz przypadek testowy .

teraz nadszedł czas, aby dostać w swoje ręce rzeczywisty test, który chcieliśmy zrobić. Przypomnijmy, że chcemy sprawdzić, czy pole wyszukiwania Google zwraca co najmniej 5 wyników dla danego słowa kluczowego.

przyjrzyjmy się najpierw metodzie konfiguracji:

w tym fragmencie kodu tworzymy sterownik przeglądarki Chrome.

musisz pobrać sterownik selenium Chrome stąd, jeśli go jeszcze nie masz. W chwili pisania tego tekstu Chrome ma również wersję 74. Ponieważ moja przeglądarka Chrome to wersja 73, pobrałem wersję 73 do tego ćwiczenia.

linia 2 i 3 Utwórz opcję Chrome i daj selenium webdriver znać, że nie chcemy, aby przeglądarka była widoczna podczas uruchamiania testu.

jeśli nie dodasz tej opcji, test utknie w momencie otwarcia przeglądarki.

spójrzmy teraz na metodę tearDown:

po prostu czyścimy sterownik wywołując metodę quit ().

wreszcie nadszedł czas, aby spojrzeć na test, który chcemy uwzględnić w tym przypadku testowym. Przypomnijmy, że możemy testować (assert), jeśli liczba zwracanych wyników wyszukiwania jest większa lub równa 5.

rzeczywisty kod testu

linia 1: Metoda badania rozpoczyna się od słowa „test”.

linia 3: załaduj www.google.com strony WWW do sterownika (zauważ, że ja.driver jest tworzony podczas konfiguracji).

Kolejka 6: Znajdź pole wyszukiwania według nazwy elementu HTML”q”. Musisz sprawdzić stronę HTML, aby ją zidentyfikować.

linia 7: Ustaw pole wyszukiwania puste w przypadku, gdy są jakieś wartości domyślne.

linia 10: wypełnij pole wyszukiwania ciągiem wyszukiwania „automatyczne testowanie”.

linia 11: prześlij zapytanie do Google.

linia 14: XPath identyfikujące nagłówki wyników wyszukiwania.

linia 17: poczekaj 10 sekund, aż Strona wyników Google zostanie załadowana.

linia 20: Pobierz wszystkie nagłówki wyników wyszukiwania za pomocą XPath zdefiniowanego w linii 14.

linie 25 i 26: Nagłówki wyników wyszukiwania są w rzeczywistości listą i powtarzamy je, aby wyświetlić je na ekranie. Dodaliśmy te dwie linie tylko w celach demonstracyjnych. Zwykle skrypty testowe nie mają ekranów drukowania, ponieważ nie ma nikogo, kto mógłby gapić się na ekran, aby zobaczyć takie wyjście podczas automatyzacji.

Linijka 30: assertGreater jest metodą zdefiniowaną w unittest.Klasa TestCase, która pozwala nam sprawdzić, czy dane wyjściowe są większe od wartości some.

TestCase w rzeczywistości dostarcza nam zestaw takich metod sprawdzania równości, większej niż, mniejszej niż itp. zależy, co chcesz powiedzieć. Poniższy wykres przedstawia niektóre z powszechnie dostępnych metod assert.

wspólne metody Assert w unittest.TestCase

jak pokazano na początku, możesz napisać testowy przypadek, wywołując następujące w kodzie:

unittest.main()

w wierszu poleceń możesz po prostu wpisać nazwę pliku użytą do zapisania przypadku testowego.

python google_search_test.py

uruchamia setUp(), następnie test_result_count() i na końcu tearDown().

powinieneś zobaczyć wyjście podobne do następującego:

wynik uruchomienia przypadku testowego

jeśli jakikolwiek test się nie powiedzie, zobaczysz komunikat o błędzie wraz z metodą testową, która się nie powiodła.

to twój pierwszy udany przypadek testowy selenu/unittest. Gratulacje! To ważny krok milowy.

Bonus

jeśli masz Steama, zachęcam do śledzenia reszty, aby jeszcze bardziej zagłębić się w zautomatyzowane testowanie aplikacji webowych Selenium/unittest base.

powiedzmy, że chcesz sprawdzić, czy nagłówek jest równy „Google”.

kod testu wygląda następująco:

def test_header(self):
self.driver.get("http://www.google.com")
self.assertEqual("Google", self.driver.title)

teraz cały nasz testowy przypadek wygląda następująco:

class GoogleSearchTest(unittest.TestCase):
def setUp(self): def test_header(self): def test_result_count(self): def tearDown(self):
if __name__ == "__main__":
unittest.main()

Załóżmy, że powyższe ekrany drukowania są komentowane. Po uruchomieniu zaktualizowanego przypadku testowego należy uzyskać następujące dane wyjściowe:

test_header (__main__.GoogleSearchTest) ... ok
test_result_count (__main__.GoogleSearchTest) ... ok----------------------------------------------------------------------
Ran 2 tests in 13.799s
OK

mówi, że przeprowadził dwa testy i oba zakończyły się sukcesem.

powiedzmy, że w pierwszym teście zmieniam warunek assertEqual na następujący:

self.assertEqual("Microsoft", self.driver.title)

jak myślisz, co by się tu stało?

tak, dobrze zgadłeś. Pierwszy przypadek testowy zakończy się niepowodzeniem.kierowca.tytuł jest równy Google, Nie Microsoft.

otrzymasz wynik podobny do następującego:

test_header (__main__.GoogleSearchTest) ... FAIL
test_result_count (__main__.GoogleSearchTest) ... ok
====================================================================
FAIL: test_header (__main__.GoogleSearchTest)
--------------------------------------------------------------------
Traceback (most recent call last):
File "google_search_test.py", line 19, in test_header
self.assertEqual("Microsoft", self.driver.title)
AssertionError: 'Microsoft' != 'Google'
- Microsoft
+ Google
--------------------------------------------------------------------
Ran 2 tests in 14.011s
FAILED (failures=1)

powyższy wynik mówi, że tylko jeden test był udany, a nieudany.

kiedy piszesz swoje przypadki testowe po raz pierwszy, możesz napotkać takie sytuacje.

zakładając, że Twój przypadek testowy jest poprawny, zidentyfikujesz błędy w kodzie i poprosisz odpowiednich programistów o naprawienie problemu i ponowne przetestowanie.

Jeśli ten błąd wystąpi w teście regresji, błąd ten zostanie wprowadzony ze względu na rozwój nowego oprogramowania na bazie istniejącego kodu.

to pokazuje, że coś jest nie tak z nową bazą kodu, która wymaga naprawy, aby upewnić się, że stara funkcjonalność działa. Ponownie, deweloperzy muszą się tym zająć.

co powiesz na wiele przypadków testowych? Załóżmy, że mamy TestCase1 i TestCase2, z których każda ma kilka testów.

możesz utworzyć tak zwany pakiet testowy i uruchomić go za pomocą programu test runner w następujący sposób:

suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestCase1))
suite.addTest(unittest.makeSuite(TestCase2))
runner = unittest.TextTestRunner()
runner.run(suite)

powyższy kod uruchomi wszystkie testy w TestCase1, a następnie w TestCase2.

to wszystko na dziś. Mam nadzieję, że to pomoże.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.