blog.testowka.pl

Kurs Selenium część 5 – Ładne testy

opublikowany przez 17, Sty, 2013, w kategoriach Automatyzacja, Kurs Selenium, Testowanie

Całość kursu dostępna tutaj

Stwórzmy troszeczkę bardziej skomplikowany test. Spróbujmy się zalogować do http://demo.bananascrum.com

@Test
public void test1() {
	driver.get("http://demo.bananascrum.com/login");
	WebElement a = driver.findElement(By.id("login")); //pole z loginem
	a.sendKeys("admin"); //wpisuje login
	WebElement b = driver.findElement(By.id("password"));  //pole z haslem
	b.sendKeys("password");//wpisuje haslo
	WebElement c = driver.findElement(By.name("commit")); //klikam zatwierdz
    c.click();
	driver.findElement(By.id("admin")).isDisplayed(); //Sprawdź czy zalogowany
}

Czy coś z tym testem jest nie tak?
Przecież działa…

Przede wszystkim problemem są w nim komentarze. Jeśli nasz kod potrzebuje komentarzy to znaczy, że nie jest wystarczająco przejrzysty. I tak własnie jest w przypadku tego kodu.

Zanim zabiorę się do komentarzy wypadało by się zastanowić co chcemy przetestować – z tego testu nie wynika to wprost.

Przede wszystkim należało by zmienić nazwę.

@Test
public void shouldBePossibleToLogInWithCorrectData() {
...

Używam konwencji z „should” na początku – dzięki temu nazwa testu zawsze wskazuje na to co chcemy przetestować.
Nazwa ma dodatkowo bardzo istotne znaczenie – raczej staramy się by nasze testy były jak najbardziej atomowe i testowały zawsze jedną rzecz. Dzięki takiemu podejściu informacja jaką nam dają jest zawsze przejrzysta – dokładnie wiemy co się zepsuło i gdzie szukać błędów.

Jeśli w nazwie swojego testu wpisujesz „and” albo „or” to wiedz, że coś się dzieje…

Komentarze…

Z komentarzami główny problem jest taki, że przeważnie są nieaktualne i mylące – o ile w momencie gdy piszemy kod bywają pomocne to z czasem tylko przeszkadzają. Pamiętajmy o tym, że nasz kod żyje swoim życiem i cały czas się rozwija.

Jak się ich pozbyć? Można na przykład stosować odpowiednie nazwy metod.

Krok pierwszy – Extract Method.

@Test
public void shouldBePossibleToLogInWithCorrectCredentials() {
	openLoginPage();
	logIn();
	checkIfLogedIn();
}

private void checkIfLogedIn() {
	driver.findElement(By.id("admin")).isDisplayed();
}

private void logIn() {
	WebElement a = driver.findElement(By.id("login")); //pole z loginem
	a.sendKeys("admin"); //wpisuje login
	WebElement b = driver.findElement(By.id("password"));  //pole z haslem
	b.sendKeys("password");//wpisuje haslo
	WebElement c = driver.findElement(By.name("commit")); //klikam zatwierdz
    c.click();
}

Polecam używać skrótu klawiszowego ALT+SHIFT+M. Zaznaczamy kawałek kodu i wciskamy skrót – pozostaje podanie nazwy metody.

Wytworzone w ten sposób metody pozostawiają wiele do życzenia.

Zwłaszcza metoda logIn() nadal wymaga komentarzy…

private void logIn() {
	WebElement login = driver.findElement(By.id("login"));
	WebElement password = driver.findElement(By.id("password"));
	WebElement commit = driver.findElement(By.name("commit")); 

	login.sendKeys("admin");
	password.sendKeys("password");
	commit.click();
}

Teraz wygląda to trochę lepiej. Nie jest jeszcze perfekcyjnie ale do tego przejdziemy później.

Krok 2 – struktura testów.

@Test
public void shouldBePossibleToLogInWithCorrectCredentials() {
	openLoginPage();
	logIn();
	checkIfLogedIn();
}

Powyższy test wygląda już całkiem nieźle.

Widać w nim pewną strukturę:
– najpierw przygotowujemy sobie środowisko testowe (otwieramy testowaną stronę)
– następnie wykonujemy testowaną akcję
– i weryfikujemy czy akacja przyniosła oczekiwany efekt.

Powyższą strukturę można opisać jako Given, When, Then (konwencja znana praktykom BDD). Given – kontekst testu, When – akcja do wykonania (zawsze jedna), Then – sprawdzenie poprawności wykonywanej akcji, asercje.

@Test
public void shouldBePossibleToLogInWithCorrectCredentials() {
	// GIVEN
	openLoginPage();
	// WHEN
	logIn();
	// THEN
	checkIfLogedIn();
}

To by było na tyle jak na początek. Więcej w praniu…
Polecam książkę Clean Code – Robert C. Martin.
Czystość i przejrzystość testów to podstawa jeśli zależy nam na ich utrzymywalności i rozwijalności w przyszłości. A zależy nam na tym zawsze – inaczej nie było by sensu pisać testów.

W następnych częściach kursu będzie o tym jak parametryzować testy oraz rozpoczniemy przygodę z wzorcami projektowymi. Nasze testy nadal nie są obiektowe – a warto by było wykorzystać w pełni możliwości języków obiektowych takich jak Java.


Skomentuj