+ All Categories
Home > Documents > Spring Testing

Spring Testing

Date post: 25-May-2015
Category:
Upload: roman-pichlik
View: 604 times
Download: 0 times
Share this document with a friend
Description:
* Proč testujeme* Rozdíl mezi automatickými a ručními testy* Použití mocku a stubu* Integrace Spring framerku a JUnit
35
Spring framework Motto: Musíte rozbít vejce když chcete udělat omeletu Spring framework training materials by Roman Pichlík is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License . 1 Sunday 13 May 2012
Transcript
Page 1: Spring Testing

Spring frameworkMotto: Musíte rozbít vejce když chcete udělat omeletu

Spring framework training materials by Roman Pichlík is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

1Sunday 13 May 2012

Page 2: Spring Testing

Spring frameworkMotto: Musíte rozbít vejce když chcete udělat omeletu

2Sunday 13 May 2012

Page 3: Spring Testing

3Sunday 13 May 2012

Page 4: Spring Testing

Spring TDDTestování aplikací postavených na Spring frameworku

4Sunday 13 May 2012

Page 5: Spring Testing

Proč testujeme

5Sunday 13 May 2012

Page 6: Spring Testing

Primární Motivace

• Pocit sucha a bezpečí

• Verifikace kódu, že opravdu funguje

• Zpětná vazba při změnách

6Sunday 13 May 2012

klidné spaní

Page 7: Spring Testing

Jak testujeme

7Sunday 13 May 2012

Page 8: Spring Testing

Manuální testy

• Historicky běžná součást vývojového procesu

• Testovací fáze

• Vývojáři nebo QA oddělení

8Sunday 13 May 2012

Page 9: Spring Testing

Hlavní rysy

• Pomalé

• Drahé

• Neefektivní

• Náchylné k chybě lidského faktoru

9Sunday 13 May 2012

Pomalé - trvání testovacího kolečka, specifikace, vlastní průchod testuDrahé - lidský čas je oproti strojovému stále dražší (i v Bengalore)Neefektivní - otestování low level změny je kolikrát nemožnéLidský faktor - člověk je tvor líny, monotóní práce je ubijející (ne pro stroj)

Page 10: Spring Testing

Dopady manuálního testování

• Delší release cyklus

• Chyby se odhalí na konci vývojového cyklu

• Problém chyba v RC

• Neškáluje

10Sunday 13 May 2012

RC= Go nebo no Go nebo Hotfix díky tomu, že nám hoří termínNeškáluje = nový tester neznamená větší otestovanost (roste i code base)

Page 11: Spring Testing

Automatické testy• Píší se společně s kódem

• Kontinuální evoluce

• Různé testy podle úrovně abstrakce a cílové oblasti

• Jednotkové

• Integrační

• Výkonové11Sunday 13 May 2012

Page 12: Spring Testing

Dopady aut. testů

• Rychlejší release cyklus

• Test coverage

• Známe slabá místa

• Umožňují lépe pochopit fungování kódu

• Ukazují špatný/dobrý design

12Sunday 13 May 2012

Rychlejší release cyklus díky testům závisí na tom jak drahé je pro nás testy psát a udržovat

Page 13: Spring Testing

Manuální vs Automatické testy

13Sunday 13 May 2012

Page 14: Spring Testing

Kolik stojí opravení chybyN

ákla

dy n

a od

stra

nění

chy

by

čas nalezení chyby

14Sunday 13 May 2012

Náklady na odstranění rostou exponenciálně s čase objevení chyby

Page 15: Spring Testing

Kolik stojí opravení chybyN

ákla

dy n

a od

stra

nění

chy

by

čas nalezení chyby

automatické testy manuální testy15Sunday 13 May 2012

Náklady na odstranění rostou exponenciálně s čase objevení chybyAutomatické testy snižují čas na odhalení chyby

Page 16: Spring Testing

Doporučení

• Zaměřte se na automatické testy

• Testy lze zavádět inkrementálně

• Nový kód vždy

• Starý kód pokud se do něj šahá

• Starý kód podle důležitosti

• Testy jsou zrcadlem návrhu16Sunday 13 May 2012

Page 17: Spring Testing

