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()