30
Introduction to Test Driven Development Prasanna N Venkatesan

Tdd

Embed Size (px)

Citation preview

Page 1: Tdd

Introduction to !

Test Driven Development

Prasanna N Venkatesan

Page 2: Tdd

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”

Page 3: Tdd

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

Page 4: Tdd

Not a Silver Bullet

Page 5: Tdd

“TDD doesn't drive good design. TDD gives you immediate feedback about what is likely to be a bad design.”

!

- Kent Beck

Page 6: Tdd

Design / Think

Failing Test

Make the test pass

Refactor TDD

Page 7: Tdd

Design / Think

Failing Test

Make the test

pass

Refactor TDD

Design / Think!

!

Figure out what test will best move your code towards completion. (Take as much time as you need. This is the hardest step for beginners.)

Page 8: Tdd

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.

Page 9: Tdd

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.

Page 10: Tdd

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.

Page 11: Tdd

3 Rules of TDD

Page 12: Tdd

Rule 1

You can’t write production code unless it makes a failing unit test pass.

Page 13: Tdd

Rule 2

You can’t write any more of unit test that is sufficient to fail, and not compiling is failing

Page 14: Tdd

Rule 3

You can’t write any more production code than is sufficient to pass one failing unit test.

Page 15: Tdd

“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

Page 16: Tdd

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.

Page 17: Tdd

@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; } }

Page 18: Tdd

@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; } }

Page 19: Tdd

@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; } }

Page 20: Tdd

@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; } }

Page 21: Tdd

@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; } }

Page 22: Tdd

@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; } }

Page 23: Tdd

@Test public void shouldReturnFalseIfNotPresentInHolidayListAndNotAWeekend(){ Calendar calendarInstance = getCalendarForDay(Calendar.FRIDAY); DeliveryDate deliveryDate = new DeliveryDate(calendarInstance); boolean result = deliveryDate.isWeekendOrHoliday(null); // No idea ?? }

What if ??

Page 24: Tdd

Unit Test should be

Fast Independent Repeatable Self-Validating Timely

Page 25: Tdd

Test Doubles

Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive.

Page 26: Tdd

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.

Page 27: Tdd

Test Doubles

Spies are stubs that also record some information based on how they were called.

Page 28: Tdd

Test Doubles

✤ Dummy objects that are passed around but never actually used. !

✤ Fake objects actually have working implementation (simpler)

Page 29: Tdd

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

Page 30: Tdd

** END **