Automatické testy

17Sunday 13 May 2012

Page 18: Spring Testing

Jednotkové vs. Integrační

• Jednotkové testy

• Konkrétní třída v izolaci

• Žádné závislosti

• Odstíněné od prostředí

• Integrační testy

• Interakce několika komponent

18Sunday 13 May 2012

Page 19: Spring Testing

Jednotkové testy

• Nejdůležitější je izolace

• Pokud možno všechny ostatní třídy odizolované

• Použití Stub a Mock objektů

• Nemíchat testovací scénáře

• Jedna testovací metoda per scénář

19Sunday 13 May 2012

JDK se považuje za důveryhodné => nemusíme dělat stuby

Page 20: Spring Testing

Unit test

public class ReservationServiceImpl implements ReservationService{

private BookStoreDao bookStoreDao; private AtomicLong counter = new AtomicLong(); private Map<Long, Reservation> resevations = new HashMap<Long, Reservation>();

public Reservation reserveBook(Long bookId) { Book book = bookStoreDao.getBook(bookId); if(book == null) { throw new BookNotFoundException(bookId); } ReservationImpl reservationImpl = new ReservationImpl(); reservationImpl.setReservationId(counter.incrementAndGet()); reservationImpl.setBookId(bookId); return reservationImpl; }}

20Sunday 13 May 2012

Page 21: Spring Testing

Unit test

public class ReservationServiceImpl implements ReservationService{

private BookStoreDao bookStoreDao; private AtomicLong counter = new AtomicLong(); private Map<Long, Reservation> resevations = new HashMap<Long, Reservation>();

public Reservation reserveBook(Long bookId) { Book book = bookStoreDao.getBook(bookId); if(book == null) { throw new BookNotFoundException(bookId); } ReservationImpl reservationImpl = new ReservationImpl(); reservationImpl.setReservationId(counter.incrementAndGet()); reservationImpl.setBookId(bookId); return reservationImpl; }}

Externí třída (v testu nahradit stub/mock)

20Sunday 13 May 2012

Page 22: Spring Testing

Unit test

public class ReservationServiceImpl implements ReservationService{

private BookStoreDao bookStoreDao; private AtomicLong counter = new AtomicLong(); private Map<Long, Reservation> resevations = new HashMap<Long, Reservation>();

public Reservation reserveBook(Long bookId) { Book book = bookStoreDao.getBook(bookId); if(book == null) { throw new BookNotFoundException(bookId); } ReservationImpl reservationImpl = new ReservationImpl(); reservationImpl.setReservationId(counter.incrementAndGet()); reservationImpl.setBookId(bookId); return reservationImpl; }}

Externí třída (v testu nahradit stub/mock)

dvě testovací metody (scénáře)20Sunday 13 May 2012

Page 23: Spring Testing

Unit test

public class ReservationServiceImpl implements ReservationService{

private BookStoreDao bookStoreDao; private AtomicLong counter = new AtomicLong(); private Map<Long, Reservation> resevations = new HashMap<Long, Reservation>();

public Reservation reserveBook(Long bookId) { Book book = bookStoreDao.getBook(bookId); if(book == null) { throw new BookNotFoundException(bookId); } ReservationImpl reservationImpl = new ReservationImpl(); reservationImpl.setReservationId(counter.incrementAndGet()); reservationImpl.setBookId(bookId); return reservationImpl; }}

Externí třída (v testu nahradit stub/mock)

dvě testovací metody (scénáře)20Sunday 13 May 2012

Page 24: Spring Testing

Unit test

public class ReservationServiceImpl implements ReservationService{

private BookStoreDao bookStoreDao; private AtomicLong counter = new AtomicLong(); private Map<Long, Reservation> resevations = new HashMap<Long, Reservation>();

public Reservation reserveBook(Long bookId) { Book book = bookStoreDao.getBook(bookId); if(book == null) { throw new BookNotFoundException(bookId); } ReservationImpl reservationImpl = new ReservationImpl(); reservationImpl.setReservationId(counter.incrementAndGet()); reservationImpl.setBookId(bookId); return reservationImpl; }}

Externí třída (v testu nahradit stub/mock)

