blog.testowka.pl

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 Comments for this entry

  • Sevo

    Fajne i przydatne lekcje. Czekam na więcej 😉

  • ziom

    Nic specjalnego, poziom poniżej podstawowego. Web drivery są już przestarzałe…

  • streser

    @ziom:
    „poziom poniżej podstawowego” – czyli dokładnie to o co chodziło. Cieszę się że udało mi się osiągnąć zamierzony efekt stworzenia kursy dla na prawdę początkujących.

    Z czasem będą pojawiały się kolejne części kursu – potrzebuje tylko trochę czasu żeby poskładać wszystko…

    „Web drivery są już przestarzałe…” – co proponujesz innego?

  • Maciej

    Ok,
    Wszystko fajnie, ale jeżeli będziemy mieli w obiekcie do przetestowania kilka loginów i haseł, które będą prawidłowe, to tylko pierwszy z nich zostanie uznany za właściwy, ponieważ nie przewidziano w testcie sytuacji, że jesteśmy zalogowani. Co z wiązku z tym? Należy dodać warunek, że po prawidłowym zalogowaniu należy się wylogować i ponownie przejść na stronę główną?

  • Maciej

    Kontynując poprzednie moje pytanie, czy takie rozwiązanie jest poprawne politycznie?

    private void checkIfLogedIn() {
    boolean check;
    check = driver.findElement(By.id(„admin”)).isDisplayed();
    if(check){
    LogOutWhenLogedIn();
    }
    }

    private void LogOutWhenLogedIn() {
    driver.get(„http://demo.bananascrum.com/logout”);
    }

    Kolejna sprawa, gdzie znaleść pełną dokumentację wszystkich metod i opisów możliwości Selenium??

  • streser

    Rozwiązanie problemu jest jeszcze prostsze – wystarczy zamiast @BeforeClass użyć @BeforeMethod w metodzie SetUp(). Dzięki temu przy każdym teście będzie uruchamiała się nowa przeglądarka.
    (Aby uniknąć pozostawania otwartych okienek należy również zmienić @AfterClass na @AfterMethod).

    Wcześniej w przykładach używałem @BeforeClass ze względu na czas wykonania testów. Przy testach samego logowania takie podejście jest nieskuteczne ze względu na problem opisany powyżej.

    Ale prawdę powiedziawszy: Kto testuje logowanie?
    To że możemy automatyzować testy nie znaczy, że powinniśmy testować wszystko! Jeśli chcecie dowiedzieć się więcej zapraszam na szkolenia (z automatyzacji testów albo BDD) – ciężko jest takie rzeczy opisać na blogu.

  • streser

    A gdzie znaleźć opisy metod? http://docs.seleniumhq.org/docs/ tu jest większość. Poza tym google it.

  • streser

    Tutaj jest dokumentacja do kodu źródłowego selenium – bo jak by nie było to open source jest: http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/

  • krakus

    To właściwie jak może wyglądać docelowy kod?
    Próbuję jak poniżej i nawet dobrze działa ale tylko dla poprawnych danych a nie o to chodzi. Wkleiłem zmieniony login i hasło.

    package testowka;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.By;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.testng.annotations.BeforeMethod;
    import org.testng.annotations.Test;
    import org.testng.annotations.AfterMethod;
    import org.testng.annotations.DataProvider;
    import static org.testng.Assert.*;

    public class Test06_Parameters {
    WebDriver driver;

    @BeforeMethod
    public void setUp(){
    System.setProperty(„webdriver.chrome.driver”, „X:\\!Software\\Selenium\\chromedriver_win32\\chromedriver.exe”);
    driver = new ChromeDriver();
    }

    @Test(dataProvider = „loginCredentials”)
    public void shouldBeNotPossibleToLoginWithInCorrectData(String login, String password, boolean loggedIn){
    //GIVEN
    openLoginPage();
    //WHEN
    logIn(login, password);
    //THEN
    checkIfLoggedIn(loggedIn);
    }

    @DataProvider
    public Object[][] loginCredentials(){
    return new Object[][] { {„Userkrk”, „Userkrk1”, true}, {„User”, „Userkrk1”, false}, {„Userkrk”, „User”, false}, {„User”, „User”, false}, {„User”, „”, false}, {„”, „Userkrk1”, false}, {„”, „”, false}, };
    }

    private void openLoginPage() {
    driver.get(„https://github.com/login”);
    }

    private void logIn(){
    logIn(„Userkrk”, „Userkrk1”);
    }

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

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

    private void checkIfLoggedIn(boolean loggedIn){
    assertEquals(driver.findElement(By.partialLinkText(„UserkrkA”)).isDisplayed(), loggedIn);
    }

    @AfterMethod
    public void tearDown() {
    driver.quit();
    }

    }

  • krakus

    Problem polega na tym że testy przechodzą tylko dla pierwszych poprawnych danych.

  • principais sintomas de diabetes infantil

    Em por norma geral os sintomas são tardios e estão associados ao descontrole da doença, podendo levar anos para desabrochar.

Skomentuj