Upload
abdelmonaim-remani
View
1.628
Download
4
Tags:
Embed Size (px)
DESCRIPTION
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.
Citation preview
License
● Creative Commons Attribution-NonCommercial 3.0 Unported
● http://creativecommons.org/licenses/by-nc/3.0/
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
WarningThis presentation is very long and covers a lot of material
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
There Will Be Code!
Part I - Unit Testing
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
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?
xUnit and 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
Good Test Data Include
● Valid data
● Invalid data / Boundary conditions● Different Formats● Different Order● Wide Range● Null data● Error Conditions
Good Tests
● Cover all possible basis paths
● Have Self-Describing Names
● Are Cohesive● Independent of each other● Reliable● Repeatable● Fast
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
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
Vanilla Is Boring
Story Time
The Quadratic Equation
The Quadratic Equation
The Code
● QuadraticEquation.java● https://github.com/PolymathicCoder/LeTourDeXUnit/blob/
master/src/main/java/com/polymathiccoder/talk/xunit/domain/QuadraticEquation.java
Testing the Quadratic EquationVanilla Unit Tests
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
JUnit Annotations
● Test suites● @RunWith● Naming Convention
● <Class Name>Test
● Test fixtures● Set Up
● @Before
● @BeforeClass
● Tear Down● @After
● @AfterClass
JUnit Annotations
● Tests● @Test● Naming Convention
● <Method Name>_<State Under Test>_<Expected Behavior>
● Assertions● assertTrue, assertEquals, assertThat, assertNull,
etc…
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
The Code
● QuadraticEquationTest.java● https://github.com/PolymathicCoder/LeTourDeXUnit/blob/
master/src/test/java/com/polymathiccoder/talk/xunit/domain/QuadraticEquationTest.java
Stay PUT
Testing the Quadratic EquationParameterized Unit Tests
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
Libra-paloozaFeaturing the coolest JUnit extensions and libraries
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/
The Code
● QuadraticEquationParameterizedTest.java● https://github.com/PolymathicCoder/LeTourDeXUnit/blob/
master/src/test/java/com/polymathiccoder/talk/xunit/domain/QuadraticEquationParameterizedTest.java
All Those Theories
Story Time
The River Crossing Puzzle
The River Crossing Puzzle
The Code
● RiverCrossing.java● https://github.com/PolymathicCoder/LeTourDeXUnit/blob/
master/src/main/java/com/polymathiccoder/talk/xunit/domain/RiverCrossing.java
Testing the River Crossing PuzzleTheories
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
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
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
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
The Code
● RiverCrossingTheory.java● https
://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/domain/RiverCrossingTheory.java
All That CRUD
Story Time
The Employee Database
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
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
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
Testing the Employee DatabaseAll that CRUD
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
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…
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
Libra-paloozaFeaturing the coolest JUnit extensions and libraries
Libra-palooza
● HamSandwich● http://code.google.com/p/hamsandwich/
● Hamcrest Text Patterns● http://code.google.com/p/hamcrest-text-patterns/
The Code
● EmployeeDaoCollectionImplTest.java● https://github.com/PolymathicCoder/LeTourDeXUnit/blob/
master/src/test/java/com/polymathiccoder/talk/xunit/repository/EmployeeDaoCollectionImplTest.java
Libra-paloozaFeaturing the coolest JUnit extensions and libraries
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/
Libra-palooza
● Unitils● Database testing, etc…● Integrates with DBUnit
● Annotations
● @RunWith(UnitilsJUnit4TestClassRunner.class)
● @DataSet
● @ExpectedDataSet
● @TestDataSource
● http://unitils.org
The Code
● EmployeeDaoDbImplTest.java● https://
github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/test/java/com/polymathiccoder/talk/xunit/repository/EmployeeDaoDbImplTest.java
Fakery
The Mailer
The Mailer
● Simple email sender that uses the JavaMail API
● 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/
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
Libra-paloozaFeaturing the coolest JUnit extensions and libraries
Libra-palooza
● XMLUnit● http://xmlunit.sourceforge.net/
● HTMLUnit● http://htmlunit.sourceforge.net/
● HttpUnit● http://httpunit.sourceforge.net/
● Spring Test● http://static.springsource.org/spring/docs/3.1.x/spri
ng-framework-reference/html/testing.html
Mockery
Story Time
The Egyptian Plover & the Nile Crocodile
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
The Code
● EgyptianPlover.java● https
://github.com/PolymathicCoder/LeTourDeXUnit/blob/master/src/main/java/com/polymathiccoder/talk/xunit/domain/EgyptianPlover.java
Testing the Egyptian Plover & the Nile CrocodileMocking
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
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
Egyptian
Plover
Nile Crocodile
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
Egyptian
Plover
Nile Crocodile
Libra-paloozaFeaturing the coolest JUnit extensions and libraries
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/
The Code
● EgyptianPloverTest.java● https://github.com/PolymathicCoder/LeTourDeXUnit/blob/
master/src/test/java/com/polymathiccoder/talk/xunit/domain/EgyptianPloverTest.java
This is a digitally constructed image from the Warren Photographic Image Library of Nature and Pets
http://www.warrenphotographic.co.uk/
Miscellaneous Topics
Test Suites and Groups
● Annotations● @Category● @RunWith(Categories.class)● @IncludeCategory● @ExcludeCategory● @SuiteClasses
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
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/
Part II – TDDTest-Driver Development
This Is How We Have Been Doing It
Design Implementation Testing
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
What if?
● Design
● Testing● Write failing tests
● Implementation● Get the tests to pass
Design Testing Implementation Testing
The TDD WayDesign
Testing
ImplementationTesting
Refactor
Part III – BDDBehavior-Driver
Development
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?
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. BDDVerification
State-Based
Bottom-Up approach
Specification
Interaction-Based
Outside-In Approach
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
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!
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]
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/
Testing the Quadratic EquationStories, Scenarios, and Steps
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
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
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
Part IV - Tools
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/
Q & A
Material
● The Slides● http://www.slideshare.net/PolymathicCoder
● The Code● https://github.com/PolymathicCoder/LeTourDeXUnit
● The Speaker● Email: [email protected]● Twitter: @polymathiccoder● LinkedIn: http
://www.linkedin.com/in/polymathiccoder
Thank You