Test driven development - JUnit basics and best practices

  • View
    1.152

  • Download
    0

Embed Size (px)

Transcript

  1. 1. TESTDRIVENDEVELOPMENT Unit testing basics and best practices Lets get test infected!
  2. 2. @npathai on github Narendra Pathai 5 years of core development experience 4 years with unit testing 2 years with TDD Collaborator of Java Design Patterns repository Contributor to JUnit 4 and Java Hamcrest
  3. 3. @harshSE on github Harsh Patel 5 years of core development experience 3 years with unit testing 1 years with TDD Contributor to JMeter, Java Design Patterns
  4. 4. TESTING CAN BE USED TO SHOW presence of bugs, NOTabsence - Edsger Dijkstra
  5. 5. myths &misconceptions
  6. 6. Lets write unit test cases because then there will be no bugsYayyy!! Myth 1
  7. 7. less bugs If unit testing is done properly then there will be Reality 1
  8. 8. wastes time I would rather write something that is useful because it Myth 2
  9. 9. saves time I must write tests today so that it tomorrow Reality 2
  10. 10. finding bugs Unit testing is just about Myth 3
  11. 11. Multi-faceted unit tests drive code design executable specification Reality 3
  12. 12. 100% coverage I can be confident that code works only if there is Myth 4
  13. 13. n% coverage Its perfectly fine to have if it gives the required confidence in the code Reality 4
  14. 14. production code Developers only write Myth 5 QA team does the testing
  15. 15. unit tests Its developers who must write Reality 5
  16. 16. What is UNITTESTING?
  17. 17. tool { Its a DESIGN CONFIDENCE REGRESSION
  18. 18. TESTS ARE FIRST CLIENTS OF CODE
  19. 19. TESTS ARE FIRST CLIENTS OF CODE I repeat
  20. 20. TEST PYRAMID
  21. 21. UNIT TESTS INTEGRATION TESTS END 2 END TESTS MANUAL TESTS CONFIDENCEINENTIRESYSTEM CONFIDENCEININDIVIDUALCHANGE EXECUTIONTIME RELIABILITY High Low Low High COST
  22. 22. ICE CREAM CONE Inverse of Test Pyramid More manual than unit tests Too costly to test what we dont want Difficult to do in depth testing Often how testing is done
  23. 23. UNIT TESTS INTEGRATION TESTS END 2 END TESTS MANUAL TESTS
  24. 24. WHO WILL WRITE WHICH TESTS? Not important right now, a topic for some other day!
  25. 25. NAMINGCONVENTIONYou should call a spade a spade
  26. 26. HOW TO NAME TEST METHODS UnitOfWork_StateUnderTest_ExpectedBehavior behavior under test define current state of object Resultant state / event
  27. 27. HOW TO NAME TEST METHODS poppingAStack_whenEmpty_throwsException popping from stack when stack is empty because empty stack cannot be popped
  28. 28. TEST METHODS ON STEROIDS poppingAnEmptyStackThrowsException popping from stack when stack is empty because empty stack cannot be popped
  29. 29. BUILD THE RIGHTTHING poppingAnEmptyStackThrowsException { Object obj = stack.pop(); } are we building the right thing? are we building it right?
  30. 30. Writing the first TEST
  31. 31. xUnit frameworksare language specific Java jUnit .NET nUnit C++ CppTest Javascript qUnit *multiple frameworks per language are available
  32. 32. @Test is the way to define a new test case
  33. 33. @Before setup environment to run each test static Dont even think about it.
  34. 34. @After cleanup resources after each test case
  35. 35. @BeforeClass setup expensive resources shared across all tests Think static
  36. 36. @AfterClass cleanup expensive resources shared across all tests
  37. 37. assertion A statement that is expected to be true at that point in code
  38. 38. assertion Passing test passes |assertion Failing test fails
  39. 39. assert keyword assert 2 + 1 == 3; Limited power Lower expressiveness
  40. 40. jUnit assertion More power * Better expressiveness assertXXX(...) methods
  41. 41. assertTrue(woah!, 2 + 1 == 3); assertion la jUnit assertEquals(3, 2 + 1); assertArrayEquals([], []);
  42. 42. AARRANGE AACT AASSERT (given) (when) (then)
  43. 43. Defining a UNIT there is no correct way
  44. 44. UNIT is SUBJECTIVE a single class a group of related classes
  45. 45. When defining a UNIT DONT CONSIDER INTERNAL STRUCTURE OF CLASS AS A UNIT IT TAKES EXPERIENCE TRIAL & ERROR
  46. 46. now introducing Hamcrest Matchers assertion on STEROIDS
  47. 47. assertThat(2 + 1, equalsTo(3)); expressive assertions assertThat(list, hasSize(3)); assertThat(list, contains(a));
  48. 48. assertThat(person, hasAge(30)); custom assertions assertThat(2, isEven()); assertThat(21, isDivisbleBy(3));
  49. 49. unexpected EXCEPTIONSnot all exceptions are unexpected
  50. 50. @Test poppingAnEmptyStackThrowsException() { try {... fail();} catch (SomeException e) { assertThat(e.getMessage(), ..); } } Using try...catch Error prone, we can do much better
  51. 51. @Test(expected = EmptyStackException.class) poppingAnEmptyStackThrowsException() Using @Test but cannot test exception message!
  52. 52. follow|RULES JUNIT ADDITION OR REDEFINITION OF TEST METHOD BEHAVIOR
  53. 53. ExpectedException rule @Rule public ExpectedException thrown = ExpectedException.none(); declares a rule reference rules must be public
  54. 54. poppingAnEmptyStackThrowsException() { thrown.expect(StackEmptyException.class); thrown.expectMessage(stack is empty); emptyStack.pop(); } ExpectedException rule
  55. 55. @Rule public TemporaryFolder folder = new TemporaryFolder(); folder.newFile(myFile.txt); folder.newFolder(subFolder); TemporaryFolder rule Automatically deletes temp files and directories
  56. 56. ExternalResource Timeout Custom More rules! No more leaked resources Fail tests after timeout Define custom rules
  57. 57. Run with (Runners) way to customize test processing & extend its purpose.
  58. 58. @RunWith A class level annotation that selects the runner to use for test case @RunWith(Suite.class) class of the runner to use
  59. 59. Hierarchical runner organize scenarios of the unit with nested classes/contexts
  60. 60. Suite runner organize several feature tests of a unit together
  61. 61. data >> tests test a system using data inputs
  62. 62. JUnitParams library Data driven testing from multiple types of sources @RunWith(JUnitParamsRunner.class)
  63. 63. PASS FROM ANNOTATION @Parameters({a, A, b, B}) @Test toUpperCaseConvertsCharactersToUpperCase(String in , String expectedOut)
  64. 64. PASS FROM METHOD @Parameters(method=dataFor_toUpperCase) @Test toUpperCaseConvertsCharactersToUpperCase(String in , String expectedOut)
  65. 65. PASS FROM CLASS @Parameters(source = DataForToUpperCase.class) @Test toUpperCaseConvertsCharactersToUpperCase(String in , String expectedOut)
  66. 66. PASS FROM FILE @FileParameters(dataForToUpperCase.csv) @Test toUpperCaseConvertsCharactersToUpperCase(String in , String expectedOut)
  67. 67. DONT DO THIS AT HOME DIFFERENT SCENARIO - SAME DATA SOURCE DRIVING CONDITIONS FROM DATA
  68. 68. and the tools change us TOOLS We change the
  69. 69. EclEmma Plugin a plugin for code coverage in eclipse Infinitest Plugin a plugin that runs tests continuously in eclipse
  70. 70. Anti-PatternsEvery time you do this a kitten dies
  71. 71. 1 TEST CODE IS SECONDARY Anti-Pattern
  72. 72. 1 PRODUCTIONcode = TESTcode Best Practice
  73. 73. 2 REPEATING TEST CODE Anti-Pattern
  74. 74. 2 KEEP CODE DRY Best Practice
  75. 75. 3 TESTING internals or third party code Anti-Pattern
  76. 76. 3TEST USING PUBLIC API Best Practice
  77. 77. 4 MULTIPLESCENARIOS in a test Anti-Pattern
  78. 78. 4 SINGLE SCENARIO per test Best Practice
  79. 79. 5 CHANGEORDELETE tests* Anti-Pattern
  80. 80. 5 ONLY IF CHANGE IN behavior Best Practice
  81. 81. Ending thoughts we have learnt a lot!
  82. 82. PRODUCTION CODE TEST CODE
  83. 83. PRODUCTION CODE TEST CODE contains nesting doesnt contain nesting Is mostly imperative Is declarative takes more time to write takes less time to write
  84. 84. ?