Presentation is loading. Please wait.

Presentation is loading. Please wait.

Junit Training Chris Yeung 8 th Sept, 2006. Introduction JUnit is a regression testing frameworkJUnit is a regression testing framework Written by Erich.

Similar presentations


Presentation on theme: "Junit Training Chris Yeung 8 th Sept, 2006. Introduction JUnit is a regression testing frameworkJUnit is a regression testing framework Written by Erich."— Presentation transcript:

1 Junit Training Chris Yeung 8 th Sept, 2006

2 Introduction JUnit is a regression testing frameworkJUnit is a regression testing framework Written by Erich Gamma and Kent Beck.Written by Erich Gamma and Kent Beck. Used by developers to implement unit tests in JavaUsed by developers to implement unit tests in Java Goal: Accelerate programming and increase the quality of code.Goal: Accelerate programming and increase the quality of code. Part of XUnit family (HTTPUnit, Cactus), CppUnitPart of XUnit family (HTTPUnit, Cactus), CppUnit

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

4 What is Junit? Test framework provides tools for:Test framework provides tools for: –assertions –running tests –aggregating tests (suites) –reporting results Philosophy always the same:Philosophy always the same: –Let developers write tests. –Make it easy and painless. –Test early and test often

5 Test infected It’s a Good Thing, no penicillin neededIt’s a Good Thing, no penicillin needed Immediate gratification with build iterationsImmediate 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 testsBreak the cycle of more pressure == fewer tests Reduce code captivityReduce code captivity –If others can test it, others can work on it.

6 Junit Mechanics Define a subclass of TestCase.Define a subclass of TestCase. Override the setUp() & tearDown() methods.Override the setUp() & tearDown() methods. Define one or more public testXXX() methodsDefine one or more public testXXX() methods –Exercise the object(s) under test. –Asserts the expected results. Define a static suite() factory methodDefine a static suite() factory method – Create a TestSuite containing all the tests. Optionally define main() to run the TestCase in batch mode.Optionally define main() to run the TestCase in batch mode.

7 Junit Mechanics

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

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

10

11 Other assertion methods assertEquals( expected, actual ) assertEquals(String message, expected, actual ) 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 ) 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 ) assertNotSame(Object expected, Object actual ) assertNotSame(String message, Object expected, Object actual ) –Asserts that two objects do not refer to the same object

12 Other assertion methods assertNull(Object object ) assertNull(String message, Object object ) assertNull(Object object ) assertNull(String message, Object object ) –Asserts that the object is null assertNotNull(Object object ) assertNotNull(String message, Object object ) assertNotNull(Object object ) assertNotNull(String message, Object object ) –Asserts that the object is null fail() fail(String message ) 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 aren’t quite what you want

13 What should I test? Tests things which could breakTests things which could break Tests should succeed quietly.Tests should succeed quietly. –Don’t print “Doing foo…done with foo!” –Negative tests, exceptions and errors What shouldn’t I testWhat shouldn’t I test –Don’t test set/get methods –Don’t test the compiler

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

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

16 Test Suites public static void main (String [] args){ junit.textui.TestRunner.run (suite ()); junit.textui.TestRunner.run (suite ()); } public static Test suite (){ suite = new TestSuite ("AllTests"); suite.addTest (new TestSuite (AllTests.class)); (new TestSuite (AllTests.class)); suite.addTest (StringTest.suite()); public void testAllTests () throws Exception{ assertTrue (suite != null); assertTrue (suite != null); }}

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

18 TestRunners - Swing Run with java junit.swingui.TestRunnerRun with java junit.swingui.TestRunner

19 Test Runners - Eclipse

20 Automating testing (Ant) Junit Task

21 Ant Batch mode

22 Designing for testing –Separation of interface and implementation Allows substitution of implementation to testsAllows substitution of implementation to tests –Factory pattern Provides for abstraction of creation of implementations from the tests.Provides for abstraction of creation of implementations from the tests. –Strategy pattern Because FactoryFinder dynamically resolves desired factory, implementations are plugableBecause FactoryFinder dynamically resolves desired factory, implementations are plugable

23 Design for testing - Factories new only used in Factorynew only used in Factory Allows writing tests which can be used across multiple implementations.Allows writing tests which can be used across multiple implementations. Promotes frequent testing by writing tests which work against objects without requiring extensive setupPromotes frequent testing by writing tests which work against objects without requiring extensive setup – “extra-container” testing.

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

25 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

26 Testing with resources (EJB/DB) Use fixtures to request resource connection via factory, could be no-op.Use fixtures to request resource connection via factory, could be no-op. Use vm args or resource bundle to drive which factory is used.Use vm args or resource bundle to drive which factory is used. Data initialization/clearing handled by fixtures to preserve order independence of tests.Data initialization/clearing handled by fixtures to preserve order independence of tests.

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

28 In-container unit testing There are tools like cactus and StrutsTestCaseThere are tools like cactus and StrutsTestCase Excellent for testing:Excellent for testing: –EJB –Servlets, Filters, Taglibs –Container-dependent frameworks, like Struts

29 JUnit Best Practices Separate production and test codeSeparate production and test code But typically in the same packagesBut typically in the same packages Compile into separate trees, allowing deployment without testsCompile into separate trees, allowing deployment without tests Don’t forget OO techniques, base classingDon’t forget OO techniques, base classing Test-driven developmentTest-driven development 1.Write failing test first 2.Testing for Exceptions 3.Test then Fix 4.Test then Refactor 5.Where should I put my test files?

30 Write failing test first Write your test first, or at least at the same timeWrite your test first, or at least at the same time Test what can breakTest what can break Create new tests to show bugs then fix the bugCreate new tests to show bugs then fix the bug Test driven development says write the test then make it pass by coding to it.Test driven development says write the test then make it pass by coding to it.

31 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){ }

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

33 Test then Refactor Once the code is written you want to improve it.Once the code is written you want to improve it. Changes for performance, maintainability, readability.Changes for performance, maintainability, readability. Tests help you make sure you don’t break it while improving it.Tests help you make sure you don’t break it while improving it. Small change, test, small change, test...Small change, test, small change, test...

34 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 com xyz xyz SomeClass.java SomeClass.java SomeClassTest.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 com xyz xyz SomeClass.java SomeClass.javatest com com xyz xyz SomeClassTest.java SomeClassTest.java These approaches allow the tests to access to all the public and package visible methods of the classes under test.

35 Resources http://www.junit.orghttp://www.junit.org http://www.xprogramming.comhttp://www.xprogramming.com http://www- 106.ibm.com/developerworks/java/library /j-junitmail/index.htmlhttp://www- 106.ibm.com/developerworks/java/library /j-junitmail/index.html http://jakarta.apache.org/anthttp://jakarta.apache.org/ant


Download ppt "Junit Training Chris Yeung 8 th Sept, 2006. Introduction JUnit is a regression testing frameworkJUnit is a regression testing framework Written by Erich."

Similar presentations


Ads by Google