Programmer testing

1,507
-1

Published on

This is a slide set with some information about programmer testing. It includes test doubles, mockit and junit.
Visit http://jpereira.eu/2011/12/03/programming-testing/ for more information. If you want to download these slides, please contact me (find my contacts on my blog)

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,507
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
5
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Programmer testing

  1. 1. Introduction to programmertesting with JUnit, Mockito et. al. João Pereira joaomiguel.pereira@gmail.com http://jpereira.eu October 2011
  2. 2. Programmer testing • What is a Test? What is a Test? • Overview of Agile testing quadrants • What is Test Driven Development h i i l • Overview of unit testing and JUnit • Introduction to Test Doubles and Mockito • Measure code coverage with Cobertura Measure code coverage with Cobertura • ReferencesJoão Pereira, Sep. 2011  2
  3. 3. Programmer testing • What is a Test? What is a Test? • Overview of Agile testing quadrants • What is Test Driven Development p • Overview of unit testing and JUnit • Introduction to Test Doubles and Mockito • Measure code coverage with Cobertura • ReferencesJoão Pereira, Sep. 2011  3
  4. 4. What is a test ? What is aJoão Pereira, Sep. 2011  4
  5. 5. What is a Test? • Everybody knows what a test is. Everybody knows what a test is. – Certify that whatever you do, your system will  always behave as expected – Your system, also known as System Under Test, or  SUT for short, can be: • An Human Resources application li i • Some layer of a Human Resources application • One module for a Human Resources application One module for a Human Resources application • One object that makes your Human Resources  application workJoão Pereira, Sep. 2011  5
  6. 6. Programmer testing • What is a Test? • Overview of Agile testing quadrants • What is Test Driven Development What is Test Driven Development • Overview of unit testing and JUnit • Introduction to Test Doubles and Mockito • Measure code coverage with Cobertura • ReferencesJoão Pereira, Sep. 2011  6
  7. 7. Agile testing Quadrants Business Facing Tests F ti lT t •Functional Tests •Exploratory Tests Exploratory Tests Test that critique t •Examples •Scenarios •UAT (User Acceptance  team •Prototypes p •Mock‐ups testing) ports the t •Simulations / •Alpha/Beta releases Q2 Q3 t that supp the produc Q1 Q4 •Unit tests •Performance & Load  •Component test testing ct S i T i Test •Security Testing •“ility” Testing Technology Facing TestsJoão Pereira, Sep. 2011  7
  8. 8. Purpose of tests • Business facing tests helps drive Business facing tests helps drive  development, through constant feedback from  the usage of the product (or parts of the  the usage of the product (or parts of the product)  by the customer team. • Technology facing tests helps the team  to decide the most appropriate design and  architecture.João Pereira, Sep. 2011  8
  9. 9. Purpose of tests • Test that critique the product helps the Test that critique the product helps the  organization to discover improvements to  implement into the product. implement into the product • Test that supports the team helps the  team to learn HOW to develop WHAT the  customer wants.João Pereira, Sep. 2011  9
  10. 10. Tests that supports the team • Are the decisions about design and Are the decisions about design and  architecture the most appropriate? • Does the system behave correctly? Does the system behave correctly? • Does the user interface meet the expectations  of users? (GUI mockups, wireframes, etc) f ? (GUI k i f )João Pereira, Sep. 2011  10
  11. 11. Business facing tests • Is what the customer told us really what the Is what the customer told us, really what the  customer needs? • Are we implementing what the customer Are we implementing what the customer  need?  • A Are we delivering the business value required  d li i h b i l i d by the client?João Pereira, Sep. 2011  11
  12. 12. Test that critique the product • Are there any improvements to make to the Are there any improvements to make to the  product? • It’s the product better that the competition? It s the product better that the competition? • Is the interface with the users working well?João Pereira, Sep. 2011  12
  13. 13. Technology facing tests • Is the system fast enough? And Secure? Is the system fast enough? And Secure? • It’s reliable and robust? • Are the non‐functional requirements being  h f i l i b i met? (maintainability, modularity, reusability,  testability, …) bili ) • Do we have the right design for extensibility? • Is our code testable? And reusable? João Pereira, Sep. 2011  13
  14. 14. Agile testing Quadrants Feedback Business Facing Tests Tes st that critiqu ts the team Q Q Q2 Q3 Test Results Test Results Test that support ue the produ Q1 Q4 uct Technology Facing Tests FeedbackJoão Pereira, Sep. 2011  14
  15. 15. Agile testing Quadrants Feedback Business Facing Tests Tes st that critiqu ts the team •New requirements •Missing requirements Improvements •Improvements Q2 Q3 Q Q Test that support ue the produ •Design Improvements •Architecture improvements Q1 Q4 uct Technology Facing Tests FeedbackJoão Pereira, Sep. 2011  15
  16. 16. How does it helps? • Agile testing Quadrants help the team to answer  g e test g Quad a ts e p t e tea to a s e questions like:  – Are we using unit and component tests to help us find  the right design for our application? – Do we have an automated build process that runs our  automated unit tests for quick feedback? automated unit tests for quick feedback? – Do our business‐facing tests help us deliver a product  that matches customers’ expectations? – Are we capturing the right examples of desired system  behavior? Do we need more? Are we basing our tests  on these examples? on these examples?João Pereira, Sep. 2011  16
  17. 17. How does it helps? • More questions: More questions:  – Do we show prototypes of UIs and reports to the  users before we start coding them?  – Do we budget enough time for exploratory  testing? How do we tackle usability testing? Are  we involving our customers enough? we involving our customers enough? – Do we consider technological requirements such  as performance and security early enough in the  as performance and security early enough in the development cycle? Do we have the right tools to  do “ility” testing?João Pereira, Sep. 2011  17
  18. 18. Programmer testing • What is a Test? • Overview of Agile testing quadrants • What is Test Driven Development p • Overview of unit testing and JUnit • Introduction to Test Doubles and Mockito • Measure code coverage with Cobertura • ReferencesJoão Pereira, Sep. 2011  18
  19. 19. TDD in Agile testing Quadrants Business Facing Tests F ti lT t •Functional Tests •Exploratory Tests Exploratory Tests Test that critique t ? ? •Examples •Scenarios •UAT (User Acceptance  team •Prototypes p •Mock‐ups testing) ports the t •Simulations / •Alpha/Beta releases Q2 Q3 t that supp the produc Q1 Q4 •Unit tests •Performance & Load  ? •Component test testing ? ct S i T i Test •Security Testing •“ility” Testing Technology Facing TestsJoão Pereira, Sep. 2011  19
  20. 20. Agile testing Quadrants Business Facing Tests F ti lT t •Functional Tests •Exploratory Tests Exploratory Tests Test that critique t •Examples •Scenarios •UAT (User Acceptance  team •Prototypes p •Mock‐ups testing) ports the t •Simulations / •Alpha/Beta releases Q2 Q3 t that supp the produc Q1 Q4 •Performance & Load  testing ct S i T i Test •Security Testing •“ility” Testing Technology Facing TestsJoão Pereira, Sep. 2011  20
  21. 21. What is TDD? A way to approach how we  develop software that is  d l ft th t i maintainable, testable, reusable  maintainable, testable, reusable and consistently deliver the  expected business value.  db lJoão Pereira, Sep. 2011  21
  22. 22. What is TDD? • Makes you constantly think about what is Makes you constantly think about what is  expected the software to do. • Drives and evolves your design and Drives and evolves your design and  architecture through constant feedback. • Gi Gives you the confidence to change and  h fid h d improve your code. • As soon you master the technique, the faster  and better you developJoão Pereira, Sep. 2011  22
  23. 23. What is TDD? • A core practice of any agile methodology A core practice of any agile methodology • Inspired by the test‐first programming concept  of eXtreme of eXtreme Programming • Core concept states that designers write  automated unit tests upfront and run them  d i f d h throughout the project • Introduced by Kent Beck in 1999João Pereira, Sep. 2011  23
  24. 24. What is TDD? Write the test Refactoring Run the test Run the test Yes Needs  Green G Green or  refactoring? Red? Red Commit Implement/fix SUT Go to the next  featureJoão Pereira, Sep. 2011  24
  25. 25. What is TDD? • Make more sense with various processes Make more sense with various processes ,  techniques and tools: – Build process Build process – Source Code Control System – Continuous Integration Continuous Integration – Information radiatorsJoão Pereira, Sep. 2011  25
  26. 26. TDD in context Check‐in code Information Radiator Source Code Control  System •Build GREEN. Last commit at  12:44 by jsousa •Build RED. Last commit at  13:40 by jpereira •Build GREEN Last commit at Build GREEN. Last commit at Team 14:54 by jpereira •Build GREEN. Last commit at  15:11 by jsousa •Build GREEN. Last commit at  ts Run test Continuous  18:59 by jsousa 18 9 b j Build Integration  •Build RED. Last commit at  System 09:44 by jpereira Feedback Build/test information / João Pereira, Sep. 2011  26
  27. 27. Some tools, for your reference tools Popular Source Code Control System in Java World Popular Continuous Integration System in Java WorldJoão Pereira, Sep. 2011  27
  28. 28. Programmer testing • What is a Test? • Overview of Agile testing quadrants • What is Test Driven Development • Overview of unit testing and JUnit • Introduction to Test Doubles and Mockito • Measure code coverage with Cobertura • ReferencesJoão Pereira, Sep. 2011  28
  29. 29. JUnit in Agile testing Quadrants Business Facing Tests F ti lT t •Functional Tests •Exploratory Tests Exploratory Tests Test that critique t ? ? •Examples •Scenarios •UAT (User Acceptance  team •Prototypes p •Mock‐ups testing) ports the t •Simulations / •Alpha/Beta releases Q2 Q3 t that supp the produc Q1 Q4 •Unit tests •Performance & Load  ? •Component test testing ? ct S i T i Test •Security Testing •“ility” Testing Technology Facing TestsJoão Pereira, Sep. 2011  29
  30. 30. JUnit in Agile testing Quadrants Business Facing Tests F ti lT t •Functional Tests •Exploratory Tests Exploratory Tests Test that critique t •Examples •Scenarios •UAT (User Acceptance  team •Prototypes p •Mock‐ups testing) ports the t •Simulations / •Alpha/Beta releases Q2 Q3 t that supp the produc Q1 Q4 •Performance & Load  •Unit testing testing •Component test Component test ct S i T i Test •Security Testing •“ility” Testing Technology Facing TestsJoão Pereira, Sep. 2011  30
  31. 31. What is Unit Testing Wh i U i T i ?João Pereira, Sep. 2011  31
  32. 32. What is Unit Testing An attitude of developers that  A i d fd l h strive for high quality code! strive for high quality code!João Pereira, Sep. 2011  32
  33. 33. What is Unit Testing • Small pieces of code are tested in isolation Small pieces of code are tested in isolation from the rest of the system • Generally don’t care about the interaction Generally, don t care about the interaction  with other classes Don t Test Don’t TestJoão Pereira, Sep. 2011  33
  34. 34. What is Unit Testing • Helps you to think about simple designs with Helps you to think about simple designs with  some OO Principles and best practice in mind: Encapsulate what varies, program to interfaces,  Encapsulate what varies, program to interfaces, Single Responsibility Principle, Open Closed Principle,  Don’t Repeat Yourself Principle,… • Helps you think about what the system should  do and how it should do it.João Pereira, Sep. 2011  34
  35. 35. What is Unit Testing • Pre‐condition for refactoring*. Would you  Pre condition for refactoring Would you change a line of production code without  knowing the change s side effects? knowing the change’s side effects? *Refactoring is the process of changing a software  system in such a way that it does not alter the  external behavior of the code yet improves its  external behavior of the code yet improves its internal structure. It is a disciplined way to clean  up code that minimizes the chances of introducing  bugs – in “Refactoring: Improving the design of  existing code” Martin FowlerJoão Pereira, Sep. 2011  35
  36. 36. What is Unit Testing • Generally there is a suite of tests for a single Generally, there is a suite of tests for a single  class (the System Under Test, or SUT for short) • Every line of SUT’s code is tested during the Every line of SUT s code is tested during the  execution of all tests in the suite A Suite of tests is a powerful bug detector  that decapitates the time it takes to find  bugs – i “R f t i b in “Refactoring: Improving the  I i th design of existing code” Martin Fowler Martin FowlerJoão Pereira, Sep. 2011  36
  37. 37. João Pereira, Sep. 2011  37
  38. 38. What is JUnit? “JUnit is a simple framework to write repeatable tests. It is an  instance of the xUnit architecture for unit testing  instance of the xUnit architecture for unit testing frameworks.” Erich Gamma Kent BeckJoão Pereira, Sep. 2011  38
  39. 39. What is JUnit? • xUnit is the family name given to a bunch of is the family name given to a bunch of  testing frameworks that have become widely  known amongst software developers known amongst software developers • Origins from Kent Beck paper: “Simple  Smalltalk Testing: With Patterns Smalltalk Testing: With Patterns” ‐ http://www.xprogramming.com/testfram.htmJoão Pereira, Sep. 2011  39
  40. 40. Lifecycle of an JUnit Test Class Load  suite fixtures Load  test fixtures Setup suite resources Setup suite resources Run Test Setup test resources Setup test resources Clear test fixtures Clear test fixtures Next Test N Release test resources Yes More  Tests? No Clear suite fixtures End Release suite resourcesJoão Pereira, Sep. 2011  40
  41. 41. Anatomy of an JUnit Test (version 4.x) 4 x)public class GreetingsTest {1 @BeforeClass void setupTest() { setupTest public static 1 System.out.println("setupTest"); } @Before 2 setupTestCase2 public void setupTestCase() { System.out.println("setupTestCase"); } 3 testGreetingsWithNullName @Test3 public void testGreetingsWithNullName() { System.out.println("testGreetingsWithNullName"); 5 tearDownTestCase } @ est @Test4 public void testGreetingsWithValidName() { 2 setupTestCase System.out.println("testGreetingsWithValidName"); } @After 4 testGreetingsWithValidName5 public void tearDownTestCase() { System.out.println("tearDownTestCase"); } 5 tearDownTestCase @AfterClass6 public static void tearDownTest() { System.out.println("tearDownTest"); 6 tearDownTest }}João Pereira, Sep. 2011  41
  42. 42. Anatomy of an JUnit Test (version 4.x) 4 x) • Simple POJO (Plain Old Java Object) Simple POJO (Plain Old Java Object) • Use of annotations to declare testing instructions • Basic annotations: Basic annotations: – @BeforeClass – Runs before the first test  execution – @Before – Runs before every test execution – @Test – Run as a test Run as a test  – @After – Runs after every test execution – @AfterClass – Runs after last test execution @ te C ass u s a te ast test e ecut oJoão Pereira, Sep. 2011  42
  43. 43. JUnit Quick Start (version 4.x) 4 x) • In your test class, import statically the Assert class In your test class, import statically the Assert class import static org.junit.Assert.*; • Create the test methods Give a human Create the test methods. Give a human  understandable name to the test. Annotate the  method with @org.junit.Test et od t @o g.ju t. est @Test public void testAddFundsToAccount() { //test } @Test public void testCannotWithdrawFromAccountWhenNotEnoughFunds() { //Test }João Pereira, Sep. 2011  43
  44. 44. JUnit Quick Start (version 4.x) 4 x) • Exercise the SUT, and use one of the available Exercise the SUT, and use one of the available  assertXXX methods, available in class  org.junit.Assert, to verify the results. • Example: assertNotNull("this should be true", sut.findDoorUnit("name")); • Full list of assertXXX methods: – http://junit.sourceforge.net/javadoc/João Pereira, Sep. 2011  44
  45. 45. JUnit Quick Start (version 4.x) 4 x) • Verify that a given exception is throw Verify that a given exception is throw @T t(expected=NullPointerException.class) @Test( t d N llP i t E ti l public void testShouldThrowNPE() { Object dummyNullObject = null; dummyNullObject.toString(); y j g(); }João Pereira, Sep. 2011  45
  46. 46. JUnit Quick Start (version 4.x) 4 x) • Verify if a test is taking more than x Verify if a test is taking more than x milliseconds to complete. Used for early  detection of performance problems. @Test(timeout=1000) public void testShouldCompleteAlgortithmInLessThanOneSecond() { //Some complex algorithm running on a complex data structure }João Pereira, Sep. 2011  46
  47. 47. Test Fixtures • Use Creation Methods to generate test data Use Creation Methods to generate test data. • Example: p public void setupTests() { p //Some sophisticated test data factory List<Door> testDoors = TestDataFactory.<Door>generateTestData(10); for (Door door: testDoors) { door.save(); } } public class TestDataFactory { /** * Create a list ob objects of type T * @param i the number of instances to create * @return a list of objects of type T */ public static <T> List<T> generateTestData(int i) { //Creational Logic goes here… } }João Pereira, Sep. 2011  47
  48. 48. Test Fixtures • Use YAML to statically represent test data and  y p load it into your test, with snakeyaml (http://snakeyaml.org) • Example testData.yaml DoorOne: name: The door one defaultCode: 18siks99 DoorTwo: name: Other door defaultCode: 27shs7k public void setupTestData() throws FileNotFoundException { //Magically is loaded... YamlAdapter yaml = new YamlAdapter(); List<Door> doors = yaml.<Door>loadData(new FileInputStream("/testData.yaml")); //rest of the setup }João Pereira, Sep. 2011  48
  49. 49. Want to lean more about JUnit and Unit Testing? • In the web: In the web: – xUnit Patterns: http://xunitpatterns.com – JUnit: http://junit sourceforge net JUnit:  http://junit.sourceforge.net • Books: –JUnit In ActionJoão Pereira, Sep. 2011  49
  50. 50. Programmer testing • What is a Test? • Overview of Agile testing quadrants • What is Test Driven Development • Overview of unit testing and JUnit • Introduction to Test Doubles and Mockito • Measure code coverage with Cobertura • ReferencesJoão Pereira, Sep. 2011  50
  51. 51. Revisiting what Unit Testing is…. Small pieces of code are tested in  isolation from the rest of the system. Generally, don’t care about the  interaction with other classes. interaction with other classes Don’t TestJoão Pereira, Sep. 2011  51
  52. 52. Testing in Isolation Testing in Isolation ?How we deal with these dependencies ?João Pereira, Sep. 2011  52
  53. 53. Testing in isolation • Generally the SUT depends on other Generally, the SUT depends on other  components, or the so called depend‐on  component (DOC, for short) in xUnit component (DOC for short) in xUnit Patterns DOCs SUTJoão Pereira, Sep. 2011  53
  54. 54. Testing in isolation • DOCs may not be available yet or do not DOCs may not be available yet, or do not  produce the results we want for our test. • Executing DOC code may result in undesirable Executing DOC code may result in undesirable  side effects. Ex: DOC may connect to a  production DB and alter production data. production DB and alter production data • Running tests for a SUT that uses all DOCs is  like running integration tests and can be very  lik i i i d b slow. It’s not the purpose of unit testing!!João Pereira, Sep. 2011  54
  55. 55. Testing in isolation • DOCs may not be available yet or do not DOCs may not be available yet, or do not  produce the results we want for our test. • Executing DOCit T may result ldundesirable Unit Tests should  U code t h in Executing DOC code may result in undesirable  side effects. Ex: DOC may connect to a  g alter production data give instant  production DB and alter production data. production DB and feedback! • Running tests for a SUT that uses all DOCs is  like running integration tests and can be very  lik i i i d b slow. It’s not the purpose of unit testing!!João Pereira, Sep. 2011  55
  56. 56. Testing in isolation How can we test  The SUT without the DOC ?João Pereira, Sep. 2011  56
  57. 57. Testing in isolation How can we test the SUT without the DOC? How can we test the SUT without the DOC? We can replace these DOCs by “test‐ spec f c equ a e ts specific equivalents”João Pereira, Sep. 2011  57
  58. 58. Testing in isolation • Replace the DOCs by Test Doubles (Just like in Replace the DOCs by Test Doubles (Just like in  movie industry) • Test Doubles will provide the same API used Test Doubles will provide the same API used  by SUT • SUT ill SUT will use the Test Double without knowing  h T D bl i h k i it’s a “Imposter”João Pereira, Sep. 2011  58
  59. 59. Using Test DoublesJoão Pereira, Sep. 2011  59
  60. 60. Test Doubles • Test Doubles can take many forms depending Test Doubles can take many forms, depending  on the purpose:  – Dummy Objects Dummy Objects – Fakes – Stubs – Spies –M k MocksJoão Pereira, Sep. 2011  60
  61. 61. Test Doubles • Test Doubles can take many forms, depending on the Test Doubles can take many forms, depending on the  purpose:  –Dummy Objects Dummy Objects – Fakes – Stubs – Spies – MocksJoão Pereira, Sep. 2011  61
  62. 62. Test Doubles: Dummy Objects • Problem: An SUT method signature requires Problem: An SUT method signature requires  and object as a parameter, however we don’t  care about what the value of the object is. • Ex: public class ClassUnderTest { public boolean openDoor(DoorRequest doorRequest) { //Code goes here } } public class TestClassUnderTest { public void testDorShouldNotOpen() { // Dummy doorRequest. DoorRequest doorRequest = new DoorRequest(); ClassUnderTest sut = new ClassUnderTest(); assert !sut.openDoor(doorRequest) : "The door shouldnt open"; } }João Pereira, Sep. 2011  62
  63. 63. Test Doubles: Dummy Objects • Dummy Objects generally appear in the form Dummy Objects, generally, appear in the form  of: – Literal Value Literal Value – Derived Value – Generated Value Generated ValueJoão Pereira, Sep. 2011  63
  64. 64. Test Doubles: Dummy Objects • A Literal Value is any value we use for A Literal Value is any value we use for  attributes of Objects in our test fixtures.  • Ex: public void testDoorShouldOpen() { String doorIdLiteralValue = "AHBV834"; // Dummy doorRequest doorRequest. DoorRequest doorRequest = new DoorRequest(); //Using the literal value for populating the dummy doorRequest object doorRequest.setDoorId(doorIdLiteralValue); DoorManager sut = new DoorManager(); //Exercise SUT sut.closeDoor(doorRequest); //Verify using the literal value assert !sut.getDoor(doorIdLiteralValue).isOpen(): "The door should be closed!"; }João Pereira, Sep. 2011  64
  65. 65. Test Doubles: Dummy Objects • A Derived Value, also know as Calculated Value,  e ed a ue, a so o as Ca cu ated a ue, is any value calculated from other values • Ex: public void testDoorCodeShouldBeSet() { String doorIdLiteralValue = "AHBV834"; Door dummyDoor = new Door(); //Calculated code from the algorithm in Door and some literal value String doorCode = dummyDoor.generateCode("142536A"); DoorRequest doorRequest = new DoorRequest(); // Using the literal value for creating the dummy doorRequest object doorRequest.setDoorId(doorIdLiteralValue); //Use the derived value doorRequest.setCode(doorCode); d R t tC d (d C d ) DoorManager sut = new DoorManager(); // Exercise sut.openDoor(doorRequest); // Verify using the literal value assert sut.getDoor(doorIdLiteralValue).isOpen() : "The door should be closed! ; The closed!"; }João Pereira, Sep. 2011  65
  66. 66. Test Doubles: Dummy Objects • A Generated Value, is a value that is A Generated Value, is a value that is  generated each time a test runs. • Ex: public void testCreateDoor() { // Create a randomly generated BigInteger, uniformly distributed over // the range 0 to 2^130 -1, then convert it to a string using a radix of 2 130 1, // 32 String doorCode = new BigInteger(130, new SecureRandom()).toString(32); Door door = new Door(); door.setCode(doorCode); //Rest of the test }João Pereira, Sep. 2011  66
  67. 67. Test Doubles • Test Doubles can take many forms, depending on the Test Doubles can take many forms, depending on the  purpose:  – Dummy Objects –Fakes – Stubs – Spies – MocksJoão Pereira, Sep. 2011  67
  68. 68. Test Doubles: Fakes • Problem: An SUT’s DOC is not available or is Problem: An SUT s DOC is not available or is  not suitable for using in tests. • Ex: XJoão Pereira, Sep. 2011  68
  69. 69. Test Doubles: Fakes • A Fake Object is a more simpler lightweight A Fake Object is a more simpler, lightweight  object than the real DOC • Ex: public void testCloseDoor() { Door sut = new Door(new FakeController()); assert sut.close(): "The door should be closed ; The closed"; } While the USBDoorController may use  your USB drivers, the FakeController may  simple use some simulator, for example. i l i l t f lJoão Pereira, Sep. 2011  69
  70. 70. Test Doubles: Fakes • Common uses of Fakes: Co o uses o a es: – Fake Database  offers same functionality as the real  db, but is more lightweight. Example: Use HashMaps or In‐Memory Databases (ex: HSQL In Memory DB) I M D t b ( HSQL I M DB) – Fake Webservice  Instead of using the real web  service, use one with the same API but that returns  , fake data – Fake Service Layer  For GUI coding, the service layer  API can be implemented to return fake data to the  API b i l t dt t f k d t t th Presentation LayerJoão Pereira, Sep. 2011  70
  71. 71. Test Doubles • Test Doubles can take many forms, depending on the Test Doubles can take many forms, depending on the  purpose:  – Dummy Objects – Fakes –Stubs – Spies – MocksJoão Pereira, Sep. 2011  71
  72. 72. Test Doubles: Stubs • Problem: An SUT’s DOC is not available, or is Problem: An SUT s DOC is not available, or is  not suitable for using in tests, but you need  indirect input from the DOC to SUT. • Ex: Input from DOC  f is needed!João Pereira, Sep. 2011  72
  73. 73. Test Doubles: Stubs • Problem: An SUT’s DOC is not available, or is Problem: An SUT s DOC is not available, or is  not suitable for using in tests, but you need  indirect input from the DOC to SUT. • Ex: Input from DOC  f is simulated!João Pereira, Sep. 2011  73
  74. 74. Test Doubles • Test Doubles can take many forms, depending on the Test Doubles can take many forms, depending on the  purpose:  – Dummy Objects – Fakes – Stubs Spies –Spies – MocksJoão Pereira, Sep. 2011  74
  75. 75. Test Doubles: Spies • Problem: An SUT’s DOC is not available, or is Problem: An SUT s DOC is not available, or is  not suitable for using in tests, but DOC’s  output, or behavior, is required to be verified. • Ex: Output/behavior from  p / DOC is required to be  verified!João Pereira, Sep. 2011  75
  76. 76. Test Doubles: Spies • Problem: An SUT’s DOC is not available or is not Problem: An SUT s DOC is not available, or is not  suitable for using in tests, but DOC’s output, or  behavior, is required needed to be verified. , q • Ex: Output/behavior from DOC  is recorded and can be  verified afterwardsJoão Pereira, Sep. 2011  76
  77. 77. Test Doubles: Spies • Example: We don’t really want to send an Example: We don t really want to send an  email, but we want to know if the email was  sent when method doorsInDanger is  sent when method doorsInDanger is executed.João Pereira, Sep. 2011  77
  78. 78. Test Doubles: Spies • Example: We don’t really want to send an Example: We don t really want to send an  email, but we want to know if the email was  sent when method doorsInDanger is  sent when method doorsInDanger is executed. Output/behavior from DOC  is recorded and can be  verified afterwardsJoão Pereira, Sep. 2011  78
  79. 79. Test Doubles: Spies • In Java: In Java: MailService.java public interface MailService { public void sentEmail(String email); } DoorManager.java p public class DoorManager { g private MailService mailService; public void setMailService(MailService mailService) { this.mailService = mailService; } public void doorsInDanger() { // Some l i logic mailService.sentEmail("Contents..."); } }João Pereira, Sep. 2011  79
  80. 80. Test Doubles: Spies • In Java: In Java: TestMailService.java public class TestMailService implements MailService { // Store the sent emails private List<String> sentEmails = new ArrayList<String>(); /** * Get the number of mails sent since initialization * * @return The number of emails sen */ public int getNumberOfSentEmails() { return sentEmails.size(); } @Override public void sentEmail(String email) { // Will not send the email. Just record it this.sentEmails.add(email); } }João Pereira, Sep. 2011  80
  81. 81. Test Doubles: Spies • In Java: In Java:DoorManagerTest.javapublic class DoorManagerTest { public void sendNotificationToOwner() { MailService spyMail = new TestMailService(); DoorManager sut = new DoorManager(); sut.setMailService(spyMail); // doorsInDanger logs the incident in LOG and sent an email to the owner // of the Door sut.doorsInDanger(); assert ((TestMailService)spyMail).getNumberOfSentEmails()==1: "Should have sent oneemail"; }}João Pereira, Sep. 2011  81
  82. 82. Test Doubles • Test Doubles can take many forms, depending on the Test Doubles can take many forms, depending on the  purpose:  – Dummy Objects – Fakes – Stubs – Spies p –MocksJoão Pereira, Sep. 2011  82
  83. 83. Test Doubles: Mocks • Problem: An SUT’s DOC is not available, or is not  , suitable for using in tests, but DOC’s calls, in a  defined order, are expected to occurs in order to  verify SUT behavior. verify SUT behavior • Ex: Is expected that SUT calls  DOC in this order.  DOC i thi dJoão Pereira, Sep. 2011  83
  84. 84. Test Doubles: Mocks • Problem: An SUT’s DOC is not available, or is not  , suitable for using in tests, but DOC’s calls, in a  defined order, are expected to occurs in order to  verify SUT behavior. verify SUT behavior • Ex:João Pereira, Sep. 2011  84
  85. 85. Did you notice the importance of  using interfaces?  using interfaces?João Pereira, Sep. 2011  85
  86. 86. João Pereira, Sep. 2011  86
  87. 87. What is Mockito? • “Mockito is a mocking framework that tastes Mockito is a mocking framework that tastes  really good. It lets you write beautiful tests  with clean & simple API. Mockito doesn t give  with clean & simple API Mockito doesn’t give you hangover because the tests are very  readable and they produce clean verification  readable and they produce clean verification errors” – http://code.google.com/p/mockitoJoão Pereira, Sep. 2011  87
  88. 88. What can Mockito do for you? • Helps you develop test easily using Mocks Helps you develop test easily using Mocks • Provides a framework for creating and using  Stubs • Allows you to follow BDD (Behavior driven  Development) technique D l ) h iJoão Pereira, Sep. 2011  88
  89. 89. A first example using Mocks • Let’s consider the following class diagram: Let s consider the following class diagram: A DoorService is the API used to manage  DoorUnits. Most of the operations on  DoorService are delegated to a  DoorUnitManager i t D U itM instance.João Pereira, Sep. 2011  89
  90. 90. A first example using Mocks Let s create a test for the  Let’s create a test for the DoorService. The first  method we will implement is  h d ill i l i addDoorUnit.João Pereira, Sep. 2011  90
  91. 91. A first example using Mocks • A first draft of the unit test for A first draft of the unit test for  addDoorUnit: @Test public void testAddDoorUnit() { //Need a service. Our SUT DoorService sut = createTestDoorService(null); DoorUnit d i dummyDoorUnit = createDummyDoorUnit(); i i () sut.addDoorUnit(dummyDoorUnit); } How should we really test?João Pereira, Sep. 2011  91
  92. 92. A first example using Mocks Back to our first design; we said that most  ope a o s o a oo Se operations on a DoorService are to be  ce a e o be delegated to DoorUnitManager instance. In those cases we only want to be sure that  the appropriate methods are called on a  DoorUnitManager. D U itMJoão Pereira, Sep. 2011  92
  93. 93. A first example using Mocks • Complete unit test for addDoorUnit Complete unit test for addDoorUnit @Test public void testAddDoorUnit() { DoorUnitManager mockedDoorUnitManager = mock(DoorUnitManager.class); //Need a service. Our SUT DoorService sur = createTestDoorService(mockedDoorUnitManager); DoorUnit dummyDoorUnit = createDummyDoorUnit(); //exercise sur.createDoorUnit(dummyDoorUnit); //Verify expectations on the mockedDoorUnitManager verify(mockedDoorUnitManager).addDoorUnit(dummyDoorUnit); verify(mockedDoorUnitManager) addDoorUnit(dummyDoorUnit); }João Pereira, Sep. 2011  93
  94. 94. A first example using Stubs • Next let’s implement findDoorUnit Next, let s implement findDoorUnit methodJoão Pereira, Sep. 2011  94
  95. 95. A first example using Stubs • A first draft of the unit test for A first draft of the unit test for  findDoorUnit: @Test public void testFindDoorUnit() { DoorUnitManager mockedDoorUnitManager = mock(DoorUnitManager.class); // Need a service Our SUT service. DoorService sut = createTestDoorService(mockedDoorUnitManager); DoorUnit dummyDoorUnit = createDummyDoorUnit(); // Lets first add it sut.addDoorUnit(dummyDoorUnit); // Now find it by name DoorUnit foundDoorUnit = sut.findDoorUnit(dummyDoorUnit.getName());FAIL!! assertEquals(dummyDoorUnit, foundDoorUnit); }João Pereira, Sep. 2011  95
  96. 96. A first example using Stubs • Complete unit test for findDoorUnit: Complete unit test for findDoorUnit: @Test public void testFindDoorUnit() { // Our mocked DOC DoorUnitManager mockedDoorUnitManager = mock(DoorUnitManager.class); // Need a service. Our SUT DoorService sut = createTestDoorService(mockedDoorUnitManager); DoorUnit dummyDoorUnit = createDummyDoorUnit(); // L t fi t add it Lets first dd sut.addDoorUnit(dummyDoorUnit); // stubbing what is expected from DOC when(mockedDoorUnitManager.findByName(dummyDoorUnit.getName())) .thenReturn(dummyDoorUnit); y // Now find it by name DoorUnit foundDoorUnit = sut.findDoorUnit(dummyDoorUnit.getName()); assertEquals(dummyDoorUnit, foundDoorUnit); }João Pereira, Sep. 2011  96
  97. 97. Want to learn more? • http://code google com/p/mockito/ http://code.google.com/p/mockito/ • http://docs.mockito.googlecode.com/hg/lates t/org/mockito/Mockito.html t/org/mockito/Mockito html • http://docs.mockito.googlecode.com/hg/lates t/org/mockito/BDDMockito.html / / ki /BDDM ki h lJoão Pereira, Sep. 2011  97
  98. 98. Other alternatives jmockitJoão Pereira, Sep. 2011  98
  99. 99. Other alternatives These can be combined to suit  your needs. They can even be  your needs They can even be enriched with scripting  jmockit languages!!!João Pereira, Sep. 2011  99
  100. 100. Programmer testing • What is a Test? • Overview of Agile testing quadrants • What is Test Driven Development • Overview of unit testing and JUnit • Introduction to Test Doubles and Mockito • Measure code coverage with Cobertura • Exercises • ReferencesJoão Pereira, Sep. 2011  100
  101. 101. What is code coverage? What is Wh t i Code Coverage ? C d CJoão Pereira, Sep. 2011  101
  102. 102. What is code coverage? • A measure that indicates the degree to which A measure that indicates the degree to which  a program has been tested. – Consider the following java method: Consider the following java method: public int foo(int a, int b) { int result = -1; if (a > 0 && b > 0) { result = a / b; } if ( <= 0 || b < 0) { (a < <= result = -1; } return result; }João Pereira, Sep. 2011  102
  103. 103. What is code coverage? • …and consider this test: and consider this test: @Test public void testFoo() { SystemUnderTest sut = new SimpleDoorServiceTest(); assertEquals( 1, sut.foo( 2, assertEquals(-1 sut foo(-2 3)); }João Pereira, Sep. 2011  103
  104. 104. What is code coverage? How good this test… @Test public void testFoo() { SystemUnderTest sut = new SimpleDoorServiceTest(); assertEquals(-1, sut.foo(-2, 3)); } …cover all statements in this code? public int foo(int a, int b) { int result = -1; if (a > 0 && b > 0) { result = a / b; } if (a <= 0 || b <= 0) { result = -1; } return result; }João Pereira, Sep. 2011  104
  105. 105. What is code coverage? Line Coverage Branch Coverage g Branch Coverage Number of hitsJoão Pereira, Sep. 2011  105
  106. 106. What is code coverage? • Number of hits  How many times the Number of hits How many times the  statement was executed during the tests? • Line coverage  What is the percentage of Line coverage What is the percentage of  the total number of lines of code that are  being tested? • Branch coverage  What is the percentage of  the total branches that are being tested? • Complexity What is the Average McCabes  cyclomatic code complexity?João Pereira, Sep. 2011  106
  107. 107. What is code coverage? • Branch coverage: Branch coverage: Tested values Tested values A B Branch Cumulative Branch coverage Coverage >0 0 >0 0 25% 25% >0 <0 25% 50% <0 >0 25% 75% <0 0 <0 0 25% 100%João Pereira, Sep. 2011  107
  108. 108. What is code coverage? 100% Coverage is not good enough to tell  Tested values Tested values g A that our software is bug free. It just tell us that  B Branch Cumulative Branch coverage tests are executing all statements and branches  Coverage >0 0 >0 0 25% 25% of our code. It doesn’t tell, however, that we’re  f d I ll h h ’ >0 <0 25% 50% making the correct assumptions, or that we fully  <0 >0 25% 75% understand the problem!!. p <0 0 <0 0 25% 100%João Pereira, Sep. 2011  108
  109. 109. What is code coverage? • Complexity (number of decision points (if else for while Complexity (number of decision points (if, else, for. while,  case) + 1 public int foo(int a, int b) { int result = -1; 1 1 if (a > 0 && b > 0) { result = a / b; } 1 1 if (a <= 0 || b <= 0) { result = -1; } return result; } Complexity: 5João Pereira, Sep. 2011  109
  110. 110. What is code coverage? • Equivalent to: Equivalent to: public int fooMethod(int a, int b) { int result = -1; if (a > 0) { 1 if (b > 0) { 1 result = a / b; } } if (a <= 0) { 1 result = -1; } if (b <= 0) { result = -1; 1 ; } return result; } Complexity: 5João Pereira, Sep. 2011  110
  111. 111. What is code coverage? Tested values Tested values Code with high* complexity can be a pain  A B Branch Cumulative Branch coverage Coverage for maintenance and it increases the  >0 0 >0 0 25% 25% probability of bugs.  b bilit f b >0 <0 25% 50% *An generally accepted higher limit is 10 <0 >0 25% 75% <0 0 <0 0 25% 100%João Pereira, Sep. 2011  111
  112. 112. Cobertura • Better integrated with Maven Just run: Better integrated with Maven. Just run: mvn cobertura:cobertura • Know more about Cobertura: – http://cobertura.sourceforge.net/ • Know more about Maven Cobertura Plugin: g – http://mojo.codehaus.org/cobertura‐maven‐ p g / plugin/João Pereira, Sep. 2011  112
  113. 113. Other alternatives Coverlipse EclEmmaJoão Pereira, Sep. 2011  113
  114. 114. Programmer testing • What is a Test? • Overview of Agile testing quadrants • What is Test Driven Development • Overview of unit testing and JUnit • Introduction to Test Doubles and Mockito • Measure code coverage with Cobertura • ReferencesJoão Pereira, Sep. 2011  114
  115. 115. Programmer testing • What is a Test? • Overview of Agile testing quadrants • What is Test Driven Development • Overview of unit testing and JUnit • Introduction to Test Doubles and Mockito • Measure code coverage with Cobertura • ReferencesJoão Pereira, Sep. 2011  115
  116. 116. References about Testing subjects • Books: – The Art of Software Testing, Second Edition • http://amzn to/art‐of‐software‐testing http://amzn.to/art‐of‐software‐testing  – Agile Testing: A Practical Guide for Testers and  Agile Teams Agile Teams • http://amzn.to/agile‐testing  – Code Complete 2: A Practical Handbook of  p Software Construction • http://amzn.to/code‐completeJoão Pereira, Sep. 2011  116

×