Presentation is loading. Please wait.

Presentation is loading. Please wait.

Junit At the forefront of Test Driven Development.

Similar presentations


Presentation on theme: "Junit At the forefront of Test Driven Development."— 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 Junit tag and test tags

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 overviewhttp://jakarta.apache.org/cactus/ 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


Download ppt "Junit At the forefront of Test Driven Development."

Similar presentations


Ads by Google