showdown of the asserts by philipp krenn

71
Java Day Charkiv Showdown of the Asserts Philipp Krenn @xeraa

Upload: javadayua

Post on 16-Apr-2017

168 views

Category:

Technology


0 download

TRANSCRIPT

Java Day Charkiv

Showdown of the

AssertsPhilipp Krenn��@xeraa

Vienna

Vienna

Vienna

Electronic Data Interchange (EDI)

ViennaDBPapers We Love Vienna

AssertDictionary state a fact or belief confidently and forcefully

This is

notan assertive talk

Who uses

JUnit

Who uses

TestNG

Who uses

Hamcrest

Who uses

AssertJ

Who uses

Spock

Who uses

something else

Once upon a time we were using

JUnit

Then we switched to

TestNG

Then we switched back to

JUnit+ tempus-fugit

tempusfugitlibrary.orgJava micro-library for writing & testing concurrent code

@RunWith(ConcurrentTestRunner.class)public class ConcurrentTestRunnerTest {

@Test public void shouldRunInParallel1() { System.out.println("I'm running on thread " + Thread.currentThread().getName()); }

@Test public void shouldRunInParallel2() { System.out.println("I'm running on thread " + Thread.currentThread().getName()); }

@Test public void shouldRunInParallel3() { System.out.println("I'm running on thread " + Thread.currentThread().getName()); }}

I'm running on thread ConcurrentTestRunner-Thread-0I'm running on thread ConcurrentTestRunner-Thread-2I'm running on thread ConcurrentTestRunner-Thread-1

!try { Thread.sleep(100);} catch (InterruptedException e) { // nothing}

sleep(millis(100));

So unit tests looked like this...assertNotEquals(unexpected, actual);

...but one day I foundassertThat(actual, is(not(equalTo(unexpected))));

“Declare the dependency for your favourite test framework you want to use in your tests.”$ gradle init

JunitTestNGHamcrestAssertJTruthSpock

JUnitTesting framework

TestNGJUnit compatible testing framework

HamcrestReplaces JUnit / TestNG asserts

AssertJReplaces JUnit / TestNG assertsFork of fest

TruthReplaces JUnit / TestNG asserts

SpockTesting framework written in GroovyJUnit runner

Mocking / Stubbing

Original codeassertNotEquals(unexpected, actual);

assertThat(actual, is(not(equalTo(unexpected))));

» Different order

» Longer

» Additional dependency

Minimal examplepublic class Adder {

public int add(int a, int b){ return a+b; }

}

JUnitimport org.junit.Test;import static junit.framework.Assert.assertEquals;

public class Junit {

@Test public void testAdd(){ Adder adder = new Adder(); assertEquals(3, adder.add(1, 2)); }}

TestNGimport org.testng.annotations.Test;import static org.testng.Assert.assertEquals;

public class Testng {

@Test public void testAdd(){ Adder adder = new Adder(); assertEquals(adder.add(1, 2), 3); }}

Hamcrestimport org.junit.Test;import static org.hamcrest.MatcherAssert.assertThat;import static org.hamcrest.Matchers.equalTo;

public class Hamcrest {

@Test public void testAdd(){ Adder adder = new Adder(); assertThat(adder.add(1, 2), equalTo(3)); }}

AssertJ

import org.junit.Test;import static org.assertj.core.api.Assertions.assertThat;

public class Assertj {

@Test public void testAdd(){ Adder adder = new Adder(); assertThat(adder.add(1, 2)).isEqualTo(3); }}

Truthimport org.junit.Test;import static com.google.common.truth.Truth.assertThat;

public class Truth {

@Test public void testAdd(){ Adder adder = new Adder(); assertThat(adder.add(1, 2)).isEqualTo(3); }}

Spockclass Spock extends spock.lang.Specification {

def "Add two numbers"() { def adder = new Adder()

expect: adder.add(1, 2) == 3 }}

Differences

JUnitfail(message)assertTrue([message,] boolean condition)assertFalse([message,] boolean condition)assertEquals([message,] expected, actual)assertEquals([message,] expected, actual, tolerance)assertNull([message,] object)assertNotNull([message,] object)assertSame([message,] expected, actual)assertNotSame([message,] expected, actual)

JUnit Readability?Double myPi = 3.14;

assertEquals( "My own pi is close to the real pi", Math.PI, myPi, 0.1)

TestNG order of argumentsimport static org.testng.AssertJUnit.*;

import static org.testng.Assert.*;

Hamcrest

HamcrestDouble myPi = 3.1;assertThat(myPi, closeTo(Math.PI, 0.1));

HamcrestassertThat(new CartoonCharacterEmailLookupService().getResults("looney"), allOf( not(empty()), containsInAnyOrder( allOf( instanceOf(Map.class), hasEntry("id", "56"), hasEntry("email", "[email protected]")), allOf( instanceOf(Map.class), hasEntry("id", "76"), hasEntry("email", "[email protected]")) )));

Hamcrest sugarassertThat(foo, equalTo(bar));assertThat(foo, is(equalTo(bar)));assertThat(foo, is(bar));

Hamcrest custom matcherimport org.hamcrest.Description;import org.hamcrest.Factory;import org.hamcrest.Matcher;import org.hamcrest.TypeSafeMatcher;

public class IsNotANumber extends TypeSafeMatcher<Double> {

@Override public boolean matchesSafely(Double number) { return number.isNaN(); }

public void describeTo(Description description) { description.appendText("not a number"); }

@Factory public static <T> Matcher<Double> notANumber() { return new IsNotANumber(); }

}

Hamcrest custom matcherassertThat(1.0, is(notANumber()));

java.lang.AssertionError:Expected: is not a number got : <1.0>

AssertJassertThat(new CartoonCharacterEmailLookupService().getResults("looney")) .isNotEmpty() .extracting("id", "email").contains( tuple("76", "[email protected]"), tuple("56", "[email protected]"));

AssertJDouble myPi = 3.1;assertThat(myPi).isCloseTo(Math.PI, Percentage.withPercentage(3));

TruthassertThat(new CartoonCharacterEmailLookupService().getResults("looney")) .containsEntry("id", "76");

TruthTruth.ASSERTTruth.ASSUMEExpect.create()

TruthDouble myPi = 3.1;assertThat(myPi).isWithin(0.1).of(Math.PI);

Spockwhen:stack.push(elem)

then:!stack.emptystack.size() == 1stack.peek() == elem

Spockdef "length of Spock's and his friends' names"() { expect: name.size() == length

where: name | length "Spock" | 5 "Kirk" | 4 "Scotty" | 6}

Spock with Hamcrest matcherdef "comparing two decimal numbers"() { def myPi = 3.14

expect: myPi closeTo(Math.PI, 0.1)}

Conclusion

It's a messOrder of arguments

It's a messTraditional vs fluent interfaces

It's a messDifferent styles

Stick to onetechnology (combination)style

“Want to get much better at writing unit tests? For the next week, try writing every single assertion using equal()”https://medium.com/javascript-scene/what-every-unit-test-needs-f6cd34d9836d

PS: There is no maybe in tests

Thanks

Questions?@xeraa

Image Credit» Schnitzel https://flic.kr/p/9m27wm

» Architecture https://flic.kr/p/6dwCAe

» Conchita https://flic.kr/p/nBqSHT

» Paper: http://www.freeimages.com/photo/432276