Test

Jak testujeme?

  • Ručně - proklikáním aplikace...
  • Automatizovaně - popsáním testů a následném spouštění

Automatické testování

  • Unit - testujem funkčnost na úrovni jedné abstrakce.
public Document createDocument(JournalArticle article) {

   try {
        Document document = documentService.getDocument(article);
        return document;
   }
   catch (DocumentException e) {
        LOGGER.error("Error at parsing document: " + article.getContent(), e);
        return null;
   }
   catch (IllegalArgumentException e) {
        LOGGER.error("Error at create document", e);
        return null;
   }
}

Automatické testování

  • Integrační - testujeme ucelenou funkčnost skrtz více úrovní nebo systémů.

JUnit

  • framework pro testování, používá anotace k specifikaci testů
public class NumberServiceTest {

    @Test
    public void sumTest() {
        //code
    }
}

JUnit - cv

  • napište test na:
public class NumberService {

    public double multiply(int x, Double y) {

        check(y);
        return x*y;

    }

    private void check(Object o) {

        if (o == null) {
            throw new IllegalArgumentException();
        }
    }
}

JUnit - cv

  • parametrizované testování
    @Test
    @Parameters({"1, 2, 2", "1, 2, 1"})
    public void multiplyTest(int x, double y, double result) {

        Assert.assertEquals(result, numberService.multiply(x, y), 0);
    }

JUnit - pojmenování

  • jmené konvence pro testy:
    • pro třídu používám název testované třídy + suffix test
    • pro jednotlivé testovací metody
      nazveMetody_specifickyStav_coByMelaUdelat

      "
      divide_byZero_shouldThrowException"
       

Co když...

  • co dělat když máme metodu následujícího typu:
public double divide(int x, Double y) {

   check(y);
   remoteService.sendSomeEmailMessage(arg...);

   return x/y;
}

Co když...

  • servisu "remoteService" musíme pro testovací účely vytvořit a naší testované service dodat.
  • jak?

Co když...

  • servisu "remoteService" musíme pro testovací účely vytvořit a naší testované service dodat.
  • jak?
  • podle používaného frameworku pro závislosti:
    • setter
    • konstruktor
  • jak vytvoříme servisu pro testy?

Co když...

  • servisu "remoteService" musíme pro testovací účely vytvořit a naší testované service dodat.
  • jak?
  • podle používaného frameworku pro závislosti:
    • setter
    • konstruktor
  • jak vytvoříme servisu pro testy?
    • stub
    • mock

Stub

  • Implementace servisi pro potřeby testů.
public class ServiceImpl implements Service {

    public int doSomething() {
        return 2;
    }

    public int doSomething2() {
        ...
    }
  
    ...
}

Mock

  • vytvoří "mock" potřebné služby a definuje chování u potřebných metod
  • využijeme knohovnu mockito: http://mockito.org/

Mockito

  • knihovna která umožní definovat chování jednotlivých metod.
  • definujeme:
    •  co metoda vrací na základě volání s parametry
  • kontrolujeme:
    • návratovou hodnotu
    • počet volání metody
    • hodnotu parametrů se kterými byla volána

Mockito - cv

  • otestujte následující kód
public class MainService {

    private NumberService numberService;

    public MainService(NumberService numberService) {

        this.numberService = numberService;
    }

    public double divide(double x, double y) {

        if (y == 0) throw new IllegalArgumentException();

        return numberService.divide((int) x, y);
    }
}
public class NumberService {

    public double divide(int x, Double y) {
        return x/y;
    }
}

Mockito - cv

  • musíme přidat knihovnu mockito

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.9.5</version>
</dependency>

Mockito - cv

  • vytvoříme mock naši třídy
@Before
public void init() {

    numberServiceMock = mock(NumberService.class);
    mainService = new MainService(numberServiceMock);
}

Mockito - cv

  • vytvoříme mock naši třídy
@Before
public void init() {

    numberServiceMock = mock(NumberService.class);
    mainService = new MainService(numberServiceMock);
}
  • nastavíme co cheme testovat a otestujeme
@Test
public void divide_shouldReturnSameValueAsMock() {

    double result = 0.5;
    when(numberServiceMock.divide(1, 2D)).thenReturn(result);

    double divideResult = mainService.divide(1, 2D);
    Assert.assertEquals(result, divideResult, 0);
    verify(numberServiceMock, times(1)).divide(anyInt(), anyDouble());
}

test

By Jiří Čížek

test

  • 421