junit

24
Junit At the forefront of Test Driven Development

Upload: anakin

Post on 06-Jan-2016

56 views

Category:

Documents


0 download

DESCRIPTION

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 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Junit

JunitAt the forefront of Test Driven Development

Page 2: Junit

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

Page 3: Junit

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

Page 4: Junit

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

Page 5: Junit

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>

Page 6: Junit

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

Page 7: Junit

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”) );

Page 8: Junit

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

Page 9: Junit

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

Page 10: Junit

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

Page 11: Junit

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

Page 12: Junit

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

Page 13: Junit

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

Page 14: Junit

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

Page 15: Junit

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

}}

Page 16: Junit

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 );}

}

Page 17: Junit

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 );

}

}

Page 18: Junit

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

}

}

Page 19: Junit

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

Page 20: Junit

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;

}

}

Page 21: Junit

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

}

}

Page 22: Junit

More about Junit

Tests

TestSuites

Assertions

Page 23: Junit

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

Page 24: Junit

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