2. Unit Testing is a practice where the smallest
testable parts of an application (units) are
individually and independently tested.
Unit Tests are developer tests.
It enables developers to do “Refactoring” and
helps in “Code Maintenance”
3. Test Driven Development (TDD) is a
Software development technique which
advocates to test the code that's to be written
before it is written.
Test Driven Development (TDD) is mostly
driven through Unit Tests
8. Design
/ Think
Failing
Test
Make
the test
pass
Refactor TDD
Write a Failing Test!
!
Write a very small amount of test
code. Only a few lines. Usually no
more than five lines. Run the tests
and watch the new test fail. The
test bar should turn red.
9. Design
/ Think
Failing
Test
Make
the test
pass
Refactor TDD!
Make The Test Pass!
!
Write a very small amount of
production code. Again, usually no
more than five lines of code. Don't
worry about design purity or
conceptual elegance. Sometimes
you can just hardcode the answer.
Run the tests and watch them pass
the test bar will turn green.
10. Design
/ Think
Failing
Test
Make
the test
pass
Refactor TDD!
Refactor!
!
Now that your tests are passing, you
can make changes without worrying
about breaking anything. Look at the
code you've written, and ask yourself
if you can improve it. After each little
refactoring, run the tests and make
sure they still pass.
12. Rule 1
You can’t write production code unless it makes a
failing unit test pass.
13. Rule 2
You can’t write any more of unit test that is
sufficient to fail, and not compiling is failing
14. Rule 3
You can’t write any more production code than
is sufficient to pass one failing unit test.
15. “But one should not first make the program
and then prove its correctness, because
then the requirement of providing the proof
would only increase the poor programmer's
burden. On the contrary: the programmer
should let correctness proof and program
grow hand in hand.”
!
The Humble Programmer, Edsger W. Dijkstra 1972
16. Test First vs Testing
✦ Think small, iteratively develop.
✦ More focus on the problem to be
solved.
✦ Immediate feedback of the code.
✦ No excuses for not testing.
17. @Test
public void shouldReturnTrueForSaturday(){
DeliveryDate deliveryDate = new DeliveryDate();
boolean result = deliveryDate.isWeekendOrHoliday();
assertTrue("Should be true for Saturday",result);
}
First Test - Should Return true for Saturday
public class DeliveryDate {
!
public boolean isWeekendOrHoliday() {
return false;
}
}
18. @Test
public void shouldReturnTrueForSaturday(){
DeliveryDate deliveryDate = new DeliveryDate();
boolean result = deliveryDate.isWeekendOrHoliday();
assertTrue("Should be true for Saturday",result);
}
First Test - Should Return true for Saturday
public class DeliveryDate {
!
public boolean isWeekendOrHoliday() {
return true;
}
}
19. @Test
public void shouldReturnTrueForSaturday(){
Calendar calendarInstance = getCalendarForDay(Calendar.SATURDAY);
DeliveryDate deliveryDate = new DeliveryDate(calendarInstance);
boolean result = deliveryDate.isWeekendOrHoliday();
assertTrue("Should be true for Saturday",result);
}
First Test - Should Return true for Saturday
public class DeliveryDate {
private Calendar calendar;
public DeliveryDate(Calendar calendar){
this.calendar = calendar;
}
!
public boolean isWeekendOrHoliday() {
if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY){
return true;
}
return false;
}
}
20. @Test
public void shouldReturnTrueForSunday(){
Calendar calendarInstance = getCalendarForDay(Calendar.SUNDAY);
DeliveryDate deliveryDate = new DeliveryDate(calendarInstance);
boolean result = deliveryDate.isWeekendOrHoliday();
assertTrue("Should be true for Sunday",result);
}
Second Test - Should Return true for Sunday
public class DeliveryDate {
private Calendar calendar;
public DeliveryDate(Calendar calendar){
this.calendar = calendar;
}
!
public boolean isWeekendOrHoliday() {
if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY ||
calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){
return true;
}
return false;
}
}
21. @Test
public void shouldReturnTrueIfPresentInHolidayList(){
Calendar calendarInstance = getCalendarForDay(Calendar.FRIDAY);
DeliveryDate deliveryDate = new DeliveryDate(calendarInstance);
boolean result = deliveryDate.isWeekendOrHoliday(asList(calendarInstance.getTime()));
assertTrue("Should be true for Holiday",result);
}
Third Test - Should Return true for Holidays
public class DeliveryDate {
private Calendar calendar;
public DeliveryDate(Calendar calendar){
this.calendar = calendar;
}
!
public boolean isWeekendOrHoliday(List<Date> holidayList) {
if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY ||
calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ||
holidayList.contains(calendar.getTime())){
return true;
}
return false;
}
}
22. @Test
public void shouldReturnFalseIfNotPresentInHolidayListAndNotAWeekend(){
Calendar calendarInstance = getCalendarForDay(Calendar.FRIDAY);
DeliveryDate deliveryDate = new DeliveryDate(calendarInstance);
boolean result = deliveryDate.isWeekendOrHoliday(new ArrayList<Date>());
assertFalse("Should be false for Friday",result);
}
One More to confirm that it’s working.
public class DeliveryDate {
private Calendar calendar;
public DeliveryDate(Calendar calendar){
this.calendar = calendar;
}
!
public boolean isWeekendOrHoliday(List<Date> holidayList) {
if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY ||
calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ||
holidayList.contains(calendar.getTime())){
return true;
}
return false;
}
}
24. Unit Test should be
Fast
Independent
Repeatable
Self-Validating
Timely
25. Test Doubles
Mocks are pre-programmed with
expectations which form a specification
of the calls they are expected to receive.
26. Test Doubles
Stubs provide canned answers to calls
made during the test, usually not
responding at all to anything outside
what’s programmed in for the test.
27. Test Doubles
Spies are stubs that also record some
information based on how they were
called.
28. Test Doubles
✤ Dummy objects that are passed
around but never actually used.
!
✤ Fake objects actually have working
implementation (simpler)
29. class Washer
def wash(clothes,detergent)
if(isInWorkingCondition? and power.isOn?){
while(!waterIsFull){
inlet.fillWater();
}
100.times do base.spin();
outlet.dispense();
set clothes.washed = true
return clothes unless hasException?
}
throw DirtyClothesException!
end
def isInWorkingCondition?
// Does too many checks to make sure that
end
end
class WasherTest
def wash_returnTrueOnSuccessfulWash
//Mocking External systems
when(MockPower.isOn?).thenReturn(true)
//Stubbing - Overriding Behaviours
def fillWater(){
set waterIsFull = true if 100.times.called
}
//Spying - Internal behaviours
when(isInWorkingCondition?()).then(true)
washedClothes = Washer.wash(dirtyClothes,some_detergent)
assert washedClothes.getStatus == CLEAN
end
end
A quick walkthrough of Test Doubles