0% found this document useful (0 votes)
70 views35 pages

Junit Training: Chris Yeung 8 Sept, 2006

This document provides an introduction and overview of JUnit, a unit testing framework for Java. It discusses why testing is important, what JUnit is and how it works, best practices for writing tests, integrating tests with build tools like Ant, and designing code for testability. Key aspects covered include writing test cases with assertions, organizing tests into suites, running tests from the command line or IDEs, using mock objects, and testing code that interacts with external resources.

Uploaded by

jskathirvel
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
70 views35 pages

Junit Training: Chris Yeung 8 Sept, 2006

This document provides an introduction and overview of JUnit, a unit testing framework for Java. It discusses why testing is important, what JUnit is and how it works, best practices for writing tests, integrating tests with build tools like Ant, and designing code for testability. Key aspects covered include writing test cases with assertions, organizing tests into suites, running tests from the command line or IDEs, using mock objects, and testing code that interacts with external resources.

Uploaded by

jskathirvel
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 35

Junit Training

Chris Yeung 8th Sept, 2006

Introduction
JUnit is a regression testing framework Written by Erich Gamma and Kent Beck.

Used by developers to implement unit tests in Java


Goal: Accelerate programming and increase the quality of code. Part of XUnit family (HTTPUnit, Cactus), CppUnit

Why test? Why Junit?


Automated tests prove features Tests retain their value over time and allows others to prove the software still works (as tested). Confidence, quality, sleep Effective, open source, integrated Get to code sooner by writing tests.

What is Junit?
Test framework provides tools for:
assertions running tests aggregating tests (suites) reporting results

Philosophy always the same:


Let developers write tests. Make it easy and painless.

Test early and test often

Test infected
Its a Good Thing, no penicillin needed Immediate gratification with build iterations
Start with The Simplest Thing That Could Possibly Work.
Iterate by successive application of design pattern.

Break the cycle of more pressure == fewer tests Reduce code captivity
If others can test it, others can work on it.

Junit Mechanics
Define a subclass of TestCase. Override the setUp() & tearDown()methods. Define one or more public testXXX()methods
Exercise the object(s) under test. Asserts the expected results.

Define a static suite() factory method


Create a TestSuite containing all the tests.

Optionally define main() to run the TestCase in batch mode.

Junit Mechanics

Simple Testcase
public class StringTest extends TestCase { protected void setUp(){ /* run before */} protected void tearDown(){ /* after */ } public void testSimpleAdd() { String s1 = new String(abcd); String s2 = new String(abcd); assertTrue(Strings not equal, s1.equals(s2)); } public static void main(String[] args){ junit.textui.TestRunner.run (suite ()); } }

Simple Testcase (cont.)


