Budowanie aplikacje przy wykorzystaniu TDD ( ang. Test Drivent Development) staje się nie tyle coraz popularniejsze, co wygodne (zwłaszcza przy dużych projektach), bowiem pozwala wyeliminować wiele błędów, które pojawiłyby się przy pominięciu tworzenia testów jednostkowych i funkcjonalnych budowanych aplikacji. Książka, które niezwykle ciekawie przedstawia proces TDD w praktyce jest Test-Driven Development with Python, w której na przykładzie języka Python oraz framework’a Django autor pokazał jak tworzyć testy jednostkowe oraz testy funkcjonalne w Selenium.
Przykłady omawiane w książce dostępne są w GitHub, które można pobrać i wykorzystać do nauki nie tylko samego Django i Python’a, ale przede wszystkim podejścia TDD i testów w Selenium. Poniżej przedstawiony został przykładowy test w Selenium wraz z komentarzami zbudowany właśnie na podstawie lektury wspomnianej książki.
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class NewVisitorTest(StaticLiveServerTestCase):
def setUp(self):
# wykorzystanie sterownika dla Chrome (wcześniej pobranego i umieszczonego w odpowiednim katalogu)
self.browser = webdriver.Chrome('/Users/seba/Projects/python/drivers/chromedriver')
# odczekanie 3 sekund po uruchomieniu przeglądarki w celu całkowitego załadownia strony
self.browser.implicitly_wait(3)
def tearDown(self):
# zamknięcie przeglądarki
self.browser.quit()
def check_for_row_in_list_table(self, row_text):
# pobranie tabeli
table = self.browser.find_element_by_id('id_list_table')
# pobranie wierszy z tabeli
rows = table.find_elements_by_tag_name('tr')
# sprawdzenie czy w którymś z wierszy znajduje się poszukiwany fragment tekstu
self.assertIn(row_text, [row.text for row in rows])
def test_can_start_a_list_and_retrieve_it_later(self):
# uruchomienie w przeglądarce adresu URL, pod którym dostępna jest testowana aplikacja
self.browser.get(self.live_server_url)
# sprawdzenie, czy w tytule strony oraz nagłówku h1 jest nazwa aplikacji 'To-Do'
self.assertIn('To-Do', self.browser.title)
header_text = self.browser.find_element_by_tag_name('h1').text
self.assertIn('To-Do', header_text)
# znalezienie na wyświetlonej stronie elementu o identyfikatorze 'id_new_item'
inputbox = self.browser.find_element_by_id('id_new_item')
self.assertEqual(
inputbox.get_attribute('placeholder'),
'Wpisz zadanie'
)
# wpisanie w polu tekstowym wartości 'sprzatanie mieszkania'
inputbox.send_keys('sprzatanie mieszkania')
# wciśniecię klawisza ENTER by zakończyć wprowadzanie nowego zadania
inputbox.send_keys(Keys.ENTER)
# sprawdzenie, czy nowy adres URL zawiera słowo 'lists'
user1_list_url = self.browser.current_url
self.assertRegex(edith_list_url, '/lists/.+')
# sprawdzenie czy w liście zadań jest dodane 'sprzatanie mieszkania'
self.check_for_row_in_list_table('1: sprzatanie mieszkania')
# dodanie kolejnego zadania 'zrob zakupy'
inputbox = self.browser.find_element_by_id('id_new_item')
inputbox.send_keys('zrob zakupy')
inputbox.send_keys(Keys.ENTER)
# sprawdzenie czy oba zadania są wyświetlane na stronie
self.check_for_row_in_list_table('2: zrob zakupy')
self.check_for_row_in_list_table('1: sprzatanie mieszkania')
# zamknięcie przeglądarki wraz z sesją użytkownika, który dodał 2 zadania
self.browser.quit()
# ponowne uruchomienie przeglądarki
self.browser = webdriver.Chrome('/Users/seba/Projects/python/drivers/chromedriver')
# ponowne uruchomienie witryny z testowaną aplikacją
self.browser.get(self.live_server_url)
# sprawdzenie czy zadania dodane przez inne użytkownika nie są wyświetlane
page_text = self.browser.find_element_by_tag_name('body').text
self.assertNotIn('zrob zakupy', page_text)
self.assertNotIn('sprzatanie mieszkania', page_text)
# dodanie pierwszego zadania przez innego użytkownika
inputbox = self.browser.find_element_by_id('id_new_item')
inputbox.send_keys('mycie samochodu')
inputbox.send_keys(Keys.ENTER)
# sprawdzenie, czy nowy adres URL zawiera słowo 'lists'
user2_list_url = self.browser.current_url
self.assertRegex(francis_list_url, '/lists/.+')
# sprawdzenie czy URL listy 1 i 2 użytkownika są różne
self.assertNotEqual(user1_list_url, user2_list_url)
# sprawdzenie czy zadanie 1 użytkownika nie są widoczne, a 2 użytkownika - są wyświetlane
page_text = self.browser.find_element_by_tag_name('body').text
self.assertNotIn('zrob zakupy', page_text)
self.assertIn('mycie samochodu', page_text)