Transcript
Page 1: Test driven development - JUnit basics and best practices

TEST DRIVEN DEVELOPMENTUnit testing basics and best practices

Let’s get test infected!

Page 2: Test driven development - JUnit basics and best practices

@npathai on github

Narendra Pathai5 years of core development experience

4 years with unit testing2 years with TDD

Collaborator of Java Design Patterns repositoryContributor to JUnit 4 and Java Hamcrest

Page 3: Test driven development - JUnit basics and best practices

@harshSE on github

Harsh Patel5 years of core development experience

3 years with unit testing1 years with TDD

Contributor to JMeter, Java Design Patterns

Page 4: Test driven development - JUnit basics and best practices

“TESTING CAN BE USED TO SHOW presence of bugs,

NOT absence”- Edsger Dijkstra

Page 5: Test driven development - JUnit basics and best practices

myths & misconceptions

Page 6: Test driven development - JUnit basics and best practices

Let’s write unit test cases because then there will be

no bugsYayyy!!

Myth 1

Page 7: Test driven development - JUnit basics and best practices

less bugsIf unit testing is done properly then there will be

Reality 1

Page 8: Test driven development - JUnit basics and best practices

wastes timeI would rather write something that is useful because it

Myth 2

Page 9: Test driven development - JUnit basics and best practices

saves timeI must write tests today so that it

tomorrow

Reality 2

Page 10: Test driven development - JUnit basics and best practices

finding bugsUnit testing is just about

Myth 3

Page 11: Test driven development - JUnit basics and best practices

Multi-faceted unit testsdrive code design

executable specification

Reality 3

Page 12: Test driven development - JUnit basics and best practices

100% coverageI can be confident that code works only if there is

Myth 4

Page 13: Test driven development - JUnit basics and best practices

n% coverageIt’s perfectly fine to have

if it gives the required confidence in the code

Reality 4

Page 14: Test driven development - JUnit basics and best practices

production codeDevelopers only write

Myth 5

QA team does the testing

Page 15: Test driven development - JUnit basics and best practices

unit testsIt’s developers who must write

Reality 5

Page 16: Test driven development - JUnit basics and best practices

What is

UNIT TESTING?

Page 17: Test driven development - JUnit basics and best practices