public static Test suite (){ suite = new TestSuite (StringTest"); String tests = System.getProperty("tests"); if (tests == null){ suite.addTest(new TestSuite(StringTest.class)); }else{ StringTokenizer tokens = new StringTokenizer(tests, ","); while (tokens.hasMoreTokens()){ suite.addTest(new StringTest((String)tokens.nextToken())); } } return suite; }

<JUnit Report>

assertEquals(expected, actual) assertEquals(String message, expected, actual) This method is heavily overloaded: arg1 and arg2 must be both objects or both of the same primitive type For objects, uses your equals method, if you have defined it properly, as public boolean equals(Object o)--otherwise it uses == assertSame(Object expected, Object actual) assertSame(String message, Object expected, Object actual) Asserts that two objects refer to the same object (using ==) assertNotSame(Object expected, Object actual) assertNotSame(String message, Object expected, Object actual) Asserts that two objects do not refer to the same object

Other assertion methods

Other assertion methods


assertNull(Object object) assertNull(String message, Object object) Asserts that the object is null assertNotNull(Object object) assertNotNull(String message, Object object) Asserts that the object is null fail() fail(String message) Causes the test to fail and throw an AssertionFailedError Useful as a result of a complex test, when the other assert methods arent quite what you want

What should I test?


Tests things which could break Tests should succeed quietly.
Dont print Doing foodone with foo! Negative tests, exceptions and errors

What shouldnt I test


Dont test set/get methods

Dont test the compiler

Fixtures
Handle common objects under test setup() and tearDown() used to initialize and release common objects. Used to insure there are no side effects between tests. Enforce the test independence rule, test execution order is not guarunteed.

Execrise
Write a testcase to test 3 method of java.util.ArrayList

Test Suites
public static void main (String [] args){ junit.textui.TestRunner.run (suite ()); }

public static Test suite (){ suite = new TestSuite ("AllTests"); suite.addTest (new TestSuite (AllTests.class)); suite.addTest (StringTest.suite());
public void testAllTests () throws Exception{ assertTrue (suite != null); } }

TestRunners
Text
Lightweight, quick quiet Run from command line
java StringTest ....... Time: 0.05
Tests run: 7, Failures: 0, Errors: 0

TestRunners - Swing
Run with java junit.swingui.TestRunner

Test Runners - Eclipse

Automating testing (Ant)


Junit Task
<target name="test" depends="compile-tests"> <junit printsummary="yes" fork="yes"> <classpath> <pathelement location="${build}" /> <pathelement location="${build}/test" /> </classpath> <formatter usefile="yes" type="plain" /> <test name="AllTests" /> </junit> </target>

Ant Batch mode


<target name="batchtest" depends="compile-tests"> <junit printsummary="yes" fork="yes" haltonfailure="no"> <classpath> <pathelement location="${build.dir}" /> <pathelement location="${build.dir}/test" /> </classpath> <formatter type="plain" usefile="yes"/> <batchtest fork="yes" todir=""> <fileset dir="${test.dir}"> <include name="**/*Test.java" /> </fileset> </batchtest> </junit> </target>

Designing for testing


Separation of interface and implementation
Allows substitution of implementation to tests

Factory pattern
Provides for abstraction of creation of implementations from the tests.

Strategy pattern
Because FactoryFinder dynamically resolves desired factory, implementations are plugable

Design for testing - Factories


new only used in Factory Allows writing tests which can be used across multiple implementations. Promotes frequent testing by writing tests which work against objects without requiring extensive setup
extra-container testing.

Design for testing - Mock Objects


When your implementation requires a resource which is unavailable for testing External system or database is simulated. Another use of Factory, the mock implementation stubs out and returns the anticipated results from a request.

Example of using Mock Object


import org.jmock.*; class PublisherTest extends MockObjectTestCase { public void testOneSubscriberReceivesAMessage() { // set up, subscriber can be any class Mock mockSubscriber = mock(Subscriber.class); Publisher publisher = new Publisher(); publisher.add((Subscriber) mockSubscriber.proxy());

final String message = "message";


// expectations mockSubscriber.expects(once()).method("receive").with( eq(message) ); // execute publisher.publish(message); } }

Of course, you can write mock yourself by implement interface with simple implementation

Testing with resources (EJB/DB)


Use fixtures to request resource connection via factory, could be no-op. Use vm args or resource bundle to drive which factory is used.

Data initialization/clearing handled by fixtures to preserve order independence of tests.

Develop testcase with database using abstract base class


public abstract class DatabaseTestCase extends TestCase{ protected final void setUp() throws SQLException, IOException { resetData(); DefaultDataManager.setupDefaultData(); databaseSetUp(); } protected final void tearDown() throws SQLException { this.databaseTearDown(); this.getConnection().close(); } protected void databaseSetUp() throws SQLException, IOException { } protected void databaseTearDown() throws SQLException { } public final Connection getConnection() { return currentContext.connection; } }

In-container unit testing


There are tools like cactus and StrutsTestCase Excellent for testing:
EJB Servlets, Filters, Taglibs Container-dependent frameworks, like Struts

JUnit Best Practices



Separate production and test code But typically in the same packages Compile into separate trees, allowing deployment without tests Dont forget OO techniques, base classing Test-driven development
1. 2. 3. 4. 5. Write failing test first Testing for Exceptions Test then Fix Test then Refactor Where should I put my test files?

Write failing test first


Write your test first, or at least at the same time

Test what can break


Create new tests to show bugs then fix the bug Test driven development says write the test then make it pass by coding to it.

Testing for Exceptions


public void testExpectException() { String s1 = null; String s2 = new String("abcd"); try{ s1.toString(); fail("Should see null pointer"); } catch(NullPointerException ex){ } }

Test then Fix


Bugs occasionally slip through (gasp!) Write a test first which demonstrates the error. Obviously, this test is needed. Now, fix the bug and watch the bar go green! Your tests assure the bug wont reappear.

Test then Refactor


Once the code is written you want to improve it. Changes for performance, maintainability, readability.

Tests help you make sure you dont break it while improving it.
Small change, test, small change, test...

Where should I put my test files?


You can place your tests in the same package and directory as the classes under test. For example:
src com xyz SomeClass.java SomeClassTest.java An arguably better way is to place the tests in a separate parallel directory structure with package alignment. For example: src com xyz SomeClass.java test com xyz SomeClassTest.java These approaches allow the tests to access to all the public and package visible methods of the classes under test.

Resources
http://www.junit.org http://www.xprogramming.com http://www106.ibm.com/developerworks/java/library /j-junitmail/index.html http://jakarta.apache.org/ant

You might also like