dvě testovací metody (scénáře)20Sunday 13 May 2012

Page 25: Spring Testing

Stubpublic class BookStoreDaoStub implements BookStoreDao{

private Book book;

public Book getBook(Long bookId) { if(book != null && bookId.equals(book.getId())) { return book; } return null; }

public void saveBook(Book book) { this.book = book; }

public Book getBook() { return book; }

public void setBook(Book book) { this.book = book; }}

Implementuje stejné rozhraní

jednoduché chování připravené pro test

Možnost verifikovat stav stubu

21Sunday 13 May 2012

Page 26: Spring Testing

Použití stubupublic class ReservationServiceImplTest {

private BookStoreDao bookStoreDao; private ReservationServiceImpl reservationServiceImpl = new ReservationServiceImpl(); @Before public void setup(){ bookStoreDao = new BookStoreDaoStub(); reservationServiceImpl.setBookStoreDao(bookStoreDao); }

@Test public void testReserveNonExistingBook() { try { reservationServiceImpl.reserveBook(-1l); fail("BookNotFoundException musi byt vyhozena pro neexistujici knihu"); } catch(BookNotFoundException e) { //expected } }

}

Příprava stubu

22Sunday 13 May 2012

Page 27: Spring Testing

Použití stubu

• Výhody

• Znovupoužitelný kód

• Test support modul

• Nevýhody

• Změna interface znamená změnu stubu

• Implementace všech metod23Sunday 13 May 2012

žádné smart defaults

Page 28: Spring Testing

Použití mocku

• Mock je automatický generovaná třía

• Popisujeme chování, které nás zajímá

• Můžeme zkontrolovat interakci

24Sunday 13 May 2012

Page 29: Spring Testing

Mockovací knihovná Mockito

• Velmi pohodlné mockování

• Fluent API

• Jednoduchá na použití

• Umožňuje verifikovat stav mocku po testu

25Sunday 13 May 2012

jsou i další mock knihovny

Page 30: Spring Testing

Mock s Mockitem

import static org.mockito.Mockito.mock;import static org.mockito.Mockito.when;

public class ReservationServiceImplTest { private BookStoreDao bookStoreDao; private ReservationServiceImpl reservationServiceImpl = new ReservationServiceImpl(); @Before public void setup(){ bookStoreDao = mock(BookStoreDao.class); when(bookStoreDao.getBook(-1l)).thenReturn(null); reservationServiceImpl.setBookStoreDao(bookStoreDao); } @Test public void testReserveNonExistingBook() { try { reservationServiceImpl.reserveBook(-1l); fail("BookNotFoundException musi byt vyhozena pro neexistujici knihu"); } catch(BookNotFoundException e) { //expected } }

Příprava mocku

26Sunday 13 May 2012

Page 31: Spring Testing

Mock vs. Stub

• Mock

• Smart defaults

• Pokud se jedná o složitější rozhraní

• Stub

• Znovupoužitelné

27Sunday 13 May 2012

Page 32: Spring Testing

Integrační testy se Springem

28Sunday 13 May 2012

Page 33: Spring Testing

Spring test• spring-test modul

• Umožňuje nainicializovat Spring

• Umožňuje nainjectovat testované beany do testu

• Centrální třídy

• SpringJUnit4ClassRunner

• @ContextConfiguration29Sunday 13 May 2012

Page 34: Spring Testing

import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:META-INF/applicationContext.xml")public class ReservationServiceImplTest {

@Autowired private ReservationService reservationService;

@Test public void testReserveNonExistingBook() { try { reservationService.reserveBook(-1l); fail("BookNotFoundException musi byt vyhozena pro neexistujici knihu"); } catch(BookNotFoundException e) { //expected } }}

Integrace Spring a JUnit

Konfigurace Springu

Nainjectování testované beany

30Sunday 13 May 2012

Page 35: Spring Testing

• Napište jednotkový test pro ReservationServiceImp

• použijte mock pro BookStoreDao

• Napište integrační test pro ReservationServiceImp za pomocí Springu

• Jako BookStoreDao nedefinujte beanu, která bude naimplementovaná jako stub

31Sunday 13 May 2012


Recommended