This session showcases several unit testing libraries and frameworks that make it possible to write the most-effective unit and integration tests. It also highlights some of the most underused features of JUnit, including Theories, parameterized tests, and Hamcrest matchers.
Among the libraries it covers: Unitils, Spring Test, DbUnit, XMLUnit, Dumpster, Mockito, and JBehave. The presentation supplies code examples and discusses TDD/BDD best practices.
3. Who Am I? Software Engineer Particularly interested in technology evangelism and enterprise software development and architecture President and Founder of a number of organizations The Chico Java User Group The Silicon Valley Spring User Group LinkedIn http://www.linkedin.com/in/polymathiccoder Twitter http://twitter.com/polymathiccoder
4. Warning This presentation is very long and covers a lot of material
5. Outline Part I: Unit Testing Vanilla Is Boring Stay PUT All Those Theories All that CRUD Fakery Mockery Part II: TDD Part III: BDD Part IV: Tools Cross-cutting Story Time When I tell you a story Libra-palooza When I tell you about the coolness of some libraries
8. What is Unit Testing? What is a Unit? The smallest piece of code that Can be isolated Is testable Targets specific functionality Hmm⊠Letâs see⊠A statement? A branch? A method? A basis path within a method Defined by the flow of execution from the start of a method to its exit How many a method has depends on cyclomatic complexity N decisions = 2^N basis possible paths Infinite paths
9. What is Unit Testing? What kind of Testing? The verification of Intent The answer to the question: Does the code do what the developer intended for it to do? Reliability The answer to the question: Can I depend or build upon it?
10. xUnitand xUnit Concepts xUnit is any Unit Testing framework Based on SUnit, a Smalltalk project, design by Kent Beck Concepts Test fixtures Test case Assertions Test execution Test suites
11. Good Test Data Include Valid data Invalid data / Boundary conditions Different Formats Different Order Wide Range Null data Error Conditions
12. Good Tests Cover all possible basis paths Have Self-Describing Names Are Cohesive Independent of each other Reliable Repeatable Fast
13. The Most Opinionated Slide! Lame Excuses! Waste of time Nuisance Distraction from real work Hard to maintain Blah⊠Blah⊠Blah⊠3 bullet points Quit being lazy! Do yourself a favor and get with the program! You are attitude is the fastest way to get inducted to the Hall of Lame
14. xUnit Frameworks in Java The most popular frameworks JUnit A port of the original SUnit to Java by Erich Gamma and Kent Beck http://junit.org/ TestNG http://testng.org/ This presentation focuses on JUnit
19. The Code QuadraticEquation.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/main/java/com/polymathiccoder/talk/xunit/domain/QuadraticEquation.java
21. The Quadratic Equation 3 possible data combinations that must be tested Coefficients yielding a negative discriminant Coefficients yielding a discriminant equals to zero Coefficients yielding a positive discriminant 3 different outcomes The equation has no real solution The equation has one real solution The equation has two real solution 3 different basis paths
22. JUnit Annotations Test suites @RunWith Naming Convention <Class Name>Test Test fixtures Set Up @Before @BeforeClass Tear Down @After @AfterClass
24. Testing Private Methods Donât test them Relax the visibility to make the code testable Annotate Google Guavaâs @VisibleForTesting Use a nested test class Use reflection
25. The Code QuadraticEquationTest.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/domain/QuadraticEquationTest.java
28. Stay PUT Parameterized or Data-Driven Unit Tests Annotations @RunWith(Parameterized.class) To provide the parameters to be supplied via constructor injection @Parameters public static Collection<Object[]> parameters() @Parameter Object[] parameters
30. Libra-palooza Hamcrest Matchers Library Included in JUnit since 4.4 http://code.google.com/p/hamcrest/ Unitils Reflection-based assertions, etc⊠http://unitils.org Fest Fluent Assertion, etc⊠http://code.google.com/p/fest/
31. The Code QuadraticEquationParameterizedTest.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/domain/QuadraticEquationParameterizedTest.java
36. The Code RiverCrossing.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/main/java/com/polymathiccoder/talk/xunit/domain/RiverCrossing.java
38. The River Crossing Puzzle 9 possible combinations that must be tested Wolf and Cabbage left behind Cabbage and Wolf left behind Wolf and Goat left behind Goat and Wolf left behind Goat and Cabbage left behind Cabbage and Goat left behind Wolf and Wolf left behind Goat and Goat left behind Cabbage and Cabbage left behind 3 different outcomes One gets transported to the other side One of two left behind eats the other Error trying to transport more than one 18 basis paths
39. The River Crossing Puzzle 9 possible combinations that must be tested and 3 basis paths yielding 3 different outcomes 9 x 3 = 18 Vanilla Tests 3 x 3 = 9 Parameterized Tests 1 x 3 = 3 Theories
40. Theories Running tests with every possible combination of data points Annotations @RunWith(Theories.class) To provide the parameters to be supplied via constructor injection @DataPoints public static Object[] objects @DataPoint public static object
41. Assumptions and Rules Assumptions assumeThat, assumeTrue, assumeNotNull, etc⊠Rules Allowing for alterations in how test methods are run and reported @Rule Injects public fields of type MethodRule ErrorCollector ExpectedException ExternalResource TemporaryFolder TestName TestWatchman Timeout Verifier
42. The Code RiverCrossingTheory.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/domain/RiverCrossingTheory.java
46. The Employee Database Simple Domain Object Employee Id - Number Name - Text Data-Access Object Interface EmployeeDao â CRUD operations Two implementations EmployeeCollectionImpl â A Java Collection implementation EmployeeDaoDbImpl â A JDBC implementation
47. The Code Employee.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/main/java/com/polymathiccoder/talk/xunit/domain/Employee.java EmployeeDao.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/main/java/com/polymathiccoder/talk/xunit/repository/EmployeeDao.java
48. The Code EmployeeDaoCollectionImpl.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/main/java/com/polymathiccoder/talk/xunit/repository/EmployeeDaoCollectionImpl.java EmployeeDaoDbImpl.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/main/java/com/polymathiccoder/talk/xunit/repository/EmployeeDaoDbImpl.java
50. Testing Persistence Code Data Define the initial state of data before each test Define the expected state of data after each test Ensure that the data is in a known state before you run the test Run the test Compare against the expected dataset to determine the success or failure of the test Clean after yourself if necessary
51. Testing Persistence Code Notes of Java Collections An Immutable/un-modifiable collection is NOT necessarily a collection of Immutable/un-modifiable objects Notes on testing database code Use a dedicated database instance for testing per user Use an in-memory database if you can HSQLDB H2 EtcâŠ
52. Custom Hamcrest Matches Hamcrest Matches Write your own custom type-safe matcher One asserting per unit test Generating a readable description to be included in test failure messages https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/domain/matcher/EmployeeIsEqual.java
55. The Code EmployeeDaoCollectionImplTest.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/repository/EmployeeDaoCollectionImplTest.java
57. Libra-palooza DBUnit A JUnit extension used to unit test database code Export/Import data to and from XML Initialize database into a known state Verify the state of the database against an expected state http://www.dbunit.org/
59. The Code EmployeeDaoDbImplTest.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/repository/EmployeeDaoDbImplTest.java
62. The Mailer Simple email sender that uses the JavaMailAPI Fakes Dumpster A fake SMTP server to be used in unit tests http://quintanasoft.com/dumbster/ ActiveMQ An embedded broker (Make sure to disabled persistence) http://activemq.apache.org/
63. The Code Mailer.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/main/java/com/polymathiccoder/talk/xunit/repository/Mailer.java MailerTest.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/repository/MailerTest.java
69. The Egyptian Plover & the Nile Crocodile Herodotus in âThe Historiesâ claimed that there is a symbiotic relationship between the Egyptian Plover and the Nile Crocodile
70.
71. The Code EgyptianPlover.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/main/java/com/polymathiccoder/talk/xunit/domain/EgyptianPlover.java
73. The Egyptian Plover & the Nile Crocodile 3 different basis path The plover finds the crocodileâs mouth closed and flies away The plover finds the crocodileâs mouth open, doesnât find any leeches, then flies away The plover finds the crocodileâs mouth open, picks the leeches, then flies away 3 different outcomes False is returned indicating that the plover didnât eat An exception is thrown and False is returned indicating that the plover didnât eat True indicating that the plover ate
74. Mocking Dependencies need to be mock to test in isolation Simulating an object to mimic the behavior of a real object in a controlled manner
75. Mocking Dependencies need to be mock to test in isolation Simulating an object to mimic the behavior of a real object in a controlled manner
77. Libra-palooza Mockito The coolest mocking framework there is Annotations @RunWith(MockitoJUnitRunner.class) @Mock @InjectMocks @Spy Stub method calls Verify interactions http://code.google.com/p/mockito/
78. The Code EgyptianPloverTest.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/domain/EgyptianPloverTest.java
79. This is a digitally constructed image from the Warren Photographic Image Library of Nature and Pets http://www.warrenphotographic.co.uk/
81. Test Suites and Groups Annotations @Category @RunWith(Categories.class) @IncludeCategory @ExcludeCategory @SuiteClasses
82. The Code FastTest.java SlowTest.java SlowAndFastTest.java SlowTestSuite.java https://github.com/PolymathicCoder/LeTourDeXUnit/tree/master/src/test/java/com/polymathiccoder/talk/xunit/misc
83. Miscellaneous Topics Testing AOP (Aspect-Oriented Programming) Code Unit Testing the Advice Verify the execution of the Advice when Joint Point is reached Testing Concurrency In Junit Concurrent test execution Annotations @Concurrent @RunWith(ConcurrentSuite.class) GroboUtils http://groboutils.sourceforge.net/ ConcJUnit http://www.cs.rice.edu/~mgricken/research/concutest/concjunit/
86. Why Not Test First Instead? Most of us are just not disciplined to test last In order to determine a sets of verifications in the form tests to fulfill the requirements No room for misunderstanding Testable code is good code When you let testing drive the implementation A test-driven implementation is testable by definition No refactoring will be necessary
87. What if? Design Testing Write failing tests Implementation Get the tests to pass
90. TDD Is Great, But⊠TDD works But Thinking of requirements in terms of tests is NOT easy Syllogism Tests verify requirements Requirements define behavior Tests verify behavior Neuro-Linguistic Programming (NLP) suggests that the words we use influence the way we think What if we start using terminology that focuses on the behavioral aspects of the system rather than testing?
91. The BDD Way BDDÂ is simply a rephrased TDD The focus on behavior Bridges the gap between Business users and Technologists Makes the development goals and priorities more aligned with business requirements TDD vs. BDD Verification State-Based Bottom-Up approach Specification Interaction-Based Outside-In Approach
92. The BDD Way âBehavior-Driven Development (BDD) is about implementing an application by describing it from the point of view of its stakeholdersâ â Jbehave.org
93. BDD Concepts Story A description of a feature that has business value As a [Role], I want to [Feature] So that I [Value] Sounds familiar? Agile for you!
94. BDD Concepts Scenario A description of how the user expects the system to behave using a sequence of steps Step Can be a context, an event, or an outcome Given [Context] When [Event] Then [Outcome]
95. BDD in Java JBehave Very powerful and flexible Well-documented Separation of story files from code http://jbehave.org EasyB http://www.easyb.org/ Concordion http://www.concordion.org/
97. The Quadratic Equation 3 possible data combinations that must be tested Coefficients yielding a negative discriminant Coefficients yielding a discriminant equals to zero Coefficients yielding a positive discriminant 3 different outcomes The equation has no real solution The equation has one real solution The equation has two real solution 3 different basis paths
98. BDD with JBehave Write the story Map the steps to a POJO @Given @When @Then Configure the stories @Configure Run the stories @RunWith(AnnotatedEmbedderRunner.class) @UsingEmbedder @UsingSteps View Reports
99. The Code quadraticEquation.story https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/domain/quadraticEquation.story QuadraticEquationStories.java https://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/domain/QuadraticEquationStories.java
101. Tools Code Coverage Cobertura http://cobertura.sourceforge.net/ EMMA http://emma.sourceforge.net/ Continuous Integration On the server: Jenkins/Hudson http://jenkins-ci.org/ On your IDE: Infinitest http://infinitest.github.com/
103. Material The Slides http://www.slideshare.net/PolymathicCoder The Code https://github.com/PolymathicCoder/LeTourDeXUnit The Speaker Email: abdelmonaim.remani@gmail.com Twitter: @polymathiccoder LinkedIn: http://www.linkedin.com/in/polymathiccoder