O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

XP through TDD

805 visualizações

Publicada em

A short talk we gave with Marc Planaguma and Jacob Cañadas at Telefonica I+D, to help teams adopt XP starting with TDD now!

Publicada em: Tecnologia
  • Entre para ver os comentários

  • Seja a primeira pessoa a gostar disto

XP through TDD

  1. 1. eXtreme Programming Introduction TELEFÓNICA I+D Date: © 2010 Telefónica Investigación y Desarrollo, S.A. Unipersonal With Test-Driven Development Jacob Cañadas <jcr@tid.es> Marc Planagumà <mpv@tid.es> Mauricio Cappella <mauricio@pollenizer.com>
  2. 2. <ul><li>01 XP with TDD </li></ul><ul><ul><ul><li>02 TDD = Test + driven development </li></ul></ul></ul><ul><li>03 V-model for testing </li></ul><ul><ul><ul><li>04 Driven Development, why? </li></ul></ul></ul><ul><ul><ul><li>05 Steer your project with tests (V-model for TDD) </li></ul></ul></ul><ul><ul><ul><li>06 TDD is easy and optimal </li></ul></ul></ul><ul><ul><ul><li>07 TDD is the easier way to implement XP and Agile </li></ul></ul></ul><ul><ul><ul><li>08 Examples </li></ul></ul></ul><ul><ul><ul><li>09 Questions </li></ul></ul></ul>Part 1: overview (1h)
  3. 3. <ul><ul><ul><li>01 Reference architecture. </li></ul></ul></ul><ul><ul><ul><li>02 Web frontend and integration of 3rd party services. </li></ul></ul></ul><ul><ul><ul><li>03 Mobile applications and services. </li></ul></ul></ul><ul><ul><ul><li>04 Provisioning framework. </li></ul></ul></ul><ul><ul><ul><li>05 (your example or question here) </li></ul></ul></ul>Part 2: examples (1h)
  4. 4. eXtrem Programing Practices:  TDD is core 01
  5. 5. eXtrem Programing Practices:  TDD is core 01 TDD
  6. 6. Test-Driven Development is: Test Drive Development 02
  7. 7. <ul><li>  </li></ul>03
  8. 8. <ul><li>  </li></ul>
  9. 9. <ul><li>  </li></ul>Ex: Control access to building Check user credentials, if ok store date
  10. 10. <ul><li>  </li></ul>Card Reader DataBase
  11. 11. <ul><li>  </li></ul>OPenPCD Mysql
  12. 12. <ul><li>  </li></ul>
  13. 13. <ul><li>  func storeUserAccess(userId,accessDate) : </li></ul><ul><li>mysql.query(“insert into user (id,date) values(userId,accessDate)”) </li></ul><ul><li>func readUserAccess() : </li></ul><ul><li> userId,accessDate=openPcd.getLastAccess() </li></ul><ul><li>return userId,accessDate </li></ul>
  14. 14. <ul><li>func accessControlSystem() : </li></ul><ul><li>userId,accessDate = readUserAccess() </li></ul><ul><li>if(userAllowed(userId)) </li></ul><ul><li> print( userId enter building on accessDate) </li></ul><ul><li>storeUserAccess(userId,accessDate) </li></ul><ul><li>return true </li></ul><ul><li>else </li></ul><ul><li>print( userId can’t enter) </li></ul><ul><li>return false </li></ul>
  15. 15. <ul><li>  </li></ul>
  16. 16. Uni Test <ul><li>Method level </li></ul><ul><li>Test boundaries values </li></ul><ul><li>Test extreme values </li></ul><ul><li>Without dependences </li></ul><ul><li>If (x>=2) </li></ul><ul><ul><li>return(x) </li></ul></ul><ul><li>else </li></ul><ul><li>return(2x) </li></ul>
  17. 17. <ul><li>  func storeUserAccess(userId,accessDate) : </li></ul><ul><li>mysql.query(“insert into user (id,date) values(userId,accessDate)”) </li></ul><ul><li>  func storeUserAccessTest() : </li></ul><ul><ul><li>storeUserAccess(‘user123’,’06/04/2010’) </li></ul></ul><ul><ul><li>accessDate = readLastUserAccess(‘user123’) </li></ul></ul><ul><ul><li>assertTrue (accessDate = ‘06/04/2010‘) </li></ul></ul>
  18. 18. <ul><li>func accessControlSystem() : </li></ul><ul><li>userId,accessDate = readUserAccess() </li></ul><ul><li>if(userAllowed(userId)) </li></ul><ul><li> print( userId enter building on accessDate) </li></ul><ul><li>storeUserAccess(userId,accessDate) </li></ul><ul><li>return true </li></ul><ul><li>else </li></ul><ul><li>print( userId can’t enter) </li></ul><ul><li>return false </li></ul>
  19. 19. <ul><li>  func storeUserAccessMock(userId,accessDate) : </li></ul><ul><ul><li>//Nothing to do </li></ul></ul><ul><li>func readUserAccessMock() : </li></ul><ul><li>if(firstTime) </li></ul><ul><li>return ‘userOk’,’06/04/2010’ </li></ul><ul><li>else </li></ul><ul><li>return ‘userKo’,’06/04/2010’ </li></ul>
  20. 20. <ul><li>func accessControlSystem() : </li></ul><ul><li>userId,accessDate = readUserAccessMock() </li></ul><ul><li>if(userAllowed(userId)) </li></ul><ul><li> print( userId enter building on accessDate) </li></ul><ul><li>storeUserAccessMock(userId,accessDate) </li></ul><ul><li>return true </li></ul><ul><li>else </li></ul><ul><li>print( userId can’t enter) </li></ul><ul><li>return false </li></ul>
  21. 21. <ul><li>  func accessControlSystemTest() : </li></ul><ul><li>result =accessControlSystem() </li></ul><ul><li>AssertTrue(result) </li></ul><ul><li>result =accessControlSystem() </li></ul><ul><li>AssertFalse(result) </li></ul>
  22. 22. <ul><li>  </li></ul>
  23. 23. <ul><li>  func accessControlSystemTestIt() : </li></ul><ul><li>result =accessControlSystem() </li></ul><ul><li>AssertTrue(result) </li></ul><ul><li>result =accessControlSystem() </li></ul><ul><li>AssertFalse(result) </li></ul>
  24. 24. <ul><li>  </li></ul>
  25. 25. <ul><li>  </li></ul>
  26. 26. Driven Development: where should we go? 04
  27. 27. Only doing Test is NOT TDD 05
  28. 28. 1. Describe intent with tests. 2. Use the tests to validate our solution iteratively 3. Do the simplest thing that could possibly work.
  29. 29. Clear user stories and backlog Contract <ul><li>Check the acceptance criteria </li></ul><ul><li>Doc Based </li></ul><ul><li>Script Based </li></ul><ul><li>User interaction </li></ul>
  30. 30. <ul><li>Simple design and constant review about: </li></ul><ul><li>Tecnologines </li></ul><ul><li>Architecture </li></ul><ul><li>Ensure you are using the right tools. </li></ul><ul><li>Deployment </li></ul><ul><li>Connectivity </li></ul><ul><li>Performance and SLA </li></ul>
  31. 31. <ul><li>Correct orchestration : </li></ul><ul><li>Interchangeable components. </li></ul><ul><li>Code simultaneously. </li></ul><ul><li>Moularization. </li></ul><ul><li>Define good components contracts and interfaces. </li></ul><ul><li>Protocol </li></ul><ul><li>Interfaces </li></ul><ul><li>API’s </li></ul>
  32. 32. <ul><li>Get better Code: </li></ul><ul><li>Atomic functions </li></ul><ul><li>No bugs </li></ul><ul><li>Simple code </li></ul><ul><li>Test is documnetation. </li></ul><ul><li>Clear goals minimum effort: </li></ul><ul><li>Paremeters </li></ul><ul><li>pre & post conditions </li></ul>
  33. 34. TDD is easy and optimal. 06 Create Time Create Team Create effectiveness
  34. 35. TDD is easy and optimal. Use tests to:  <ul><li>Define and mockup integration interfaces. </li></ul><ul><li>Make clear how your app works. </li></ul><ul><li>Show how your components or libraries may be used </li></ul><ul><li>Document what do you expect from 3rd party tools, libraries and services and check compatibility </li></ul><ul><li>Evaluate implementation alternatives </li></ul><ul><li>Demo your user stories </li></ul><ul><li>Refactor your code without breaking something </li></ul>06
  35. 36. TDD is easy, and optimal replaces more expensive practices <ul><li>Do you write a &quot;main&quot; to try a function? make it readable, keep it, and it's TDD (and your documentation too!) </li></ul><ul><li>Tests are better than Word documents and UML and flow charts: </li></ul><ul><ul><li>just can run them to know if they are accurate </li></ul></ul><ul><ul><li>they change with your code and are where you need them. </li></ul></ul><ul><li>Avoid being blocked by integration problems. </li></ul><ul><li>Save expensive bug finding. </li></ul><ul><li>Reduce risks due to long build and release cycles. </li></ul>06
  36. 37. TDD, the easier way to XP and Agile <ul><li>Acceptance criteria : Clear user stories and backlog. Customer tests. </li></ul><ul><li>Acceptance test : do exactly what the customer asks, no less, no more (the simplest thing that may possibly work) </li></ul><ul><li>Continuous testing: bug free, easy to deploy (CI) </li></ul><ul><li>Everybody runs and tests everything: Whole team, Collective Ownership and Coding Standard. </li></ul><ul><li>TDD makes each developer also an architect and clearly documents her reasoning and decisions: Simple design (KISS) </li></ul><ul><li>Refactor Without TDD = disaster </li></ul>07
  37. 39. Example User Story 08 As a: Mobile phone user I want to: receive a list of 3 places to eat at less than 30min from where me and the contacts I select are So that: I can propose my contacts to meet there
  38. 40. Use Acceptance Tests to validate UserStory 08 Test 0: create wireframes showing the sequence of screens the user views and validate them with the PO and user Test 0.1: is feasible? write tests to check you can always get the information to generate the right screens in each scenario <ul><ul><li>allContacts= phoneDriver.getContacts() </li></ul></ul><ul><ul><li>selectedContacts= ui.selectFromList(allContacts) </li></ul></ul><ul><ul><li>result= nearUsApp.find(selectedContacts,&quot;placeToEat&quot;,30m) </li></ul></ul><ul><ul><li>if result.length<1 { showMsg(&quot;ERROR: no places found&quot;) } </li></ul></ul><ul><ul><li>else { m= new List(); foreach place in result {  </li></ul></ul><ul><ul><li>   m.add(place.desc); foreach path in place.contactPath { </li></ul></ul><ul><ul><li>       m.add(&quot; >&quot;+path.contact+&quot;: &quot;+path.transport) </li></ul></ul><ul><ul><li>  }} </li></ul></ul><ul><ul><li>  ui.showList(m) </li></ul></ul><ul><ul><li>} </li></ul></ul>(most of the mentioned application classes and methods have to be written yet!) BUT now you now exactly what the PO wants and you need!
  39. 41. Use Acceptance Test to drive Behavior (more on how to do this in your projects in part 2) 08 Test 0.2: implement what you need as stubs and pass the tests for all thinkable scenarios (you wrote the top layer of your app as) ... result= nearUsApp.find(selectedContacts,&quot;placeToEat&quot;,30m) if result.length<1 { showMsg(&quot;ERROR: no places found&quot;) } else { ...  ui.showList(m) } (now you can use mock objects like) ... phoneDriver.getContacts(){ return [&quot;Juan35m&quot;,&quot;Pedro20m&quot;]} ui.selectFromList(l) { return l[0] } nearUsApp.find(contacts, kindOfPlace, timeToGetThereMax) {   if (contacts[0]==&quot;Juan35m&quot;) { return [] }   return [...3 lugares...] //you must try none, 3 near, etc. } And TEST that running the application code you already wrote with different inputs (selecting different contacts) gives the expected results (no places to meet Juan35m in less tha 30min, etc.)
  40. 43. Use System Tests to drive Architecture (more on how to do this in your projects in part 2) 08 How do you get all the information the past tests show you need? How do you transport it from one place to another? Are the tools you intend to use available in the all target environments? How reliable are this tools? How fast? Can you accommodate more than one alternative? Test: write tests connecting to all the needed data sources and services, check your app understands all the results and errors Test: deploy simple stress test applications using each of the tools you may use to the target environments Test: stress test the architecture implement all the communications and data handling required by the components, using stubs only to simulate errors and ensuring you return data for all the relevant scenarios So: the team is sure the tools work, the application can be deployed, what are the performance limits, etc.
  41. 45. Use Integration Tests to drive Design (more on how to do this in your projects in part 2) 08 Test: write tests to define which requests and responses must support each component of your application Use simple drivers for the requests and stubs to return examples for all the possible responses So:   the team can work simultaneously in various components without integration problems the contracts and dependencies for the components are clear you can refactor anything inside as long as you respect the interface (pass the tests)
  42. 47. Use Unit Tests to find the best implementation (more on how to do this in your projects in part 2) 08 Test: write tests to understand what do you need of each class and method Test: write tests to show what inputs and outputs are supported So:   anyone can use, extend or modify any class or component without breaking something your code is free of defects you write only what you need in some cases you can have more than one implementation (e.g. critical algorithms, drivers, transport/communication protocols)
  43. 48. QUESTIONS?
  44. 49. Example: withdraw cash from an ATM 03
  45. 50. Unit test each component separately unit test unit test unit test 03
  46. 51. Integration test interaction of two or more components integration test integration test 03
  47. 52. System test usability, load, connectivity, deployment, etc . system test 03
  48. 53. Example: Web +integration of 3p services (GiffGaff) 03
  49. 54. Example: Web +integration of 3p services (GiffGaff) 03 ManInTheMiddle (developers) Selenium-IDE (developers) ManInTheMiddle (developers)
  50. 55. Example: Mobile +integration of 3p services (Walkopedia) 03 curl (developers)