tool { It’s a

DESIGN

CONFIDENCE

REGRESSION

Page 18: Test driven development - JUnit basics and best practices

TESTS ARE FIRST CLIENTS

OF CODE

Page 19: Test driven development - JUnit basics and best practices

TESTS ARE FIRST CLIENTS

OF CODE

I repeat

Page 20: Test driven development - JUnit basics and best practices

TESTPYRAMID

Page 21: Test driven development - JUnit basics and best practices

UNIT TESTS

INTEGRATION TESTS

END 2 END TESTS

MANUAL TESTS

CONF

IDENC

E IN

ENTIR

E SYS

TEM

CONF

IDENC

E IN

INDIV

IDUAL

CHAN

GE

EXEC

UTIO

N TIM

E

RELIA

BILITY

High

Low

Low

High

COST

Page 22: Test driven development - JUnit basics and best practices

ICE CREAM CONE

Inverse of Test Pyramid

More manual than unit tests

Too costly to test

what we don’t want

Difficult to do in depth testing

Often how testing is done

Page 23: Test driven development - JUnit basics and best practices

UNIT TESTS

INTEGRATION TESTS

END 2 END TESTS

MANUAL TESTS

Page 24: Test driven development - JUnit basics and best practices

WHO WILL WRITE WHICH TESTS?

Not important right now, a topic for some other day!

Page 25: Test driven development - JUnit basics and best practices

NAMINGCONVENTIONYou should call a spade a spade

Page 26: Test driven development - JUnit basics and best practices

HOW TO NAME TEST METHODS

UnitOfWork_StateUnderTest_ExpectedBehavior

behavior under test

define current state of object Resultant state / event

Page 27: Test driven development - JUnit basics and best practices

HOW TO NAME TEST METHODS

poppingAStack_whenEmpty_throwsException

popping from stack

when stack is emptybecause empty stack cannot be

popped

Page 28: Test driven development - JUnit basics and best practices

TEST METHODS ON STEROIDS

poppingAnEmptyStackThrowsException

popping from stack

when stack is emptybecause empty stack cannot be

popped

Page 29: Test driven development - JUnit basics and best practices

BUILD THE RIGHT THING

poppingAnEmptyStackThrowsException {Object obj = stack.pop();

}

are we building the right thing?

are we building it right?

Page 30: Test driven development - JUnit basics and best practices

Writing the first

TEST

Page 31: Test driven development - JUnit basics and best practices

xUnit frameworksare language specific

Java

jUnit

.NET

nUnit

C++

CppTest

Javascript

qUnit*multiple frameworks per language are available

Page 32: Test driven development - JUnit basics and best practices

@Test is the way to define a new test case

Page 33: Test driven development - JUnit basics and best practices

@Before setup environment to run each test

static Don’t even think about it.

Page 34: Test driven development - JUnit basics and best practices

@After cleanup resources after each test case

Page 35: Test driven development - JUnit basics and best practices

@BeforeClass setup expensive resources shared across all tests

Think static

Page 36: Test driven development - JUnit basics and best practices

@AfterClass cleanup expensive resources shared across all tests

Page 37: Test driven development - JUnit basics and best practices

assertionA statement that is expected to be true at that point in code

Page 38: Test driven development - JUnit basics and best practices

assertionPassing

test passes

|assertionFailing

test fails

Page 39: Test driven development - JUnit basics and best practices

assert keywordassert 2 + 1 == 3;

Limited powerLower expressiveness

Page 40: Test driven development - JUnit basics and best practices

jUnit assertion More power

* Better expressiveness

assertXXX(...) methods

Page 41: Test driven development - JUnit basics and best practices

assertTrue(“woah!”, 2 + 1 == 3);

assertion à la jUnit

assertEquals(3, 2 + 1);

assertArrayEquals([], []);

Page 42: Test driven development - JUnit basics and best practices

AARRANGE

AACT

AASSERT

(given) (when) (then)

Page 43: Test driven development - JUnit basics and best practices

Defining a UNITthere is no correct way

Page 44: Test driven development - JUnit basics and best practices

UNIT is SUBJECTIVEa single class

a group of related classes

Page 45: Test driven development - JUnit basics and best practices

When defining a UNITDON’T CONSIDER INTERNAL

STRUCTURE OF CLASS AS A UNIT

IT TAKES EXPERIENCE

TRIAL & ERROR

Page 46: Test driven development - JUnit basics and best practices

now introducing

Hamcrest Matchersassertion on STEROIDS

Page 47: Test driven development - JUnit basics and best practices

assertThat(2 + 1, equalsTo(3));

expressive assertions

assertThat(list, hasSize(3));

assertThat(list, contains(“a”));

Page 48: Test driven development - JUnit basics and best practices

assertThat(person, hasAge(30));

custom assertions

assertThat(2, isEven());

assertThat(21, isDivisbleBy(3));

Page 49: Test driven development - JUnit basics and best practices

unexpectedEXCEPTIONSnot all exceptions are unexpected

Page 50: Test driven development - JUnit basics and best practices

@TestpoppingAnEmptyStackThrowsException() {

try {... fail();} catch (SomeException e) {assertThat(e.getMessage(), ..);

}}

Using try...catch

Error prone, we can do much better

Page 51: Test driven development - JUnit basics and best practices

@Test(expected = EmptyStackException.class)poppingAnEmptyStackThrowsException()

Using @Test

but cannot test exception message!

Page 52: Test driven development - JUnit basics and best practices

follow | RULESJUNIT

ADDITION OR REDEFINITION OF TEST METHOD BEHAVIOR

Page 53: Test driven development - JUnit basics and best practices

ExpectedException rule@Rule public ExpectedException thrown =

ExpectedException.none();

declares a rule reference rules must be public

Page 54: Test driven development - JUnit basics and best practices

poppingAnEmptyStackThrowsException() {thrown.expect(StackEmptyException.class);thrown.expectMessage(“stack is empty”);

emptyStack.pop();}

ExpectedException rule

Page 55: Test driven development - JUnit basics and best practices

@Rule public TemporaryFolder folder = new TemporaryFolder();

folder.newFile(“myFile.txt”);folder.newFolder(“subFolder”);

TemporaryFolder ruleAutomatically deletes temp files and directories

Page 56: Test driven development - JUnit basics and best practices

ExternalResource

Timeout

Custom

More rules!No more leaked resources

Fail tests after timeout

Define custom rules

Page 57: Test driven development - JUnit basics and best practices

Run with (Runners)

way to customize test processing & extend its purpose.

Page 58: Test driven development - JUnit basics and best practices

@RunWith A class level annotation that selects the runner to use for test case@RunWith(Suite.class)

class of the runner to use

Page 59: Test driven development - JUnit basics and best practices

Hierarchical runnerorganize scenarios of the unit with nested classes/contexts

Page 60: Test driven development - JUnit basics and best practices

Suite runnerorganize several feature tests of a unit together

Page 61: Test driven development - JUnit basics and best practices

data >> teststest a system using data inputs

Page 62: Test driven development - JUnit basics and best practices

JUnitParams library

Data driven testing from multiple types of sources@RunWith(JUnitParamsRunner.class)

Page 63: Test driven development - JUnit basics and best practices

PASS FROM ANNOTATION

@Parameters({“a, A”, “b, B”})@TesttoUpperCaseConvertsCharactersToUpperCase(String in ,

String expectedOut)

Page 64: Test driven development - JUnit basics and best practices

PASS FROM METHOD

@Parameters(method=”dataFor_toUpperCase”)@TesttoUpperCaseConvertsCharactersToUpperCase(String in ,

String expectedOut)

Page 65: Test driven development - JUnit basics and best practices

PASS FROM CLASS

@Parameters(source = DataForToUpperCase.class)@TesttoUpperCaseConvertsCharactersToUpperCase(String in ,

String expectedOut)

Page 66: Test driven development - JUnit basics and best practices

PASS FROM FILE

@FileParameters(“dataForToUpperCase.csv”)@TesttoUpperCaseConvertsCharactersToUpperCase(String in ,

String expectedOut)

Page 67: Test driven development - JUnit basics and best practices

DON’T DO THIS AT HOME

DIFFERENT SCENARIO - SAME DATA SOURCE

DRIVING CONDITIONS FROM DATA

Page 68: Test driven development - JUnit basics and best practices

and the tools change usTOOLS

We change the

Page 69: Test driven development - JUnit basics and best practices

EclEmma Plugina plugin for code coverage in eclipse

Infinitest Plugina plugin that runs tests continuously in eclipse

Page 70: Test driven development - JUnit basics and best practices

Anti-PatternsEvery time you do this a kitten dies…

Page 71: Test driven development - JUnit basics and best practices

1TEST CODE IS SECONDARY

Anti-Pattern

Page 72: Test driven development - JUnit basics and best practices

1PRODUCTION code

=TEST code

Best Practice

Page 73: Test driven development - JUnit basics and best practices

2

REPEATINGTEST CODE

Anti-Pattern

Page 74: Test driven development - JUnit basics and best practices

2

KEEP CODE DRY

Best Practice

Page 75: Test driven development - JUnit basics and best practices

3

TESTINGinternalsor third party code

Anti-Pattern

Page 76: Test driven development - JUnit basics and best practices

3TEST USING PUBLIC API

Best Practice

Page 77: Test driven development - JUnit basics and best practices

4

MULTIPLE SCENARIOS in a test

Anti-Pattern

Page 78: Test driven development - JUnit basics and best practices

4SINGLE

SCENARIOper test

Best Practice

Page 79: Test driven development - JUnit basics and best practices

5

CHANGE OR DELETEtests*

Anti-Pattern

Page 80: Test driven development - JUnit basics and best practices

5ONLY IF

CHANGE IN behavior

Best Practice

Page 81: Test driven development - JUnit basics and best practices

Ending thoughtswe have learnt a lot!

Page 82: Test driven development - JUnit basics and best practices

PRODUCTION CODE TEST CODE

Page 83: Test driven development - JUnit basics and best practices

PRODUCTION CODE TEST CODE

contains nesting doesn’t contain nesting

Is mostly imperative Is declarative

takes more time to write

takes less time to write

Page 84: Test driven development - JUnit basics and best practices

?


Recommended