One of the things which I want to start dong more using automated testing for my web applications. jsUnit is the most widely-used testing framework for Ajax applications. jsUnit, along with many other unit-testing frameworks are based off of the Java framework JUnit. Since I’ve been meaning to try out JUnit anyways, I figured now would be as good a time as any. Although the usual way to use JUnit is through Eclipse or an Ant task, I like to do things manually first. Once you can do it from the command-line, testing through Eclipse should be easy.
There seem to be two different versions of JUnit which are widely used: 3.x and 4.x. They are quite different from one another and require different approaches. I’m going to give a simple example of both, starting with version 3.x.
—————————————————————————————–
JUnit 3
—————————————————————————————–
1. Install JUnit:
$ sudo aptitude install junit
To find out where JUnit was installed to you can use the Debian package management tool, dpkg:
$ dpkg -L junit | grep junit.jar
...
/usr/share/java/junit.jar
/usr/share/ant/lib/junit.jar
The “-L” lists the locations of all of the files installed by a particular package. I used grep to have it only show the junit.jar files.
2. Next, set the CLASSPATH environmental variable to point to the JUnit jar file:
$ CLASSPATH=.:/usr/share/java/junit.jar
Don’t forget to include the working directory (the period just after the equals sign) in the classpath, otherwise you will get a “Class not found” error when you try to run the tests.
Also, using the above will only set the variable for your current shell session. To make it stick, edit the .bashrc file in your home directory and add the line:
export CLASSPATH=.:/usr/share/java/junit.jar
3. Test the installation to make sure everything is working:
$ java junit.textui.TestRunner
Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class
Nothing exciting going on here, but at least it seems to be working. This is the same we will initiate the actual testing once we have set some tests up.
4. Create a file called “MyTest1.java”. We will do two tests, one of which should pass and the other should fail.
import junit.framework.*;
public class MyTest1 extends TestCase {
// Normally you would be testing some function's output, and not some variable you set...
public void testOne() {
int a = 2;
int b = 2;
int sum = a + b;
int expected = 4;
assertEquals(sum, expected); // 2 + 2 = 4?
}
//This test should fail...
public void testTwo() {
int a = 2;
int b = 2;
int sum = a + b +1; // Just pretend that "+1" was a mistake you overlooked
int expected = 4;
assertEquals(sum, expected); // 2 + 2 = 5?
}
}
5. Compile it and run the tests:
$ javac MyTest1.java $ java junit.textui.TestRunner MyTest1 ..F Time: 0.004 There was 1 failure: 1) testTwo(MyTest1)junit.framework.AssertionFailedError: expected: but was: at MyTest1.testTwo(MyTest1.java:20) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) FAILURES!!! Tests run: 2, Failures: 1, Errors: 0
Notice at the bottom it says that two tests were run, one of which failed. This was just as we expected! Now lets try something similar with JUnit 4.
—————————————————————————————–
JUnit 4
—————————————————————————————–
JUnit4 should be installed to the same place as JUnit3. Don’t forget to update the CLASSPATH though so that it points to “junit4.jar” instead of “junit3.jar”. The format of the tests is pretty similar but the imports are different and you also have to use the @TEST tag above your test functions (although the functions themselves no longer have to be named “test…”). Also, pay attention to the command used to run the tests: is different from that command used in JUnit 3.
$ sudo aptitude install junit4
$ CLASSPATH=.:/usr/share/java/junit4.jar
$ java org.junit.runner.JUnitCore
JUnit version 4.3.1
Time: 0.001
OK (0 tests)
MyTest2.java:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class MyTest2{
@Test
public void testOne() {
int a = 2;
int b = 2;
int sum = a + b;
int expected = 4;
assertEquals(sum, expected); // 2 + 2 = 4?
}
@Test
public void testTwo() {
int a = 2;
int b = 2;
int sum = a + b +1;
int expected = 4;
assertEquals(sum, expected); // 2 + 2 = 5?
}
}
Compile & Run:
$ javac MyTest2.java $ java org.junit.runner.JUnitCore MyTest2 JUnit version 4.3.1 ..E Time: 0.019 There was 1 failure: 1) testTwo(MyTest2) java.lang.AssertionError: expected: but was: at org.junit.Assert.fail(Assert.java:71) at org.junit.Assert.failNotEquals(Assert.java:451) at org.junit.Assert.assertEquals(Assert.java:99) at org.junit.Assert.assertEquals(Assert.java:116) at MyTest2.testTwo(MyTest2.java:21) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99) at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81) at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34) at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75) at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45) at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66) at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35) at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42) at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34) at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52) at org.junit.internal.runners.CompositeRunner.run(CompositeRunner.java:29) at org.junit.runner.JUnitCore.run(JUnitCore.java:130) at org.junit.runner.JUnitCore.run(JUnitCore.java:109) at org.junit.runner.JUnitCore.run(JUnitCore.java:100) at org.junit.runner.JUnitCore.runMain(JUnitCore.java:81) at org.junit.runner.JUnitCore.main(JUnitCore.java:44) FAILURES!!! Tests run: 2, Failures: 1
Got it! Next up: JSUnit.
—————————————————————————————–
For more JUnit info, here are some resources which may be helpful:
JUnit 3 Resources:
[1] http://www.jaredrichardson.net/articles/junit-tutorial.html
[2] http://junit.sourceforge.net/doc/testinfected/testing.htm
[3] http://supportweb.cs.bham.ac.uk/documentation/tutorials/docsystem/build/tutorials/junit/junit.html
[4] http://clarkware.com/articles/JUnitPrimer.html
[5] http://en.wikipedia.org/wiki/JUnit
JUnit 4 Resources:
[1] http://pub.admc.com/howtos/junit4x/
[2] http://junit.sourceforge.net/doc/faq/faq.htm
[3] http://junit.sourceforge.net/doc/cookbook/cookbook.htm
[4] http://today.java.net/pub/a/today/2006/12/07/junit-reloaded.html
[5] http://www.cavdar.net/2008/07/21/junit-4-in-60-seconds/
[6] http://www.ibm.com/developerworks/edu/j-dw-java-junit4.html
Very good article showing how to install junit. Thanks a lot
An excellent article, friend. Thanks for all