Python Web Scraping - Testowanie za pomocą skrobaków

W tym rozdziale wyjaśniono, jak przeprowadzić testy przy użyciu skrobaków sieci w języku Python.

Wprowadzenie

W dużych projektach internetowych automatyczne testowanie zaplecza witryny jest przeprowadzane regularnie, ale testy frontendu są często pomijane. Głównym tego powodem jest to, że programowanie stron internetowych przypomina sieć różnych języków znaczników i języków programowania. Możemy napisać testy jednostkowe dla jednego języka, ale staje się to trudne, jeśli interakcja odbywa się w innym języku. Dlatego musimy mieć zestaw testów, aby upewnić się, że nasz kod działa zgodnie z naszymi oczekiwaniami.

Testowanie w Pythonie

Kiedy mówimy o testowaniu, oznacza to testowanie jednostkowe. Zanim zagłębimy się w testowanie w Pythonie, musimy wiedzieć o testowaniu jednostkowym. Oto niektóre cechy testów jednostkowych:

  • Przynajmniej jeden aspekt funkcjonalności komponentu byłby testowany w każdym teście jednostkowym.

  • Każdy test jednostkowy jest niezależny i może również działać niezależnie.

  • Test jednostkowy nie koliduje z sukcesem ani porażką żadnego innego testu.

  • Testy jednostkowe mogą być uruchamiane w dowolnej kolejności i muszą zawierać co najmniej jedno potwierdzenie.

Unittest - moduł Pythona

Moduł Pythona o nazwie Unittest do testów jednostkowych jest dostarczany ze wszystkimi standardowymi instalacjami Pythona. Musimy go tylko zaimportować, a resztę zajmie klasa unittest.TestCase, która wykona następujące czynności -

  • Funkcje SetUp i tearDown są dostarczane przez klasę unittest.TestCase. Te funkcje mogą być uruchamiane przed i po każdym teście jednostkowym.

  • Zawiera również instrukcje assert, które pozwalają testom przejść lub nie.

  • Uruchamia wszystkie funkcje, które zaczynają się od test_ jako test jednostkowy.

Przykład

W tym przykładzie zamierzamy połączyć skrobanie sieci z unittest. Przetestujemy stronę Wikipedii pod kątem wyszukiwania ciągu „Python”. Zasadniczo wykona dwa testy, najpierw czy strona tytułowa jest taka sama jak szukany ciąg, tj. „Python” czy nie, a drugi test upewnia się, że strona ma element div z treścią.

Najpierw zaimportujemy wymagane moduły Pythona. Używamy BeautifulSoup do skrobania stron internetowych i oczywiście niestety do testowania.

from urllib.request import urlopen
from bs4 import BeautifulSoup
import unittest

Teraz musimy zdefiniować klasę, która będzie rozszerzać unittest.TestCase. Globalne obiekty b byłyby współużytkowane przez wszystkie testy. Osiągnie to niezatwierdzona funkcja setUpClass. Tutaj zdefiniujemy dwie funkcje, jedną do testowania strony tytułowej, a drugą do testowania zawartości strony.

class Test(unittest.TestCase):
   bs = None
   def setUpClass():
      url = '<a target="_blank" rel="nofollow" href="https://en.wikipedia.org/wiki/Python">https://en.wikipedia.org/wiki/Python'</a>
      Test.bs = BeautifulSoup(urlopen(url), 'html.parser')
   def test_titleText(self):
      pageTitle = Test.bs.find('h1').get_text()
      self.assertEqual('Python', pageTitle);
   def test_contentExists(self):
      content = Test.bs.find('div',{'id':'mw-content-text'})
      self.assertIsNotNone(content)
if __name__ == '__main__':
   unittest.main()

Po uruchomieniu powyższego skryptu otrzymamy następujący wynik -

----------------------------------------------------------------------
Ran 2 tests in 2.773s

OK
An exception has occurred, use %tb to see the full traceback.

SystemExit: False

D:\ProgramData\lib\site-packages\IPython\core\interactiveshell.py:2870:
UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

Testowanie z selenem

