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)