Test driven development


Published on

This presentation is simply for motivating developers towards test automation and test-driven development. It discusses lightly unit testing, mocking and integration testing, too.

Published in: Technology
1 Comment
  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Test driven development

  1. 1. Test-Driven Development (TDD) Sharafat Ibn Mollah Mosharraf Software Engineer, Therap (BD) Ltd. sharafat@therapservices.net
  2. 2. Overview ● The need for test automation ● Writing test-first code ● Unit Test Frameworks ● Mocking Frameworks ● Integration Testing ● Continuous Integration ToolsTest-Driven Development (TDD) 2 / 29
  3. 3. The Need for Test AutomationTest-Driven Development (TDD) 3 / 29
  4. 4. Traditional Programming Practice - 1 ● We code, build, deploy to app server and manually test whether our code works. ● We repeat the same process until were affirmed that our code works. ● If code building takes 1 minute, server restarting takes 2 minutes, logging in and browsing to the desired page to test the code takes 1 minute, then one round of testing takes a total of 4 minutes. ● If 10 rounds are needed to finally make the code work, total time wasted is 40 minutes. ● If testing could be automated by bypassing these lengthy processes, then this 40 minutes could be saved.Test-Driven Development (TDD) 4 / 29
  5. 5. Traditional Programming Practice - 2 returns ACTIVE, uses1 List of all users of an application LOCKED, DISABLED users List of LOCKED users to reset uses but gets ALL users returned2 their password instead of only LOCKED users Naive coder changes3 to return only LOCKED users. consequence (2) works awesome, but now (1) doesnt work as expected. However, the naive coder didnt even know feature (1) exists, so, the new bug in (1) gets overlooked until customer complaints. lesson learned Dont trust coders!! Whenever a new feature is implemented, test the whole system again. R u crazy?? There are hundreds solution of features in the app!!! Automate the testing process :)
  6. 6. Okay, understood. After writing code, we need to write test codes, too. WRONG!!!We need to write test code before writing actual code. Why on earth is that???Test-Driven Development (TDD) 6 / 29
  7. 7. Writing Test Code After Writing Actual Code is Difficult Before we learn why, lets take a look at how a test code can be writtenTest-Driven Development (TDD) 7 / 29
  8. 8. Writing Naive Test Code Actual code: Test code:Test-Driven Development (TDD) 8 / 29
  9. 9. Writing Test Code After Actual Code Becomes Difficult - An Example Actual (pseudo)code: The test code should do something like the following: 1. Add a few users including ACTIVE, LOCKED & DISABLED to database. 2. Call the actual code where the user list is retrieved. 3. Check whether all the users added above have been returned. But we cant single-out the actual code where user list is retrieved; that task is buried under the listUsers() method which returns nothing!Test-Driven Development (TDD) 9 / 29
  10. 10. Writing Testable Code 1. Write the test code first:Test-Driven Development (TDD) 10 / 29
  11. 11. Writing Testable Code... 2. Make sure your test code fails when run. Huh! I havent implemented the code yet! The test code will obviously fail!! Wrong again!! :P Quite interestingly, your test code might pass before youve written your actual code, which indicates your test code itself is incorrectly written and needs to be tested... :PTest-Driven Development (TDD) 11 / 29
  12. 12. Writing Testable Code... 3. Now write the actual code in the way expected by the test code: 4. Run the test. If the test passes, move on to the next step (step 5). If the test fails, find out the bug in your actual code and fix it. Run the test again until it passes. 5. Write some more test code if you have other codes which can be tested. Repeat steps 1 to 4 for those code. 6. Finish off the rest of the code: (see next slide)Test-Driven Development (TDD) 12 / 29
  13. 13. Writing Testable Code... Code Coverage (33.33%)Test-Driven Development (TDD) 13 / 29
  14. 14. Added Bonus of TDD ● Code conforms to good software design principles: ■ Low coupling ■ High cohesion ● Test code becomes the documentation and usage example of the written application/API ■ However, you need to make sure you write the test code well, following good practices, standards and patterns.Test-Driven Development (TDD) 14 / 29
  15. 15. Unit Testing Frameworks ● The previous -based test code is not very appealing as the test program fails ■ at the first assertion failure line, skipping the evaluation of the rest of the assertions ■ with simply an "assertion failed" message without any clue about what the actual value of something was ● We want to ■ check all assertions and figure out which specific ones fails ■ compare the actual value to the expected oneTest-Driven Development (TDD) 15 / 29
  16. 16. Unit Testing Frameworks... ● Several frameworks have been developed for the aforementioned purposes: ■ xUnit (JUnit, PHPUnit, NUnit, DBUnit etc.) ■ TestNG ● And a lot more... ● The above test code written in JUnit would look like the following:Test-Driven Development (TDD) 16 / 29
  17. 17. Unit Testing Frameworks...Test-Driven Development (TDD) 17 / 29
  18. 18. Mocking ● Unit testing is for testing an independent unit of code. ● Unit testing assumes the code to be tested is independent of any other code. ● However, in the previous example, the code to be tested ( ) is dependent on database. ● To remove the dependency, the actual object (database in our example) is replaced with a fake object, known as a mock object.Test-Driven Development (TDD) 18 / 29
  19. 19. Naive Approach for Mocking Actual Code:Test-Driven Development (TDD) 19 / 29
  20. 20. Naive Approach for Mocking... Mock Connection Implementation:Test-Driven Development (TDD) 20 / 29
  21. 21. Naive Approach for Mocking... Test Code:Test-Driven Development (TDD) 21 / 29
  22. 22. Mocking Frameworks ● To ease the tedious task of creating mock objects, several mocking frameworks have been developed, the most populars among which are (Java-only mentioned here): ■ EasyMock, PowerMock ■ Mockito ● Using Mockito would save you from writing the MockConnection class above and make the aforementioned test code look like the following: (see next slide)Test-Driven Development (TDD) 22 / 29
  23. 23. Mocking Frameworks... Test Code:Test-Driven Development (TDD) 23 / 29
  24. 24. Unit Testing is Not Enough for Test Automation ● If the previous test for passes, does that guarantee your application works? No. ● The independence nature of code unit is the culprit. ● The previous test passes with a mock connection. But when real database will be used, there is a chance of things not going well altogether. (Can you come up with a few ideas why?)Test-Driven Development (TDD) 24 / 29
  25. 25. Unit vs Integration Testing - Analogy ● When small units are tested independent of one another, its called unit testing. ● When the interaction among components are tested, its called integration testing. ● Suppose youre building a car and youve unit tested and confirmed that your tires work as expected, engine works as expected, speedometer works as expected - all parts independent of one another. Now, when you build a car whose wheels are 215/65/15*, but you fit 205/55/15 tires to it, if you run an integration test, youll find out that driving the car at 55 MPH causes the speedometer to read 60 MPH (as the actual tire circumference is 8.2% shorter than the expected one), which is an error. Integration tests are used to identify such error. * 215/65/15 is nominal width of tire (in mm) / ratio of height to width (aspect ratio) / rim diameter codeTest-Driven Development (TDD) 25 / 29
  26. 26. Continuous Integration Tools ● There is no syntactic difference between unit and integration testing; the difference is rather semantic. ● As the environment setup for integration test is complex and running the tests take much time, integration testing is usually performed in a dedicated server. ● Developers commit their code to the server and before the commits get merged, all the integration tests are run to make sure the commits dont cause other parts of the application to break. ● Developers get notified by the CI server automatically of the result of the tests. ● Some most popular CI tools include (only Java-specifics are mentioned here): ■ CruiseControl ■ HudsonTest-Driven Development (TDD) 26 / 29
  27. 27. Principles of Continuous Integration ● Maintain a Code Repository ● Automate the build ● Make the build self-testing ● Everyone commits to the baseline ● Every commit (to baseline) should be built ● Keep the build fast ● Test in a clone of production environment ● Make it easy to get the latest deliverables ● Everyone can see the results of the latest builds ● Automate deploymentTest-Driven Development (TDD) 27 / 29
  28. 28. Further Reading Test Driven Development: By Example Kent Beck Addison-Wesley (2002) xUnit Test Patterns: Refactoring Test Code Gerard Meszaros Addison-Wesley (2007) Clean Code: A Handbook of Agile Software Craftsmanship Robert C. Martin Prentice Hall (2008)Test-Driven Development (TDD) 28 / 29
  29. 29. Further Reading... Continuous Integration: Improving Software Quality and Reducing Risk Paul M. Duvall Addison-Wesley (2007) Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation (Addison-Wesley Signature Series (Fowler)) Jez Humble Addison-Wesley (2010) Unit tests lie: thats why I love them (Blog Article [2011]) Arialdo Martini This article explains quite well why unit testing is not sufficient and integration testing is needed.Test-Driven Development (TDD) 29 / 29