Zrzuty ekranu po niepowodzeniu asercji – plan działania

W tej lekcji zajmiemy się opakowaniem naszych asercji, tak aby w razie wystąpienia błędu asercji tworzony był również zrzut ekranu.

Zacznijmy powoli od najprostszych testów i przeanalizujmy kod, który już mamy, w celu zaplanowania naszych działań. Przejdźmy do pliku lost_hat_smoke_tests.py do klasy LostHatSmokeTests i zerknijmy na pierwszy test:

def test_base_page_title(self):
   expected_title = 'Lost Hat'
   self.assert_title(self.base_url, expected_title)

Rzućmy też okiem na pomocniczą metodą do asercji:

def assert_title(self, url, expected_title):
   actual_title = self.get_page_title(url)
   self.assertEqual(expected_title, actual_title,
                    f'Expected {expected_title} differ from actual title {actual_title} on page: {url}')

Która metodę chcielibyśmy udekorować? Główną assert_title a może wewnętrzną assert_equal?

To jest dobry moment, aby przystanąć na chwile. Przypadek, z którym się w tym momencie stykamy występuje bardzo często w przyrodzie i można go opisać w następujący sposób:

Mamy już całkiem zaawansowane rozwiązanie, ale potrzebujemy wprowadzić ważną zmianę, która dotknie wielu miejsc, oraz w przyszłości wpłynie na kolejne rozwiązania. Które miejsce będzie najlepsze? Jaka modyfikacja będzie najkorzystniejsza i nie spowoduje w przyszłości potrzeby przepisania połowy naszego kodu?

Tutaj musimy się dobrze zastanowić, bo zmiany, które wprowadzimy w tym teście, będziemy musieli następnie rozpropagować na wszystkie testy. Wprowadzenie dekoratora dla każdej asercji w tym miejscu może wydawać się proste, ale pytanie czy tak prosto będzie w każdym innym miejscu? Poza klasycznym assert_equal mamy też assert_greater_equal oraz kilka innych metod. Wszystkie z nich wymagałyby poprawek…

Spójrzmy na nasz problem szerzej… Wyjdźmy z naszych metod… Popatrzmy na wszystkie nasze testy…

A może by tak udekorować… cały test (czyli cała metodę testową)? 😀

W sumie czemu nie – każdy nasz test też jest metodą, więc jest możliwe jego udekorowanie. Co nam to da i czego będzie od nas wymagało? Będziemy musieli stworzyć tak naprawdę tylko jeden dekorator. Wystarczy, że umieścimy go nad dowolną metoda testową i będziemy mogli obsługiwać niepoprawne testy i robić screenshoty!

Jak nasz plan będzie wyglądał w praktyce?

  1. Przygotujemy dekorator do metod testowych.
  2. Wyłapiemy w nim testy, które kończą się niepowodzeniem asercji
  3. Dodamy robienie screenshota.
  4. Udekorujemy każdy z naszych testów.
  5. Sprawimy aby nasze raporty korzystały z tego rozwiązania.

Chyba nie brzmi aż tak strasznie, prawda? 😉 A przy okazji czeka nas masa praktycznych wyzwań!

Zatem do dzieła! 🙂

2 komentarze

    1. Hej,
      W przypadku, gdy chcielibyśmy udekorować samą metodę, to najpierw musielibyśmy wydzielić ją do osobnej metody. W naszym przypadku, mając na uwadze co chcemy osiągnąć (tzn zrzuty ekranu) całość mogłaby wyglądać w następujący sposób:

      W ten sposób mogłaby wyglądać nasza wydzielona metoda do porównywania (helpers/assertion_helpers.py):

      from helpers.assertion_wrappers import assertion_wrapper
      
      def assert_equal(unittest_self, expected, actual, message):
          assertion = assertion_wrapper(unittest_self.assertEqual)
          assertion(unittest_self.ef_driver, expected, actual, message)
      

      W ten sposób mógłby wyglądać nasz dekorator (helpers/assertion_wrappers.py):

      def assertion_wrapper(assert_fun):
          def wrapper(driver, actual, expected, message):
              try:
                  return assert_fun(actual, expected, message)
              except AssertionError as ex:
                  ScreenshotListener().on_exception(ex, driver)
                  raise ex
      
          return wrapper
      

      W samym teście (w smoke_tests.py) wywołalibyśmy ją w ten sposób:

          from helpers import assertion_helpers as ah
          def assert_title(self, url, expected_title):
              actual_title = self.get_page_title(url)
              ah.assert_equal(self, expected_title, actual_title,
                               f'Expected {expected_title} differ from actual title {actual_title} on page: {url}')
      
      

      Samo udekorowanie metody nie jest trudne. Trudność pojawia się w tym przypadku w momencie, gdy w dekoratorze chcemy wykorzystać naszego drivera przy jednoczesnym zachowaniu dobrych praktyk (np. braku powielania kodu). Przy wydzieleniu metod do asercji do osobnego modułu musimy dodatkowo podać kontekst testów (czyli po prostu self), gdyż assertEqual jest metodą z unittest.TestCase (i stąd unittest_self w assert_equal). Do tego, dodatkowym problemem może być fakt, że metod do asercji mamy kilka różnych rodzajów – czyli powyższą operację musielibyśmy powielić do każdej z tych metod… 😉

      Pozdrawiam,

      Krzysiek Kijas Krzysiek Kijas

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *