SlideShare a Scribd company logo
Russell Gold
Any fool can write code that a
computer can understand. Good
programmers write code that humans
can understand.
- Martin Fowler
What’s wrong with this test?
@Test
public void testRead() throws Exception {
Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(instream.read()).thenReturn(0, -1);
Assert.assertEquals(0, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream);
Assert.assertEquals(-1, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(instream, Mockito.times(1)).close();
Mockito.verify(eofwatcher).eofDetected(instream);
Assert.assertEquals(-1, eofstream.read());
}
(from the open-source project HttpClient)
Value of Unit Tests
Prevent Regression
Drive Development Facilitate Refactoring
Document Functionality
Strive for Clean Code
if ((getDate().year – dob.year > 62 || (getDate().year – dob.year == 62
&& getDate().month > dob.month)) && early)
payment = getEarlyPay();
else if ((getDate().year – dob.year > 65 || (getDate().year – dob.year == 65
&& getDate().month >= dob.month)) && !early)
payment = getRegPay();
else
payment = 0;
Duplication
Strive for Clean Code
if (getAgeInYears() >= 62 && early)
payment = getEarlyPay();
else if (getAgeInYears() >= 65 && !early)
payment = getRegPay();
else
payment = 0;
int getAgeInYears() {
int age = getDate().year – dob.year;
if (getDate().month >= dob.month) age++;
return age;
}
Magic
numbers
Strive for Clean Code
final static int EARLY_RETIREMENT_AGE = 62;
final static int REGULAR_RETIREMENT_AGE = 65;
if (getAgeInYears() >= EARLY_RETIREMENT_AGE && early)
payment = getEarlyPay();
else if (getAgeInYears() >= REGULAR_RETIREMENT_AGE && !early)
payment = getRegPay();
else
payment = 0; Complex conditional
Strive for Clean Code
final static int EARLY_RETIREMENT_AGE = 62;
final static int REGULAR_RETIREMENT_AGE = 65;
if (isCollectingEarlyRetirement())
payment = getEarlyPay();
else if (isCollectingRegularRetirement())
payment = getRegPay();
else
payment = 0;
boolean isCollectingEarlyRetirement() {
return early && getAgeInYears() >= EARLY_RETIREMENT_AGE);
}
Ambiguous
names
Strive for Clean Code
final static int EARLY_RETIREMENT_AGE = 62;
final static int REGULAR_RETIREMENT_AGE = 65;
if (isCollectingEarlyRetirement())
payment = getEarlyRetirementPayment();
else if (isCollectingRegularRetirement())
payment = getRegularRetirementPayment();
else
payment = 0;
boolean isCollectingEarlyRetirement() {
return electedEarlyRetirement && getAgeInYears() >= EARLY_RETIREMENT_AGE);
}
Unit Tests are Code
 Choose good method names
 Keep methods short and coherent
 Avoid magic numbers
 Avoid long argument lists
 Avoid duplication
