How to keep normal blood
pressure using TDD
A little bit about me
● Java developer at PrivatBank
● more than 3 years of experience
● much less experience in TDD
● blog: kastordriver.one
● e-mail: KastorDriver@gmail.com
Agenda
● what is TDD?
● basic principles of technique
● how to write tests correctly
● tools from the arsenal of Java developer
● some code and examples
Pyramid of fate tests
Unit tests
Integration tests
Manual
tests
What is TDD?
● tests first
● it is not about testing
● it is about design
● and little about documentation
● but they do not replace architecture and
design
Pros
● better design, because you think before writing
● documentation that we can trust
● fast feedback (faster than QA and debug)
● refactoring is encouraged
● minimalistic code
Cons
● not suitable for GUI and database schema development
● discipline is required
● discipline is required for all team members
● erroneous test leads to the erroneous code (problem?)
Test firstTest last
Test last
● we concentrate on the parts of the code instead of design
● by the time of writing tests we get tired
● tests are being wrote taking into account rakes and crutches
● “test last” requires a powerful self-organization (only superhero
is able to do that)
Test first
● write tests on the first wave of enthusiasm
● incentive for write code - pass the test
● look at issue from the user's perspective
● the code is tested and is minimal
Three laws of TDD
● You must not write code while tests
are red
● You must not be farther than one
step from green line
● You must not write code more than
necessary for passing tests
How does it look?
● think before writing test
● formalize business requirements in tests
● name of test has to clearly describe the
purpose of the test
● check that the test fails
Note: Tests clarity should be more important than avoiding code duplication
RED
GREENREFACTOR
How does it look?
● write enough code to compile and pass
the test. No more
● check that the test is passed
● check all other tests
RED
REFACTOR GREEN
How does it look?
● get rid of duplication
● think about design
● go to “red” step
GREENREFACTOR
RED
Provide correct tests names
You should not:
● name test same as tested method
● name tests like: testSomeMethod1, testSomeMethod2...
Provide correct tests names
Name of test should:
● describe feature or specification
● describe purpose of test
● describe what object does, but not what it is
● When [Action] Then [Verification]
@Test
public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() {
FizzBuzzGame fizzBuzz = new FizzBuzzGame();
assertEquals(“1”, fizzBuzz.fizzBuzzNumber(1));
}
public class FizzBuzzGame {
public String fizzBuzzNumber(int number) {
return String.valueOf(1);
}
}
@Test
public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() {
FizzBuzzGame fizzBuzz = new FizzBuzzGame();
assertEquals(“1”, fizzBuzz.fizzBuzzNumber(1));
assertEquals(“2”, fizzBuzz.fizzBuzzNumber(2));
}
public class FizzBuzzGame {
public String fizzBuzzNumber(int number) {
return String.valueOf(number);
}
}
private FizzBuzzGame fizzBuzzGame;
@Before
public void setUp() throws Exception {
fizzBuzzGame = new FizzBuzzGame();
}
@Test
public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() {
assertEquals("1", fizzBuzzGame.fizzBuzzNumber(1));
assertEquals("2", fizzBuzzGame.fizzBuzzNumber(2));
}
@Test
public void whenNumberIsMultipleOf3ThenReturnFizz() {
assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(3));
assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(9));
}
public class FizzBuzzGame {
public String fizzBuzzNumber(int number) {
if (number % 3 == 0) return "Fizz";
return String.valueOf(number);
}
}
private FizzBuzzGame fizzBuzzGame;
@Before
public void setUp() throws Exception {
fizzBuzzGame = new FizzBuzzGame();
}
@Test
public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() {
assertEquals("1", fizzBuzzGame.fizzBuzzNumber(1));
assertEquals("2", fizzBuzzGame.fizzBuzzNumber(2));
}
@Test
public void whenNumberIsMultipleOf3ThenReturnFizz() {
assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(3));
assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(9));
}
@Test
public void whenNumberIsMultipleOf5ThenReturnBuzz() {
assertEquals("Buzz", fizzBuzzGame.fizzBuzzNumber(5));
assertEquals("Buzz", fizzBuzzGame.fizzBuzzNumber(10));
}
public class FizzBuzzGame {
public String fizzBuzzNumber(int number) {
if (number % 3 == 0) return "Fizz";
if (number % 5 == 0) return "Buzz";
return String.valueOf(number);
}
}
private FizzBuzzGame fizzBuzzGame;
@Before
public void setUp() throws Exception {
fizzBuzzGame = new FizzBuzzGame();
}
@Test
public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() {
assertEquals("1", fizzBuzzGame.fizzBuzzNumber(1));
assertEquals("2", fizzBuzzGame.fizzBuzzNumber(2));
}
@Test
public void whenNumberIsMultipleOf3ThenReturnFizz() {
assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(3));
assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(9));
}
@Test
public void whenNumberIsMultipleOf5ThenReturnBazz() {
assertEquals("Bazz", fizzBuzzGame.fizzBuzzNumber(5));
assertEquals("Bazz", fizzBuzzGame.fizzBuzzNumber(10));
}
@Test
public void whenNumberIsMultipleOf3And5ThenReturnFizzBazz() {
assertEquals("FizzBazz", fizzBuzzGame.fizzBuzzNumber(15));
assertEquals("FizzBazz", fizzBuzzGame.fizzBuzzNumber(30));
}
public class FizzBuzzGame {
public String fizzBuzzNumber(int number) {
if (number % 3 == 0) return "Fizz";
if (number % 5 == 0) return "Bazz";
if (number % 3 == 0 && number % 5 == 0) return "FizzBazz";
return String.valueOf(number);
}
}
public class FizzBuzzGame {
public String fizzBuzzNumber(int number) {
if (number % 3 == 0) return "Fizz";
if (number % 5 == 0) return "Bazz";
if (number % 3 == 0 && number % 5 == 0) return "FizzBazz";
return String.valueOf(number);
}
}
org.junit.ComparisonFailure:
Expected :FizzBazz
Actual :Fizz
. . .
FizzBuzzTest.whenNumberIsMultipleOf3And5ThenReturnFizzBazz(FizzBuzzTest.java:36)
public class FizzBuzzGame {
public String fizzBuzzNumber(int number) {
if (number % 3 == 0 && number % 5 == 0) return "FizzBazz";
if (number % 3 == 0) return "Fizz";
if (number % 5 == 0) return "Bazz";
return String.valueOf(number);
}
}
private FizzBuzzGame fizzBuzzGame;
@Before
public void setUp() throws Exception {
fizzBuzzGame = new FizzBuzzGame();
}
@Test
public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() {
assertEquals("1", fizzBuzzGame.fizzBuzzNumber(1));
assertEquals("2", fizzBuzzGame.fizzBuzzNumber(2));
}
@Test
public void whenNumberIsMultipleOnlyOf3ThenReturnFizz() {
assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(3));
assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(9));
}
@Test
public void whenNumberIsMultipleOnlyOf5ThenReturnBazz() {
assertEquals("Bazz", fizzBuzzGame.fizzBuzzNumber(5));
assertEquals("Bazz", fizzBuzzGame.fizzBuzzNumber(10));
}
@Test
public void whenNumberIsMultipleOf3And5ThenReturnFizzBazz() {
assertEquals("FizzBazz", fizzBuzzGame.fizzBuzzNumber(15));
assertEquals("FizzBazz", fizzBuzzGame.fizzBuzzNumber(30));
}
public class FizzBuzzGame {
public String fizzBuzzNumber(int number) {
StringBuilder result = new StringBuilder();
if (number % 3 == 0) {
result.append("Fizz");
}
if (number % 5 == 0) {
result.append("Bazz");
}
return result.length() == 0 ? String.valueOf(number)
: result.toString();
}
}
Separate and rule your tests
http://www.kastordriver.one/2017/02/separate-and-rule-your-tests.html
Unit tests
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
Integration tests
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
We don't have time to write unit tests
Should I write code in a single
class with hundreds methods
without other classes, design
patterns and so on? No? But I
do not have time for that!
http://www.yegor256.com/2015/07/16/fools-dont-write-unit-tests.html
Are You Still Debugging?
Unit testing is a technique that
completely replaces
debugging. If debugging is
required, the design is not
good enough.
http://www.yegor256.com/2016/02/09/are-you-still-debugging.html
Legacy code
Legacy code
● write tests for legacy code
● rename, extract method, extract
interface
● write tests again
● sorry, but no fun
● Mockito makes mocking very easy
● It is extremely easy to read mock code
● Mockito works in any environment and has no
external dependencies
Sip of mockito
import static org.mockito.Mockito.*;
// mock creation
List mockedList = mock(List.class);
// using mock object - it does not throw any "unexpected interaction" exception
mockedList.add("one");
mockedList.add("one");
mockedList.clear();
// selective, explicit, highly readable verification
verify(mockedList, times(2)).add("one");
verify(mockedList).clear();
You can verify interactions
@Test(expected = RuntimeException.class)
public void test() throws Exception {
// you can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);
// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());
// the following prints "null" because get(999) was not stubbed
assertNull(mockedList.get(999));
assertEquals("first", mockedList.get(0));
//throw RuntimeException
mockedList.get(1);
}
You can stub method calls
Be careful with mocks
● Don't mock type you don't own!
● Don't mock everything, it's an anti-pattern
● Don't mock value objects
Mockito discourages
● Can I mock static methods?
○ No. Mockito prefers object orientation
and dependency injection over static,
procedural code that is hard to
understand and change.
● Can I mock private methods?
○ No. From the standpoint of testing...
private methods don't exist.
● Supports Mockito-style mocking.
● Mocks constructors, static, private and final
methods.
Powermock
class FileUtils {
public static Set<String> readUniqueWords(String path) throws IOException {
String text = new String(Files.readAllBytes(Paths.get(path)), "UTF-8");
Set<String> words = new HashSet<>();
for (String word : text.split(" ")) {
words.add(word);
}
return words;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest({Files.class, FileUtils.class})
public class FileUtilsTest {
@Test
public void readUniqueWordsMustReturnOnlyUniqueWords() throws Exception {
final String somePath = "somePath";
Path fakePath = Paths.get(somePath);
PowerMockito.mockStatic(Files.class);
when(Files.readAllBytes(fakePath)).thenReturn("One two two three".getBytes());
Set<String> result = FileUtils.readUniqueWords(somePath);
assertEquals(3, result.size());
assertTrue(result.contains("One"));
assertTrue(result.contains("two"));
assertTrue(result.contains("three"));
}
}
class Text {
private final String path;
Text(String src) {
this.path = src;
}
public String readText() throws IOException {
return new String(Files.readAllBytes(Paths.get(this.path)), "UTF-8");
}
}
public class UniqueWords {
private final String text;
UniqueWords(String txt) {
this.text = txt;
}
public Set<String> readUniqueWords() {
Set<String> words = new HashSet<>();
for (String word : this.text.split(" ")) {
words.add(word);
}
return words;
}
}
public class UniqueWordsTest {
@Test
public void readUniqueWordsMustReturnOnlyUniqueWords() throws Exception {
Set<String> result = new UniqueWords("One two two three")
.readUniqueWords();
assertEquals(3, result.size());
assertTrue(result.contains("One"));
assertTrue(result.contains("two"));
assertTrue(result.contains("three"));
}
}
Odd man out
Cobertura maven plugin allows you:
● Check the coverage percentages for unit
tests and integration tests
● fail the build if the targets are not met
Keep a code coverage on a radar
http://www.kastordriver.one/2017/02/keep-code-coverage-on-radar.html
Useful links
Kent Beck "Test Driven Development"
Андрей Солнцев “Пацан накодил - пацан протестил!
Mockito wiki
Николай Алименков "Сага о том, как Java-
разработчики должны тестировать свои
приложения"
Victor Farcic, Alex Garcia "Test-Driven Java Development"
Thank you for your attention

"How keep normal blood pressure using TDD" By Roman Loparev

  • 1.
    How to keepnormal blood pressure using TDD
  • 2.
    A little bitabout me ● Java developer at PrivatBank ● more than 3 years of experience ● much less experience in TDD ● blog: kastordriver.one ● e-mail: KastorDriver@gmail.com
  • 3.
    Agenda ● what isTDD? ● basic principles of technique ● how to write tests correctly ● tools from the arsenal of Java developer ● some code and examples
  • 4.
    Pyramid of fatetests Unit tests Integration tests Manual tests
  • 5.
    What is TDD? ●tests first ● it is not about testing ● it is about design ● and little about documentation ● but they do not replace architecture and design
  • 6.
    Pros ● better design,because you think before writing ● documentation that we can trust ● fast feedback (faster than QA and debug) ● refactoring is encouraged ● minimalistic code
  • 7.
    Cons ● not suitablefor GUI and database schema development ● discipline is required ● discipline is required for all team members ● erroneous test leads to the erroneous code (problem?)
  • 8.
  • 9.
    Test last ● weconcentrate on the parts of the code instead of design ● by the time of writing tests we get tired ● tests are being wrote taking into account rakes and crutches ● “test last” requires a powerful self-organization (only superhero is able to do that)
  • 10.
    Test first ● writetests on the first wave of enthusiasm ● incentive for write code - pass the test ● look at issue from the user's perspective ● the code is tested and is minimal
  • 11.
    Three laws ofTDD ● You must not write code while tests are red ● You must not be farther than one step from green line ● You must not write code more than necessary for passing tests
  • 12.
    How does itlook? ● think before writing test ● formalize business requirements in tests ● name of test has to clearly describe the purpose of the test ● check that the test fails Note: Tests clarity should be more important than avoiding code duplication RED GREENREFACTOR
  • 13.
    How does itlook? ● write enough code to compile and pass the test. No more ● check that the test is passed ● check all other tests RED REFACTOR GREEN
  • 14.
    How does itlook? ● get rid of duplication ● think about design ● go to “red” step GREENREFACTOR RED
  • 15.
    Provide correct testsnames You should not: ● name test same as tested method ● name tests like: testSomeMethod1, testSomeMethod2...
  • 16.
    Provide correct testsnames Name of test should: ● describe feature or specification ● describe purpose of test ● describe what object does, but not what it is ● When [Action] Then [Verification]
  • 18.
    @Test public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber(){ FizzBuzzGame fizzBuzz = new FizzBuzzGame(); assertEquals(“1”, fizzBuzz.fizzBuzzNumber(1)); }
  • 19.
    public class FizzBuzzGame{ public String fizzBuzzNumber(int number) { return String.valueOf(1); } }
  • 20.
    @Test public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber(){ FizzBuzzGame fizzBuzz = new FizzBuzzGame(); assertEquals(“1”, fizzBuzz.fizzBuzzNumber(1)); assertEquals(“2”, fizzBuzz.fizzBuzzNumber(2)); }
  • 21.
    public class FizzBuzzGame{ public String fizzBuzzNumber(int number) { return String.valueOf(number); } }
  • 22.
    private FizzBuzzGame fizzBuzzGame; @Before publicvoid setUp() throws Exception { fizzBuzzGame = new FizzBuzzGame(); } @Test public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() { assertEquals("1", fizzBuzzGame.fizzBuzzNumber(1)); assertEquals("2", fizzBuzzGame.fizzBuzzNumber(2)); } @Test public void whenNumberIsMultipleOf3ThenReturnFizz() { assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(3)); assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(9)); }
  • 23.
    public class FizzBuzzGame{ public String fizzBuzzNumber(int number) { if (number % 3 == 0) return "Fizz"; return String.valueOf(number); } }
  • 24.
    private FizzBuzzGame fizzBuzzGame; @Before publicvoid setUp() throws Exception { fizzBuzzGame = new FizzBuzzGame(); } @Test public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() { assertEquals("1", fizzBuzzGame.fizzBuzzNumber(1)); assertEquals("2", fizzBuzzGame.fizzBuzzNumber(2)); } @Test public void whenNumberIsMultipleOf3ThenReturnFizz() { assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(3)); assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(9)); } @Test public void whenNumberIsMultipleOf5ThenReturnBuzz() { assertEquals("Buzz", fizzBuzzGame.fizzBuzzNumber(5)); assertEquals("Buzz", fizzBuzzGame.fizzBuzzNumber(10)); }
  • 25.
    public class FizzBuzzGame{ public String fizzBuzzNumber(int number) { if (number % 3 == 0) return "Fizz"; if (number % 5 == 0) return "Buzz"; return String.valueOf(number); } }
  • 26.
    private FizzBuzzGame fizzBuzzGame; @Before publicvoid setUp() throws Exception { fizzBuzzGame = new FizzBuzzGame(); } @Test public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() { assertEquals("1", fizzBuzzGame.fizzBuzzNumber(1)); assertEquals("2", fizzBuzzGame.fizzBuzzNumber(2)); } @Test public void whenNumberIsMultipleOf3ThenReturnFizz() { assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(3)); assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(9)); } @Test public void whenNumberIsMultipleOf5ThenReturnBazz() { assertEquals("Bazz", fizzBuzzGame.fizzBuzzNumber(5)); assertEquals("Bazz", fizzBuzzGame.fizzBuzzNumber(10)); } @Test public void whenNumberIsMultipleOf3And5ThenReturnFizzBazz() { assertEquals("FizzBazz", fizzBuzzGame.fizzBuzzNumber(15)); assertEquals("FizzBazz", fizzBuzzGame.fizzBuzzNumber(30)); }
  • 27.
    public class FizzBuzzGame{ public String fizzBuzzNumber(int number) { if (number % 3 == 0) return "Fizz"; if (number % 5 == 0) return "Bazz"; if (number % 3 == 0 && number % 5 == 0) return "FizzBazz"; return String.valueOf(number); } }
  • 28.
    public class FizzBuzzGame{ public String fizzBuzzNumber(int number) { if (number % 3 == 0) return "Fizz"; if (number % 5 == 0) return "Bazz"; if (number % 3 == 0 && number % 5 == 0) return "FizzBazz"; return String.valueOf(number); } } org.junit.ComparisonFailure: Expected :FizzBazz Actual :Fizz . . . FizzBuzzTest.whenNumberIsMultipleOf3And5ThenReturnFizzBazz(FizzBuzzTest.java:36)
  • 29.
    public class FizzBuzzGame{ public String fizzBuzzNumber(int number) { if (number % 3 == 0 && number % 5 == 0) return "FizzBazz"; if (number % 3 == 0) return "Fizz"; if (number % 5 == 0) return "Bazz"; return String.valueOf(number); } }
  • 30.
    private FizzBuzzGame fizzBuzzGame; @Before publicvoid setUp() throws Exception { fizzBuzzGame = new FizzBuzzGame(); } @Test public void whenNumberIsNotMultipleOf3And5ThenReturnTheSameNumber() { assertEquals("1", fizzBuzzGame.fizzBuzzNumber(1)); assertEquals("2", fizzBuzzGame.fizzBuzzNumber(2)); } @Test public void whenNumberIsMultipleOnlyOf3ThenReturnFizz() { assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(3)); assertEquals("Fizz", fizzBuzzGame.fizzBuzzNumber(9)); } @Test public void whenNumberIsMultipleOnlyOf5ThenReturnBazz() { assertEquals("Bazz", fizzBuzzGame.fizzBuzzNumber(5)); assertEquals("Bazz", fizzBuzzGame.fizzBuzzNumber(10)); } @Test public void whenNumberIsMultipleOf3And5ThenReturnFizzBazz() { assertEquals("FizzBazz", fizzBuzzGame.fizzBuzzNumber(15)); assertEquals("FizzBazz", fizzBuzzGame.fizzBuzzNumber(30)); }
  • 31.
    public class FizzBuzzGame{ public String fizzBuzzNumber(int number) { StringBuilder result = new StringBuilder(); if (number % 3 == 0) { result.append("Fizz"); } if (number % 5 == 0) { result.append("Bazz"); } return result.length() == 0 ? String.valueOf(number) : result.toString(); } }
  • 32.
    Separate and ruleyour tests http://www.kastordriver.one/2017/02/separate-and-rule-your-tests.html
  • 33.
  • 34.
  • 35.
    We don't havetime to write unit tests Should I write code in a single class with hundreds methods without other classes, design patterns and so on? No? But I do not have time for that! http://www.yegor256.com/2015/07/16/fools-dont-write-unit-tests.html
  • 36.
    Are You StillDebugging? Unit testing is a technique that completely replaces debugging. If debugging is required, the design is not good enough. http://www.yegor256.com/2016/02/09/are-you-still-debugging.html
  • 37.
  • 38.
    Legacy code ● writetests for legacy code ● rename, extract method, extract interface ● write tests again ● sorry, but no fun
  • 39.
    ● Mockito makesmocking very easy ● It is extremely easy to read mock code ● Mockito works in any environment and has no external dependencies Sip of mockito
  • 40.
    import static org.mockito.Mockito.*; //mock creation List mockedList = mock(List.class); // using mock object - it does not throw any "unexpected interaction" exception mockedList.add("one"); mockedList.add("one"); mockedList.clear(); // selective, explicit, highly readable verification verify(mockedList, times(2)).add("one"); verify(mockedList).clear(); You can verify interactions
  • 41.
    @Test(expected = RuntimeException.class) publicvoid test() throws Exception { // you can mock concrete classes, not only interfaces LinkedList mockedList = mock(LinkedList.class); // stubbing appears before the actual execution when(mockedList.get(0)).thenReturn("first"); when(mockedList.get(1)).thenThrow(new RuntimeException()); // the following prints "null" because get(999) was not stubbed assertNull(mockedList.get(999)); assertEquals("first", mockedList.get(0)); //throw RuntimeException mockedList.get(1); } You can stub method calls
  • 42.
    Be careful withmocks ● Don't mock type you don't own! ● Don't mock everything, it's an anti-pattern ● Don't mock value objects
  • 43.
    Mockito discourages ● CanI mock static methods? ○ No. Mockito prefers object orientation and dependency injection over static, procedural code that is hard to understand and change. ● Can I mock private methods? ○ No. From the standpoint of testing... private methods don't exist.
  • 44.
    ● Supports Mockito-stylemocking. ● Mocks constructors, static, private and final methods. Powermock
  • 45.
    class FileUtils { publicstatic Set<String> readUniqueWords(String path) throws IOException { String text = new String(Files.readAllBytes(Paths.get(path)), "UTF-8"); Set<String> words = new HashSet<>(); for (String word : text.split(" ")) { words.add(word); } return words; } }
  • 46.
    @RunWith(PowerMockRunner.class) @PrepareForTest({Files.class, FileUtils.class}) public classFileUtilsTest { @Test public void readUniqueWordsMustReturnOnlyUniqueWords() throws Exception { final String somePath = "somePath"; Path fakePath = Paths.get(somePath); PowerMockito.mockStatic(Files.class); when(Files.readAllBytes(fakePath)).thenReturn("One two two three".getBytes()); Set<String> result = FileUtils.readUniqueWords(somePath); assertEquals(3, result.size()); assertTrue(result.contains("One")); assertTrue(result.contains("two")); assertTrue(result.contains("three")); } }
  • 47.
    class Text { privatefinal String path; Text(String src) { this.path = src; } public String readText() throws IOException { return new String(Files.readAllBytes(Paths.get(this.path)), "UTF-8"); } }
  • 48.
    public class UniqueWords{ private final String text; UniqueWords(String txt) { this.text = txt; } public Set<String> readUniqueWords() { Set<String> words = new HashSet<>(); for (String word : this.text.split(" ")) { words.add(word); } return words; } }
  • 49.
    public class UniqueWordsTest{ @Test public void readUniqueWordsMustReturnOnlyUniqueWords() throws Exception { Set<String> result = new UniqueWords("One two two three") .readUniqueWords(); assertEquals(3, result.size()); assertTrue(result.contains("One")); assertTrue(result.contains("two")); assertTrue(result.contains("three")); } }
  • 50.
  • 51.
    Cobertura maven pluginallows you: ● Check the coverage percentages for unit tests and integration tests ● fail the build if the targets are not met Keep a code coverage on a radar http://www.kastordriver.one/2017/02/keep-code-coverage-on-radar.html
  • 52.
    Useful links Kent Beck"Test Driven Development" Андрей Солнцев “Пацан накодил - пацан протестил! Mockito wiki Николай Алименков "Сага о том, как Java- разработчики должны тестировать свои приложения" Victor Farcic, Alex Garcia "Test-Driven Java Development"
  • 53.
    Thank you foryour attention