Exigen Services confidential Exigen Services confidential
Testing your code
For Java developers
Anna Khasanova
Anna.Khasanova@exigenservices.com
20 July 2015
Exigen Services confidential
Agenda
• Testing basics
• TDD approach
• Testing in action
• Best practices
2
Exigen Services confidential
What is a test? Why do we need it?
• What is test?
• Why do we need testing?
• Automation
3
Exigen Services confidential
Automatic testing
Write once run often:
• Write test once
• Run frequently:
• After each change
• Continuous integration
• No human input
4
Exigen Services confidential
TDD THEORY
What is Test Driven Development?
5
Exigen Services confidential
Test Driven Development
• Software development approach
• Test before code
• Test - code requirements
6
Exigen Services confidential
Advantages
• Increase requirements quality
• Increase code quality
• No unnecessary code
7
Exigen Services confidential
New change request?
8
Test fails
Write
test
Run test
Test succeeds
Design
Write
code
Test
succeeds
Run test
Test fails
Whole story covered
Test
succeeds
Refactor
code
Run test
Test fails
All tests succeed
Exigen Services confidential
Bugfix?
• Get bug report
• Turn it into a test
• Test should fail
• Fix bug
• Test should pass
9
Exigen Services confidential
THE PRACTICE
How should I work?
How to write tests?
10
Exigen Services confidential
What is Unit Test?
• Automated test for
• One business unit
• One business case
• Isolated
11
Exigen Services confidential
Unit Test is
• Small
• Fast
• Self documented
12
Exigen Services confidential
3 parts of Unit-test
unitTest() {
// set preconditions: “arrange”
// call tested method: “act”
// assert results are as expected: “assert”
}
13
Exigen Services confidential
Unit-Test libraries
• xUnit – collective naming: dbUnit,
htmlUnit, qUnit, etc.
• Java: jUnit
• Java: TestNG
• Javascript: jasmine
14
Exigen Services confidential
Example of TDD
Telephone field validator:
• Allowed characters:
• numbers: [0-9]
• minus, space: “-” , “ ”
• Length: 10 digits (ignore spaces and minuses)
• Leading and trailing spaces are allowed
15
Exigen Services confidential
REAL LIFE
Mock all dependencies
16
Exigen Services confidential
We have a problem!
• Method uses web service
• or some other class/function
• We don’t want to test it
17
Exigen Services confidential
Mock
• Fake implementation
• We set what mock returns
• Useful for unit-testing
18
Exigen Services confidential
Mock libraries
• Mockito
• EasyMock
• jMock
19
Exigen Services confidential
Example
20
PicturesService
+getSquarePictures()
Repository
+getAllPictures()
Exigen Services confidential
Example
@Test
public void testGetSquarePicturesEmptyResult() {
PicturesService testedService = new PicturesService();
Repository repository = mock(Repository.class);
when(repository.getAllPictures())
.thenReturn(Collections.<Picture>emptyList());
testedService.setRepository(repository);
Set<Picture> result = testedService.getSquarePictures();
assertTrue(result.isEmpty());
}
21
//create fake Repository, returning empty list of pictures
Exigen Services confidential
How to verify external calls?
• What to do if:
• Tested method should call externals
• We need to ensure that it was called?
• Mocks scenario verification
22
Exigen Services confidential
Example
@Test
public void testDeleteSquarePicturesEmptyResult() {
PicturesService testedService = new PicturesService();
Repository repository = mock(Repository.class);
Mockito.when(repository.getAllPictures())
.thenReturn(Collections.<Picture>emptyList());
testedService.setRepository(repository);
testedService.deleteSquarePictures();
verify(repository, never()).deletePictures(any());
}
23
Exigen Services confidential
How to verify arguments?
• What to do if:
• Mocked method is called with parameters
• We need to test passed parameters?
• Argument Captor
• Matchers
24
Exigen Services confidential
Example
@Test
public void testDeleteSquarePictures_captor() {
…
ArgumentCaptor<Iterable> captor =
ArgumentCaptor.forClass(Iterable.class);
verify(repository).deletePictures(captor.capture());
Iterable<Picture> result = captor.getValue();
…
}
25
Exigen Services confidential
How to verify exceptional cases?
• What to do if:
• Tested method should throw exception in
some case
• We need to test this case?
• Expected exceptions
@Test(expected = IllegalArgumentException.class)
public void testFactorialNegative() {
Factorial.factorial(-2);
}
26
Exigen Services confidential
How to verify exceptional cases?
• What to do if:
• We need to test time of execution?
• Timeout parameter
@Test(timeout = 1000)
public void infinity() {
while (true) ;
}
27
Exigen Services confidential
OTHER USEFUL FEATURES
28
Exigen Services confidential
Other features: matchers
Matchers
• when(…), verify(…)
• assertThat(…)
• See hamcrest library
• Write your own
29
Exigen Services confidential
Other features: runners
Test runners
• @RunWith
• Spring: SpringJUnit4ClassRunner
• Parameterized
• Any other
30
Exigen Services confidential
SUMMARY. GUIDELINES.
To sum this all up…
31
Exigen Services confidential
Coverage
• Coverage: what needs to be covered
• Setters-getters
32
Exigen Services confidential
Above all
1. Understand requirements
2. Commit your understanding
• Java docs
• Any other
33
Exigen Services confidential
Unit test
• One test – one case
• Each use case – covered
• Unit test != trash
34
Exigen Services confidential
Write testable code
• Statics are evil
• Extract interfaces
• One method must not do “everything”
35
Exigen Services confidential
Use framework’s features
• Parameterized tests
• Expected exceptions, timeouts
• Mock objects scenarios
• Matchers
36
Exigen Services confidential
Finally
• Automatic testing – difficult to start, but…
• Don’t give up!
37
Exigen Services confidential
QUESTIONS?
Your turn
38

Testing your code