blog.testowka.pl

Archiwum wiadomości z Styczeń, 2013

Skrzynka z narzędziami – dlaczego dobrzy developerzy zmieniają pracę?

opublikowany przez 29, Sty, 2013, w kategoriach Agile, Kanban, Scrum, XP

Nie istnieje jeden, sprawdzony i zawsze działający sposób na efektywne wytwarzanie oprogramowania. Jako praktycy, trenerzy, doradcy i konsultanci nie jesteśmy w stanie dać wam (sprzedać) czegoś co sprawi, że wasz proces będzie działał i przynosił oczekiwane efekty. Jedyne co możemy wam zaoferować to pomoc przy kreacji takiego procesu przez was – bo to wasz proces, a i to z pewnymi ograniczeniami. Jako zewnętrzni doradcy (nawet gdybyśmy byli u was na etacie było by tak samo, a nawet gorzej) nie możemy kazać wam czegoś zrobić, ba z pewnością nie chcieli byśmy niczego wam nakazywać i brać za to odpowiedzialności.

To co możemy dla was zrobić to przekazać wam nasze doświadczenia i opowiedzieć historie o tym jak jakieś narzędzia i techniki działały bądź nie w innych organizacjach, w innych zespołach. Może niektóre z nich zadziałają u was, może będą wymagały odpowiedniego dopasowania. To co jeszcze możemy zrobić to przekazać wam wiedzę na temat danych narzędzi i metod pracy. Będzie to pewnie w większości tak lekceważona i dyskryminowana wiedza teoretyczna. Ale czy wiedza, chociażby teoretyczna nie jest wartościowa?

Do poniższego artykułu zachęcił mnie wpis Sandro Mancuso zatytułowany „The best approach to software development”. Jak zapewne w nim przeczytacie nie ma jednego, najlepszego podejścia do wytwarzania oprogramowania. Natomiast jest wiele podejść, które sprawdziły się w określonym kontekście w wielu różnych projektach.

W takim razie wszelkiego rodzaju dogmatyzm na tym poziomie jest co najmniej niewskazany. Warto natomiast znać wiele technik/narzędzi chociażby takich jak TDD, BDD, ATDD, DDD, XP, Scrum, Kanban, Lean Startup, Gamification, i wiele innych. Warto mieć doświadczenie w używaniu tych narzędzi i dzięki temu wiedzieć, do jakich zadań wykorzystywać jakie narzędzia. Wielu dobrych programistów, których znam zmienia pracę dosyć często – raz na dwa lata. Zapytani dlaczego odpowiadają przeważnie, że pomimo tego, iż firmy w których pracują są na prawdę fajne to po pewnym czasie następuje wypalenie i nuda spowodowana pracą nad ograniczonym zbiorem produktów, według ograniczonych metod pracy i w ograniczonej liczbie technologii.

Wiele firm takich jak np. Google zauważyło ten problem i wręcz wymusza na swoich pracownikach zmianę projektu w którym pracują przynajmniej raz na dwa lata (przykład właśnie z Google). Dobrzy pracownicy są dobrzy przeważnie dlatego, że szybko się uczą i lubią się uczyć. Jest to coś co ich motywuje. Ale dobrzy pracownicy też łatwo się nudzą. Jeśli mają cały czas możliwość rozwoju i nauki to praca ich nie nudzi. Jeśli natomiast cały czas pracują w tym samym środowisku to z czasem motywacja spada choćby nie wiem jak wysokie były premie, jak fajni ludzie na około i jak fajne imprezy firmowe.

Dobrzy developerzy cały czas poszukują nowych narzędzi, doświadczeń i możliwości rozwoju i to właśnie te narzędzia i doświadczenie sprawiają, że są dobrzy.

1 komentarz więcej...

Kurs Selenium część 6 – parametryzacja testów

opublikowany przez 21, Sty, 2013, w kategoriach Kurs Selenium

Całość kursu dostępna tutaj.

W poprzedniej części kursu testowaliśmy formularz logowania. Przetestowaliśmy jedynie pozytywny scenariusz a co z negatywnymi – co z walidacją?
Pierwszy pomysł jaki się nasuwa to, że trzeba skopiować powyższy test i zmieniać w kopiach dane wejściowe. Niestety tworzymy w ten sposób wiele duplikacji, które utrudnią dalsze utrzymywanie testów – co na przykład jeśli zmieni się formularz logowania, albo w ogóle sposób logowania?

Jest lepsze – bardziej generyczne rozwiązanie.

Wystarczy naszym testom nadać parametry – użyjemy w tym celo adnotacji @DataProvider.

Najpierw potrzebujemy wprowadzić drobne zmiany w naszej metodzie logIn() tak by przyjmowała parametry:

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

	loginField.sendKeys(login);
	passwordField.sendKeys(password);
	commit.click();
}

Zalecam przeciążenie tej metody – czyli utworzenie dwóch metod logIn() oraz logIn(String login, String password) – dzięki takiemu podejściu nasz poprzedni test nadal będzie działał ale co najważniejsze metoda logIn() bez parametrów będzie mogła być użyta w wielu testach bez obaw o ewentualne zmiany. Przykładowo gdybyśmy zawsze używali w każdym teście logIn(„admin”, „password”) i nagle z jakiś powodów – np. polityki dotyczącej haseł, zmienia się hasło w naszych danych testowych, albo w ogóle nie logujemy się już przy użyciu hasła tylko np. przez facebooka. W takiej sytuacji dzięki przeciążonej metodzie logIn() możemy zmienić sposób logowania tylko w jednym miejscu i wszystko nadal będzie działać.

private void logIn() {
	logIn("admin", "password");
}

Dobrze, skoro mamy już metodę służącą do logowania i przyjmującą parametry to teraz należy przygotować nasz test tak by parametry przyjmował.

Robi się to w następujący sposób. W adnotacji @Test przekazujemy dataProvider – wskazujemy nazwę providera. Poniżej definiujemy wspomniany provider przy użyciu adnotacji @DataProvider.

W metodzie testu przekazujemy parametry shouldNotBePossibleToLogInWithIncorrectCredentials(String login, String password)

import org.testng.annotations.DataProvider;

@Test(dataProvider = "wrongLoginCredentials")
public void shouldNotBePossibleToLogInWithIncorrectCredentials(
	String login, String password) {
	// GIVEN
	openLoginPage();
	// WHEN
	logIn(login, password);
	// THEN
	checkIfLogedIn();
}

@DataProvider
public Object[][] wrongLoginCredentials() {
	return new Object[][] { { "admi", "password" }, { "admin", "passwor" },
			{ "admi", "passwor" }, { "admi", "" }, { "", "password" }, { "", "" }, };
}

Zastosowań @DataProvider może być wiele – odsyłam do dokumentacji.

11 komentarzy więcej...

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.

Dodaj komentarz więcej...