1 / 24

Junit

Junit. At the forefront of Test Driven Development. Some Distinctions. Unit Testing Hand testing of components Automated Unit Testing Automatic component testing run every build Integration Testing Hand testing a component based system Automated Integration Testing

anakin
Download Presentation

Junit

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Junit At the forefront of Test Driven Development

  2. Some Distinctions • Unit Testing • Hand testing of components • Automated Unit Testing • Automatic component testing run every build • Integration Testing • Hand testing a component based system • Automated Integration Testing • Automatic system integration and testing following successful Unit testing

  3. Motivations for Unit Testing • Analgous to Light Manufacturing • enforce component quailty and stop the assembly line (at compilation) rather than testing for quality at the assembly (integration) stage • Higher component quality, lower bug count • Higher component quality leads to reduced cycle times • This leads to a higher rate of adaptability to changing requirements

  4. Motivations for Automated Unit Testing • Efficiency • automated testing defeats developer excuses to skip writing and running tests • Code Quality • Incorporating automated unit testing into the build mitigates checkin of poor code • Design Quality • Bold refactorings lead to modular code • Modular code is more adaptive to change • Confidence • a test suite gives instant feedback to developers making changes, allowing bold refactorings

  5. Using Junit from Ant • Make sure junit.jar is in your classpath • Taskdef <taskdef class=“…” name=“junit”/> • Junit tag and test tags <junit haltonfailure=“yes”> <test class=“…”/> </junit>

  6. Writing a Junit Test • Create your class • Use a method of your class • Use Assertions to test the output of the method • junit.framework.Assert • Assert.assertTrue( String, boolean ) • Assert.assertNull( String, Object ) • Assert.assertEquals( String, Object, Object ) • Assertions print out error messages

  7. Creating a Junit Test Suite • Tests typically extend TestSuite • TestSuite follows the Composite pattern • TestSuites aggregate other test suites • Usually one suite per java package • com.doofus.framework • Test*.java • frameworkSuite.java • Include tests by adding them to the suite • Suite.add( new FooTest(“TestCreate”) );

  8. Designing a Unit Test • Be aware of the issues distinguishing various types of tests • http://jakarta.apache.org/cactus/ good overview • Code Logic Testing • out of application context • Integration Unit Testing • inside application context • Functional Unit Testing • testing from outside your application

  9. What resources do your classes need to be tested? • What level of coupling does your design indicate? • Inability to decouple classes leads right to integration level testing • Ability to decouple classes leads to unit testing • Design your code to be unit tested • Unit Testing limits the scope of testing • to the component being tested, • not integration with other components • substitute dependencies with mock objects • Integration Testing tests features using all integrated components

  10. Unit Testing a Class with Mock Objects • Classes not requiring an application context can be unit-tested easily • Static utility methods, basic entity classes lacking control features • Interaction with other classes should be against mock objects • Test a control class against a mock entity class • Application classes that require other application classes can be contextualized in a mock application or with mock application classes

  11. Mock Objects • Mock objects respect an interface • Implement a business interface • Extend a business class but nullify it’s logic • Mock objects often track their state with flags • You pass a mock entity into a controller, stimulate the controller, and test to see that variables have changed inside the mock object • Mock objects can verify their own state and might have a verify() method • Possibility of many mock implementations of a business class, possilby one per test, if the verify() methods are polymorphic

  12. Mock Objects and Decoupling • Be careful with that “new” statement in your business classes • You don’t want to test other classes while testing this one • new can only select one implementation • Alternatives • Mock extension of business implementations • Inversion of control

  13. Generation of mock objects • Invoking Mock object class generators are a worthwhile step in your build automation process • EasyMock • MockMaker • Hand tune and refactor mocks as necessary

  14. Factory methods (protected) • Create a mock object as a subclass of your production implementation • Invoke a mock extension of your business class during testing • All new statements are refactored into protected factory methods that are overridden by mock implementations • Mock factory methods return mock objects

  15. Before Factory Method Refactoring public class AuthToken { public void authenticate() throws SecurityVetoException; } public class UserManager { public AuthToken authenticate( String login, String passwd ) { AuthToken a = new AuthToken( login, passwd ); a.authenticate(); Return a } }

  16. Refactored with Factory method interface AuthToken { … } public class UserToken implements AuthToken { … } public class UserManager { public AuthToken authenticate( String login, String passwd ) { AuthToken token = createAuthToken(login, passwd); token. .authenticate(); return token; } protected AuthToken createAuthToken( String login, String passwd ) { return new UserToken( login, passwd ); } }

  17. Mock Extends Business Impl public class MockUserManager extends UserManager { private classs MockAuthToken extends UserToken { boolean m_authFlag = false; public void authenticate() { m_authFlag = true; } public void validate() { Assert.assertNotNull( m_login ); Assert.assertNotNull( m_passwd ); Assert.assertTrue( m_authFlag ); } } protected AuthToken createAuthToken( String login, String passwd() { return new MockAuthToken( login, passwd ); } }

  18. UnitTest uses extending class public class UserManagerTest extends TestSuite { public UserManagerTest() { super(“UserManagerTest”); suite.add( new UserManagerTest(“testAuthentication”) ); } public void testAuthentication() { UserManager u = new MockUserManager(); MockAuthToken mock = (MockAuthToken) u.authenticate( “Santa”, “Claus” ); mock.validate(); //throws X if invalid, test fails } }

  19. Inversion of control • classes and components rely on composition rather than extension • Reduces use of inheritance • Components do not say “new”, rather contextualization provides resources • Jakarta Avalon is a framework for developing Inversion of Control components • Works well with JNDI

  20. Example of Inversion of Control public class UserManager extends AbstractResourceDependent { private AuthTokenFactory m_authFactory = null; public UserManager() { super(); } public contextualize( Context c ) { super.contextualize( c ); m_authFactory = (AuthTokenFactory) c.get( AuthTokenFactory.HINT ); } public AuthToken authenticate( String login, String passwd ) { AuthToken token = m_authFactory.create( login, passwd ); return token; } }

  21. Example of IOC Unit Test Public class UserManagerTest extends TestSuite { public UserManagerTest() { super(“UserManagerTest”); suite.add( new UserManagerTest(“testAuthentication”) ); } public void testAuthentication() { Resources r = new Resources(); r.put( AuthTokenFactory.HINT, new MockTokenFactory() ); UserManager u = new UserManager(); u.contextualize( r ); MockAuthToken mock = (MockAuthToken) u.authenticate( “Santa”, “Claus” ); mock.validate(); //throws X if invalid, test fails } }

  22. More about Junit Tests TestSuites Assertions

  23. Integration Testing a feature • Integration testing tests one feature of an integrated application • Uses the application context rather than a mock environment • Cactus is a Jakarta project revolving around integration testing web applications

  24. Conclusion • Junit, Ant provide a framework for automated testing • Automated testing of classes focuses debugging effort • Junit can be used for application integration testing as well

More Related