fest assert
TRANSCRIPT
Plan prezentacji● Od czego się zaczęło ?● Co to jest FEST ?● Podstawowe asercje● Ciekawsze asercje● Własne warunki● Guava● Joda Time● Podsumowanie
Od czego się zaczęło ?
private static final int expected = 5;
@org.junit.Test public void twoPlusTwoTestA(){ int actual = 2 + 2; org.junit.Assert.assertEquals(expected,actual); } @org.testng.annotations.Test public void twoPlusTwoTestB(){ int actual = 2 + 2; org.testng.Assert.assertEquals(actual,expected); }
FEST AssertDefinicja
"FEST-Assert jest to biblioteka typu
"assertThat", która zapewnia płynny
interfejs do pisania asercji. Głównym celem
jest poprawa czytelności kodu testowego
oraz ułatwienie utrzymania testów."
FESTAssert HomePageTłumaczenie własne
FEST AssertGłówne argumenty
● Tylko jedna klasa do zaimportowania - assertThat
● Połączenie wielu różnych asercji w jednej znaczącej linii
● Podpowiadanie asercji przez CTRL(CMD) + SPACE
● Działa z TestNG oraz jUnit
FEST AssertDwie wersje biblioteki
Wersja 1.x
● 2007-2012
● Prace deweloperskie zatrzymane
● Ostatnia wersja to 1.4
Wersja 2.x
● marzec 2012-teraz
● Obecna wersja 2.0M11
Przypadki podstawoweCo będziemy testować ?
public interface IBookService { DateTime getSaleEndDate();
DateTime getSaleStartDate();
String findBook(int bookID);
String getLibraryName();
Integer getLibrarySize();
List<Book> getITBooks();
List<Book> getAllBooks();}
StringAssert@Testpublic void veryFirstAssert() { String text = sut.getLibraryName(); assertThat(text) .isNotNull() .isNotEmpty() .isEqualTo("Hello World");}
@Testpublic void veryFirstAssertWithIgnoreCase() { String text = sut.getLibraryName(); assertThat(text) .isNotNull() .isNotEmpty() .isEqualToIgnoringCase("heLLo woRLd");}
IntAssert@Testpublic void testForEdgeValuesBetterWay() { Integer value = sut.getLibrarySize(); assertThat(value) .isNotNull() .isEqualTo(4) .isNotIn(3, 5);}
@Testpublic void testSomeSophisticatedMath() { Integer value = sut.getLibrarySize(); assertThat(value) .isNotNull() .isGreaterThan(2) .isLessThanOrEqualTo(4) .isPositive();}
ListAssert@Testpublic void testContains() { List<Book> books = sut.getITBooks(); assertThat(books) .isNotEmpty() .contains(new Book("Just Spring", "Madhusudhan Konda"));}
@Testpublic void testContainsExactly() { List<Book> books = sut.getITBooks(); assertThat(books) .isNotEmpty() .containsExactly( new Book("Just Spring", "Madhusudhan Konda"), new Book("Clean Code", "Robert C. Martin"));}
ListAssert
@Testpublic void testSizes() { List<Book> books = sut.getITBooks(); assertThat(books) .isNotEmpty() .hasSize(2) .contains(new Book("Just Spring", "Madhusudhan Konda")); .doesNotContain(
new Book("Do It Yourself - Coffins", "D. Power"));}
FEST wersja 1.x - excludesFEST wersja 2.x - doesNotContain
CustomAssert
@Testpublic void testWithUltimateCondition() { Integer value = sut.getLibrarySize(); assertThat(value) .isNotNull() .is(acceptableForBuildingSize());}
FEST wersja 1.x - satisfiesFEST wersja 2.x - is
CustomAssert
class MyUltimateCondition extends Condition<Integer>{ @Override public boolean matches(Integer value) { if((value * 2) < 12){ return true; } return false; }}
public MyUltimateCondition acceptableForBuildingSize() { return new MyUltimateCondition();}
ThrowableAssert
@Testpublic void festAssertStyle() { try { sut.findBook(-1); failBecauseExceptionWasNotThrown(
IllegalArgumentException.class); } catch (Exception e) { assertThat(e) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Book ID should be positive") .hasNoCause(); }}
ThrowableAssert
@Testpublic void catchExceptionStyle() { catchException(sut).findBook(-1); assertThat(caughtException()) .isNotNull() .isInstanceOf(IllegalArgumentException.class) .hasMessage("Book ID should be positive") .hasNoCause();}
<groupId>com.googlecode.catch-exception</groupId><artifactId>catch-exception</artifactId>
Zwracane typy przez assertThat(...)w wersji 1.x
● ArrayAssert● BigDecimalAssert● BooleanArrayAssert● ByteArrayAssert● ByteAssert● CharArrayAssert● CharAssert● CollectionAssert● ComparableAssert● DoubleArrayAssert● DoubleAssert● FileAssert● FloatArrayAssert● FloatAssert
● ImageAssert● IntArrayAsert● ItemGroupAssert● IteratorAssert● ListAssert● LongArrayAssert● LongAssert● MapAssert● NumberAssert● ObjectArrayAssert● ObjectAssert● ObjectGroupAssert● ShortArrayAssert
FEST 2.x
Co nowego:● Zmieniony import● Poprawa czytelności nazw asercji● Brak kompatybilności z wersją 1.x. ● Prosta migracja z 1.x do 2.x ● Lepsze wsparcie dla kolekcji● "plugin" dla JodaTime● "plugin" dla Guava
ListAssert@Testpublic void testContainsAtIndex() { List<Book> books = sut.getITBooks(); assertThat(books) .isNotEmpty() .contains( new Book("Just Spring","Madhusudhan Konda"),atIndex(0)); }
@Testpublic void testIsSubset() { List<Book> books = sut.getITBooks(); List<Book> allBooks = sut.getAllBooks(); assertThat(books) .isNotEmpty() .isSubsetOf(allBooks);}
Komunikaty asercji
assertThat(books).doesNotContain(new Book("Clean Code", "Robert C. Martin"));
java.lang.AssertionError: expecting<[Book{author='Just Spring', title='Madhusudhan Konda'}, Book{author='Clean Code', title='Robert C. Martin'}]> not to contain<[Book{author='Clean Code', title='Robert C. Martin'}]> but found<[Book{author='Clean Code', title='Robert C. Martin'}]>
Spodziewano się, że kolekcja books nie będzie zawierała podanej książki, ale ją znaleziono.
JodaTime
@Testpublic void testBeforeAfterOnDateTime() { DateTime salesStart = sut.getSaleStartDate(); DateTime salesEnd = sut.getSaleEndDate();
assertThat(salesEnd).isAfter(salesStart); assertThat(salesStart).isBefore(salesEnd);}
@Testpublic void testBeforeAfterOnDateTimeAndString() { DateTime salesStart = sut.getSaleStartDate(); assertThat(salesStart).isBefore("2013-04-09");}
JodaTime
@Testpublic void testEqualsAndIgnoring(){ DateTime wakeUpTime = new DateTime(2013,4,9,7,10,0,0,UTC); DateTime checkEmailTime = new DateTime(2013,4,9,7,10,18,9,UTC); assertThat(wakeUpTime) .isEqualToIgnoringSeconds(checkEmailTime);}
Guava
public static Multimap<String,String> getBikes(){ Multimap<String, String> multiMap = ArrayListMultimap.create();
multiMap.put("Kawasaki", "Z1000"); multiMap.put("Kawasaki", "Zephyr");
multiMap.put("Suzuki", "GT750"); multiMap.put("Suzuki", "T500");
return multiMap;}
Multimap<String,String> to Map<String,List<String>>
GuavaFEST 1.x
@Testpublic void oldStyle(){ Multimap<String, String> multiMap = MultiMapBikes.getBikes(); assertThat(multiMap.get("Kawasaki").size()).isEqualTo(2); assertThat(multiMap.get("Suzuki")).contains("GT750", "T500");}
GuavaFEST 2.x
@Testpublic void newStyle(){ Multimap<String, String> multiMap = MultiMapBikes.getBikes(); assertThat(multiMap) .containsKeys("Kawasaki", "Suzuki") .containsValues("GT750","Zephyr") .contains(entry("Kawasaki","Zephyr"));}
Czy warto używać ?
Na tak:● Naturany język asercji● Czytelność● Proste utrzymanie● Dobre komunikaty o niespełnionej asercji
Na nie:● Linia z asercją może rosnąć
Żródła
Fest Assert:https://github.com/alexruiz/fest-assert-2.x/https://github.com/alexruiz/fest-assert-1.x/
Prezentowane przykłady dostępne:https://bitbucket.org/mlevvy/festassertexamples