Test One Thing Per Test
@Test
public void afterCellAdded_boardIsAtLeast10x10() {
Board board = new Board();
board.addCell(0, 0);
assertThat(board.getHeight(), is(greaterThan(10));
assertThat(board.getWidth(), is(greaterThan(10));
}
Name describes exactly what is being tested
Set up (could be part of test class setup)
Operation to test
Validation
Hamcrest Library
assertThat(number, both(greaterThan(10)).and(LessThan(30)));
assertThat(array, is(emptyArray());
assertThat(collection, hasItems(1, 4, 7));
assertThat(map, hasKey("color")
assertThat(javaBean, hasProperty("age"));
What’s wrong with this test?
@Test
public void testRead() throws Exception {
Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(instream.read()).thenReturn(0, -1);
Assert.assertEquals(0, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream);
Assert.assertEquals(-1, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(instream, Mockito.times(1)).close();
Mockito.verify(eofwatcher).eofDetected(instream);
Assert.assertEquals(-1, eofstream.read());
}
@Test
public void testRead() throws Exception {
Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(instream.read()).thenReturn(0, -1);
Assert.assertEquals(0, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream);
Assert.assertEquals(-1, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(instream, Mockito.times(1)).close();
Mockito.verify(eofwatcher).eofDetected(instream);
Assert.assertEquals(-1, eofstream.read());
}
Ambiguous
Sequence of cases
Magic numbers
Confusing Names
EofSensorInputStream
getWatcher()
getWrappedStream()
EofSensorWatcher
InputStream
eofwatcher
instream
Class being tested has two
component classes
wrappedStream
watcher
eofstream
Step 1: fix names
@Test
public void testRead() throws Exception {
Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(instream.read()).thenReturn(0, -1);
Assert.assertEquals(0, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream);
Assert.assertEquals(-1, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(instream, Mockito.times(1)).close();
Mockito.verify(eofwatcher).eofDetected(instream);
Assert.assertEquals(-1, eofstream.read());
}
Step 1: fix names
@Test
public void testRead() throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(0, -1);
Assert.assertEquals(0, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream);
Assert.assertEquals(-1, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(wrappedStream, Mockito.times(1)).close();
Mockito.verify(watcher).eofDetected(wrappedStream);
Assert.assertEquals(-1, eofstream.read());
}
Step 2: magic numbers
@Test
public void testRead() throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(0, -1);
Assert.assertEquals(0, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream);
Assert.assertEquals(-1, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(wrappedStream, Mockito.times(1)).close();
Mockito.verify(watcher).eofDetected(wrappedStream);
Assert.assertEquals(-1, eofstream.read());
}
Step 2: magic numbers
@Test
public void testRead() throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(0, -1);
Assert.assertEquals(0, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream);
Assert.assertEquals(-1, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(wrappedStream, Mockito.times(1)).close();
Mockito.verify(watcher).eofDetected(wrappedStream);
Assert.assertEquals(-1, eofstream.read());
}
Step 2: magic numbers
@Test
public void testRead() throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
Assert.assertEquals(DATA_VALUE, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream);
Assert.assertEquals(EOF, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(wrappedStream, Mockito.times(1)).close();
Mockito.verify(watcher).eofDetected(wrappedStream);
Assert.assertEquals(EOF, eofstream.read());
}
Step 3: What’s being
tested?@Test
public void testRead() throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
Assert.assertEquals(DATA_VALUE, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream);
Assert.assertEquals(EOF, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(wrappedStream, Mockito.times(1)).close();
Mockito.verify(watcher).eofDetected(wrappedStream);
Assert.assertEquals(EOF, eofstream.read());
}
Step 4: Separate the Tests
@Test
public void testRead() throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
Assert.assertEquals(DATA_VALUE, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream);
Assert.assertEquals(EOF, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(wrappedStream, Mockito.times(1)).close();
Mockito.verify(watcher).eofDetected(wrappedStream);
Assert.assertEquals(EOF, eofstream.read());
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readReturnsNextByte() throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
Assert.assertEquals(DATA_VALUE, eofstream.read());
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readReturnsNextByte() throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
Assert.assertEquals(DATA_VALUE, eofstream.read());
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
Assert.assertEquals(DATA_VALUE, eofstream.read());
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
Assert.assertEquals(DATA_VALUE, eofstream.read());
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
assertThat(eofstream.read(), is(DATA_VALUE));
}
Step 4: Separate the Tests
@Test
public void testRead() throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
Assert.assertEquals(DATA_VALUE, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNotNull(eofstream.getWrappedStream());
Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream);
Assert.assertEquals(EOF, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
Assert.assertNull(eofstream.getWrappedStream());
Mockito.verify(wrappedStream, Mockito.times(1)).close();
Mockito.verify(watcher).eofDetected(wrappedStream);
Assert.assertEquals(EOF, eofstream.read());
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readDoesNotCloseStream () throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
Assert.assertEquals(DATA_VALUE, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
}
@Test
public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
assertThat(eofstream.read(), is(DATA_VALUE));
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readDoesNotCloseStream () throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
Assert.assertEquals(DATA_VALUE, eofstream.read());
Assert.assertFalse(eofstream.isSelfClosed());
}
@Test
public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
assertThat(eofstream.read(), is(DATA_VALUE));
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readDoesNotCloseStream () throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
eofstream.read();
Assert.assertFalse(eofstream.isSelfClosed());
}
@Test
public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
assertThat(eofstream.read(), is(DATA_VALUE));
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readDoesNotCloseStream () throws Exception {
Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE);
Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF);
eofstream.read();
Assert.assertFalse(eofstream.isSelfClosed());
}
@Test
public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
assertThat(eofstream.read(), is(DATA_VALUE));
}
Step 4: Separate the Tests
@Test
public void whenNotAtEOF_readDoesNotCloseStream () throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
eofstream.read();
Assert.assertFalse(eofstream.isSelfClosed());
}
@Test
public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
assertThat(eofstream.read(), is(DATA_VALUE));
}
@Test
public void afterSuccessfulRead_haveOriginalWrappedStream() throws Exception {
wrappedStream.returnOnRead(DATA_VALUE);
eofstream.read();
assertThat(eofstream.getWrappedStream(), sameInstance((InputStream) wrappedStream));
}
@Test
public void whenNoData_readReturnsEOF() throws Exception {
assertThat(eofstream.read(), is(EOF));
}
@Test
public void afterEofRead_streamIsNotSelfClosed() throws Exception {
eofstream.read();
assertFalse(eofstream.isSelfClosed());
}
@Test
public void afterEofRead_wrappedStreamIsNull() throws Exception {
eofstream.read();
assertThat(eofstream.getWrappedStream(), nullValue());
}
@Test
public void afterEofRead_wrappedStreamIsClosed() throws Exception {
eofstream.read();
assertTrue(wrappedStream.isClosed());
}
@Test
public void afterEofRead_nextReadReturnsEOF() throws Exception {
eofstream.read();
assertThat(eofstream.read(), is(EOF));
}
Tests Document Behavior
whenNotAtEOF_readReturnsNextByteFromWrappedStream
whenNotAtEOF_readDoesNotCloseStream
afterSuccessfulRead_haveOriginalWrappedStream
whenNoData_readReturnsEOF
afterEofRead_streamIsNotSelfClosed
afterEofRead_wrappedStreamIsNull
afterEofRead_wrappedStreamIsClosed
afterEofRead_nextReadReturnsEOF
Unit Tests are Executable Documentation
 Keep the tests clean
 Test one thing per test
 Use descriptive names
Q&A

More Related Content

KEY
Test-driven development for TYPO3 (T3DD11)
PDF
The Impact of Test Case Summaries on Bug Fixing Performance: An Empirical Inv...
PDF
An introduction to Google test framework
PPTX
Migrating to JUnit 5
PDF
GMock framework
PDF
PPT
2012 JDays Bad Tests Good Tests
DOCX
Exception Handling in Scala
Test-driven development for TYPO3 (T3DD11)
The Impact of Test Case Summaries on Bug Fixing Performance: An Empirical Inv...
An introduction to Google test framework
Migrating to JUnit 5
GMock framework
2012 JDays Bad Tests Good Tests
Exception Handling in Scala

What's hot (20)

PPTX
Unit testing concurrent code
PPTX
Smarter Testing With Spock
PPS
Bdd: Tdd and beyond the infinite
PDF
Spock framework
KEY
About java
PDF
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
PDF
Java 7 LavaJUG
PDF
Google guava
PPT
Simple API for XML
KEY
Test-driven Development for TYPO3
ODP
JBoss Drools
PDF
Conf soat tests_unitaires_Mockito_jUnit_170113
PDF
Spock: Test Well and Prosper
PDF
soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin
PDF
Spock Framework
PDF
What can be done with Java, but should better be done with Erlang (@pavlobaron)
PDF
33rd Degree 2013, Bad Tests, Good Tests
PDF
GeeCON 2012 Bad Tests, Good Tests
PDF
Confitura 2012 Bad Tests, Good Tests
PDF
Software Testing - Invited Lecture at UNSW Sydney
Unit testing concurrent code
Smarter Testing With Spock
Bdd: Tdd and beyond the infinite
Spock framework
About java
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 LavaJUG
Google guava
Simple API for XML
Test-driven Development for TYPO3
JBoss Drools
Conf soat tests_unitaires_Mockito_jUnit_170113
Spock: Test Well and Prosper
soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin
Spock Framework
What can be done with Java, but should better be done with Erlang (@pavlobaron)
33rd Degree 2013, Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good Tests
Software Testing - Invited Lecture at UNSW Sydney
Ad

Similar to Executable documentation (20)

PDF
Developer Test - Things to Know
PPTX
Best practices unit testing
PPTX
Building unit tests correctly
PDF
2013 DevFest Vienna - Bad Tests, Good Tests
PDF
Bad test, good test
DOCX
Junit With Eclipse
PPTX
Unit Testing FAQ
PDF
Unit testing basic
PPTX
Building unit tests correctly with visual studio 2013
PDF
JUnit & Mockito, first steps
PDF
Unit Testing
PDF
Software Testing
PDF
Developer Tests - Things to Know (Vilnius JUG)
PPTX
Software testing ... who’s responsible is it?
PPTX
Software testing ... who is responsible for it?
PDF
PDF
unit_tests_tutorial
PDF
Developer Tests - Things to Know
PDF
Test driven development - JUnit basics and best practices
PDF
J unit a starter guide
Developer Test - Things to Know
Best practices unit testing
Building unit tests correctly
2013 DevFest Vienna - Bad Tests, Good Tests
Bad test, good test
Junit With Eclipse
Unit Testing FAQ
Unit testing basic
Building unit tests correctly with visual studio 2013
JUnit & Mockito, first steps
Unit Testing
Software Testing
Developer Tests - Things to Know (Vilnius JUG)
Software testing ... who’s responsible is it?
Software testing ... who is responsible for it?
unit_tests_tutorial
Developer Tests - Things to Know
Test driven development - JUnit basics and best practices
J unit a starter guide
Ad

Recently uploaded (20)

PDF
System and Network Administration Chapter 2
PDF
Nekopoi APK 2025 free lastest update
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PPT
Introduction Database Management System for Course Database
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
System and Network Administraation Chapter 3
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Digital Strategies for Manufacturing Companies
PPTX
Online Work Permit System for Fast Permit Processing
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
top salesforce developer skills in 2025.pdf
PPTX
history of c programming in notes for students .pptx
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
System and Network Administration Chapter 2
Nekopoi APK 2025 free lastest update
Design an Analysis of Algorithms II-SECS-1021-03
Introduction Database Management System for Course Database
Wondershare Filmora 15 Crack With Activation Key [2025
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
VVF-Customer-Presentation2025-Ver1.9.pptx
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
System and Network Administraation Chapter 3
Softaken Excel to vCard Converter Software.pdf
Digital Strategies for Manufacturing Companies
Online Work Permit System for Fast Permit Processing
ISO 45001 Occupational Health and Safety Management System
Upgrade and Innovation Strategies for SAP ERP Customers
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 41
CHAPTER 2 - PM Management and IT Context
top salesforce developer skills in 2025.pdf
history of c programming in notes for students .pptx
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx

Executable documentation

  • 2. Any fool can write code that a computer can understand. Good programmers write code that humans can understand. - Martin Fowler
  • 3. What’s wrong with this test? @Test public void testRead() throws Exception { Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(instream.read()).thenReturn(0, -1); Assert.assertEquals(0, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(eofwatcher).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); } (from the open-source project HttpClient)
  • 4. Value of Unit Tests Prevent Regression Drive Development Facilitate Refactoring Document Functionality
  • 5. Strive for Clean Code if ((getDate().year – dob.year > 62 || (getDate().year – dob.year == 62 && getDate().month > dob.month)) && early) payment = getEarlyPay(); else if ((getDate().year – dob.year > 65 || (getDate().year – dob.year == 65 && getDate().month >= dob.month)) && !early) payment = getRegPay(); else payment = 0; Duplication
  • 6. Strive for Clean Code if (getAgeInYears() >= 62 && early) payment = getEarlyPay(); else if (getAgeInYears() >= 65 && !early) payment = getRegPay(); else payment = 0; int getAgeInYears() { int age = getDate().year – dob.year; if (getDate().month >= dob.month) age++; return age; } Magic numbers
  • 7. Strive for Clean Code final static int EARLY_RETIREMENT_AGE = 62; final static int REGULAR_RETIREMENT_AGE = 65; if (getAgeInYears() >= EARLY_RETIREMENT_AGE && early) payment = getEarlyPay(); else if (getAgeInYears() >= REGULAR_RETIREMENT_AGE && !early) payment = getRegPay(); else payment = 0; Complex conditional
  • 8. Strive for Clean Code final static int EARLY_RETIREMENT_AGE = 62; final static int REGULAR_RETIREMENT_AGE = 65; if (isCollectingEarlyRetirement()) payment = getEarlyPay(); else if (isCollectingRegularRetirement()) payment = getRegPay(); else payment = 0; boolean isCollectingEarlyRetirement() { return early && getAgeInYears() >= EARLY_RETIREMENT_AGE); } Ambiguous names
  • 9. Strive for Clean Code final static int EARLY_RETIREMENT_AGE = 62; final static int REGULAR_RETIREMENT_AGE = 65; if (isCollectingEarlyRetirement()) payment = getEarlyRetirementPayment(); else if (isCollectingRegularRetirement()) payment = getRegularRetirementPayment(); else payment = 0; boolean isCollectingEarlyRetirement() { return electedEarlyRetirement && getAgeInYears() >= EARLY_RETIREMENT_AGE); }
  • 10. Unit Tests are Code  Choose good method names  Keep methods short and coherent  Avoid magic numbers  Avoid long argument lists  Avoid duplication
  • 11. Test One Thing Per Test @Test public void afterCellAdded_boardIsAtLeast10x10() { Board board = new Board(); board.addCell(0, 0); assertThat(board.getHeight(), is(greaterThan(10)); assertThat(board.getWidth(), is(greaterThan(10)); } Name describes exactly what is being tested Set up (could be part of test class setup) Operation to test Validation
  • 12. Hamcrest Library assertThat(number, both(greaterThan(10)).and(LessThan(30))); assertThat(array, is(emptyArray()); assertThat(collection, hasItems(1, 4, 7)); assertThat(map, hasKey("color") assertThat(javaBean, hasProperty("age"));
  • 13. What’s wrong with this test? @Test public void testRead() throws Exception { Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(instream.read()).thenReturn(0, -1); Assert.assertEquals(0, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(eofwatcher).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); }
  • 14. @Test public void testRead() throws Exception { Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(instream.read()).thenReturn(0, -1); Assert.assertEquals(0, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(eofwatcher).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); } Ambiguous Sequence of cases Magic numbers Confusing Names
  • 16. Step 1: fix names @Test public void testRead() throws Exception { Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(instream.read()).thenReturn(0, -1); Assert.assertEquals(0, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(eofwatcher).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); }
  • 17. Step 1: fix names @Test public void testRead() throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(0, -1); Assert.assertEquals(0, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream); Assert.assertEquals(-1, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(wrappedStream, Mockito.times(1)).close(); Mockito.verify(watcher).eofDetected(wrappedStream); Assert.assertEquals(-1, eofstream.read()); }
  • 18. Step 2: magic numbers @Test public void testRead() throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(0, -1); Assert.assertEquals(0, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream); Assert.assertEquals(-1, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(wrappedStream, Mockito.times(1)).close(); Mockito.verify(watcher).eofDetected(wrappedStream); Assert.assertEquals(-1, eofstream.read()); }
  • 19. Step 2: magic numbers @Test public void testRead() throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(0, -1); Assert.assertEquals(0, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream); Assert.assertEquals(-1, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(wrappedStream, Mockito.times(1)).close(); Mockito.verify(watcher).eofDetected(wrappedStream); Assert.assertEquals(-1, eofstream.read()); }
  • 20. Step 2: magic numbers @Test public void testRead() throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); Assert.assertEquals(DATA_VALUE, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream); Assert.assertEquals(EOF, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(wrappedStream, Mockito.times(1)).close(); Mockito.verify(watcher).eofDetected(wrappedStream); Assert.assertEquals(EOF, eofstream.read()); }
  • 21. Step 3: What’s being tested?@Test public void testRead() throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); Assert.assertEquals(DATA_VALUE, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream); Assert.assertEquals(EOF, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(wrappedStream, Mockito.times(1)).close(); Mockito.verify(watcher).eofDetected(wrappedStream); Assert.assertEquals(EOF, eofstream.read()); }
  • 22. Step 4: Separate the Tests @Test public void testRead() throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); Assert.assertEquals(DATA_VALUE, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream); Assert.assertEquals(EOF, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(wrappedStream, Mockito.times(1)).close(); Mockito.verify(watcher).eofDetected(wrappedStream); Assert.assertEquals(EOF, eofstream.read()); }
  • 23. Step 4: Separate the Tests @Test public void whenNotAtEOF_readReturnsNextByte() throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); Assert.assertEquals(DATA_VALUE, eofstream.read()); }
  • 24. Step 4: Separate the Tests @Test public void whenNotAtEOF_readReturnsNextByte() throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); Assert.assertEquals(DATA_VALUE, eofstream.read()); }
  • 25. Step 4: Separate the Tests @Test public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception { wrappedStream.returnOnRead(DATA_VALUE); Assert.assertEquals(DATA_VALUE, eofstream.read()); }
  • 26. Step 4: Separate the Tests @Test public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception { wrappedStream.returnOnRead(DATA_VALUE); Assert.assertEquals(DATA_VALUE, eofstream.read()); }
  • 27. Step 4: Separate the Tests @Test public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception { wrappedStream.returnOnRead(DATA_VALUE); assertThat(eofstream.read(), is(DATA_VALUE)); }
  • 28. Step 4: Separate the Tests @Test public void testRead() throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); Assert.assertEquals(DATA_VALUE, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(watcher, Mockito.never()).eofDetected(wrappedStream); Assert.assertEquals(EOF, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(wrappedStream, Mockito.times(1)).close(); Mockito.verify(watcher).eofDetected(wrappedStream); Assert.assertEquals(EOF, eofstream.read()); }
  • 29. Step 4: Separate the Tests @Test public void whenNotAtEOF_readDoesNotCloseStream () throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); Assert.assertEquals(DATA_VALUE, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); } @Test public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception { wrappedStream.returnOnRead(DATA_VALUE); assertThat(eofstream.read(), is(DATA_VALUE)); }
  • 30. Step 4: Separate the Tests @Test public void whenNotAtEOF_readDoesNotCloseStream () throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); Assert.assertEquals(DATA_VALUE, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); } @Test public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception { wrappedStream.returnOnRead(DATA_VALUE); assertThat(eofstream.read(), is(DATA_VALUE)); }
  • 31. Step 4: Separate the Tests @Test public void whenNotAtEOF_readDoesNotCloseStream () throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); eofstream.read(); Assert.assertFalse(eofstream.isSelfClosed()); } @Test public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception { wrappedStream.returnOnRead(DATA_VALUE); assertThat(eofstream.read(), is(DATA_VALUE)); }
  • 32. Step 4: Separate the Tests @Test public void whenNotAtEOF_readDoesNotCloseStream () throws Exception { Mockito.when(watcher.eofDetected(Mockito.<InputStream>any())).thenReturn(Boolean.TRUE); Mockito.when(wrappedStream.read()).thenReturn(DATA_VALUE, EOF); eofstream.read(); Assert.assertFalse(eofstream.isSelfClosed()); } @Test public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception { wrappedStream.returnOnRead(DATA_VALUE); assertThat(eofstream.read(), is(DATA_VALUE)); }
  • 33. Step 4: Separate the Tests @Test public void whenNotAtEOF_readDoesNotCloseStream () throws Exception { wrappedStream.returnOnRead(DATA_VALUE); eofstream.read(); Assert.assertFalse(eofstream.isSelfClosed()); } @Test public void whenNotAtEOF_readReturnsNextByteFromWrappedStream() throws Exception { wrappedStream.returnOnRead(DATA_VALUE); assertThat(eofstream.read(), is(DATA_VALUE)); }
  • 34. @Test public void afterSuccessfulRead_haveOriginalWrappedStream() throws Exception { wrappedStream.returnOnRead(DATA_VALUE); eofstream.read(); assertThat(eofstream.getWrappedStream(), sameInstance((InputStream) wrappedStream)); } @Test public void whenNoData_readReturnsEOF() throws Exception { assertThat(eofstream.read(), is(EOF)); } @Test public void afterEofRead_streamIsNotSelfClosed() throws Exception { eofstream.read(); assertFalse(eofstream.isSelfClosed()); }
  • 35. @Test public void afterEofRead_wrappedStreamIsNull() throws Exception { eofstream.read(); assertThat(eofstream.getWrappedStream(), nullValue()); } @Test public void afterEofRead_wrappedStreamIsClosed() throws Exception { eofstream.read(); assertTrue(wrappedStream.isClosed()); } @Test public void afterEofRead_nextReadReturnsEOF() throws Exception { eofstream.read(); assertThat(eofstream.read(), is(EOF)); }
  • 37. Unit Tests are Executable Documentation  Keep the tests clean  Test one thing per test  Use descriptive names
  • 38. Q&A