Omówmy, jak używać Python Selenium do testowania. Nazywa się to również testowaniem selenu. Zarówno Pythonunittest i Seleniumnie mają ze sobą wiele wspólnego. Wiemy, że Selenium wysyła standardowe polecenia Pythona do różnych przeglądarek, pomimo różnic w projekcie ich przeglądarek. Przypomnij sobie, że już zainstalowaliśmy Selenium i pracowaliśmy z nim w poprzednich rozdziałach. Tutaj stworzymy skrypty testowe w Selenium i wykorzystamy je do automatyzacji.

Przykład

Z pomocą kolejnego skryptu w Pythonie tworzymy skrypt testowy do automatyzacji strony logowania na Facebooku. Możesz zmodyfikować przykład automatyzacji innych wybranych formularzy i loginów, jednak koncepcja byłaby taka sama.

Najpierw do połączenia z przeglądarką internetową zaimportujemy webdriver z modułu selenium -

from selenium import webdriver

Teraz musimy zaimportować klucze z modułu selenu.

from selenium.webdriver.common.keys import Keys

Następnie musimy podać nazwę użytkownika i hasło, aby zalogować się do naszego konta na Facebooku

user = "[email protected]"
pwd = ""

Następnie podaj ścieżkę do sterownika internetowego dla przeglądarki Chrome.

path = r'C:\\Users\\gaurav\\Desktop\\Chromedriver'
driver = webdriver.Chrome(executable_path=path)
driver.get("http://www.facebook.com")

Teraz zweryfikujemy warunki za pomocą słowa kluczowego assert.

assert "Facebook" in driver.title

Za pomocą następującego wiersza kodu wysyłamy wartości do sekcji e-mail. Tutaj szukamy go według identyfikatora, ale możemy to zrobić, wyszukując go według nazwy jakodriver.find_element_by_name("email").

element = driver.find_element_by_id("email")
element.send_keys(user)

Za pomocą następującego wiersza kodu przesyłamy wartości do sekcji hasła. Tutaj szukamy go według identyfikatora, ale możemy to zrobić, wyszukując go według nazwy jakodriver.find_element_by_name("pass").

element = driver.find_element_by_id("pass")
element.send_keys(pwd)

Kolejna linia kodu służy do naciśnięcia enter / login po wprowadzeniu wartości w polu email i hasło.

element.send_keys(Keys.RETURN)

Teraz zamkniemy przeglądarkę.

driver.close()

Po uruchomieniu powyższego skryptu otworzy się przeglądarka internetowa Chrome i zobaczysz, że e-mail i hasło są wstawiane i klikane w przycisk logowania.

Porównanie: unittest lub Selenium

Porównanie unittest i selenu jest trudne, ponieważ jeśli chcesz pracować z dużymi zestawami testów, wymagana jest syntaktyczna sztywność jednostek. Z drugiej strony, jeśli zamierzasz przetestować elastyczność witryny, to test Selenium byłby naszym pierwszym wyborem. Ale co, jeśli uda nam się połączyć oba. Możemy zaimportować selen do Python unittest i uzyskać to, co najlepsze z obu. Selen może służyć do uzyskiwania informacji o witrynie internetowej, a unittest może ocenić, czy informacje te spełniają kryteria zdania testu, czy też nie.

Na przykład przepisujemy powyższy skrypt Pythona do automatyzacji logowania na Facebooku, łącząc oba w następujący sposób -

import unittest
from selenium import webdriver

class InputFormsCheck(unittest.TestCase):
   def setUp(self):
      self.driver = webdriver.Chrome(r'C:\Users\gaurav\Desktop\chromedriver')
      def test_singleInputField(self):
      user = "[email protected]"
      pwd = ""
      pageUrl = "http://www.facebook.com"
      driver=self.driver
      driver.maximize_window()
      driver.get(pageUrl)
      assert "Facebook" in driver.title
      elem = driver.find_element_by_id("email")
      elem.send_keys(user)
      elem = driver.find_element_by_id("pass")
      elem.send_keys(pwd)
      elem.send_keys(Keys.RETURN)
   def tearDown(self):
      self.driver.close()
if __name__ == "__main__":
   unittest.main()