Adding Unit tests to your Java project May 25, 2010
Tweet
Why add unit testing to Automation projects
There are several advocates of unit testing and they all call out several points about how unit tested code ends up producing lesser defects and higher quality code for the customers. This is even true for test automation frameworks. One could also argue that this is more important for test automation code because you don’t have dedicated QA engineers to test your framework.
Steps
These steps show how to setup JUnit, write unit tests for a java class and then execute them using ant. The assumption here is that you have an environment similar to the one defined in the Creating your Java project workspace post. The key is to have your unit test classes in a different directory than your product code (in this case test automation framework code).
Lets assume we have a Java utility class that reverses a string, words in a string, or the order of words in a string. This is how the class would look like:
package net.qaautomation.examples.utils;
import java.util.StringTokenizer;
/**
* String utilities.
*
* @author Rahul Poonekar
* @since May 23, 2010
*/
public class StringUtil {
public static String invertCharacters(String string) {
char[] characters = string.toCharArray();
char[] invertedCharacters = new char[characters.length];
for (int i = 0; i < characters.length; i++) {
invertedCharacters[invertedCharacters.length - i - 1] = characters[i];
}
return String.copyValueOf(invertedCharacters);
}
public static String reverseWords(String string) {
StringTokenizer tokenizer = new StringTokenizer(string, " ");
StringBuffer buffer = new StringBuffer();
while (tokenizer.hasMoreElements()) {
buffer.insert(0, ' ').insert(0, tokenizer.nextElement());
}
int length = buffer.length();
if (length > 0) {
buffer.deleteCharAt(length-1);
}
return buffer.toString();
}
public static String invertWords(String string) {
StringTokenizer tokenizer = new StringTokenizer(string, " ");
StringBuffer buffer = new StringBuffer();
while (tokenizer.hasMoreElements()) {
buffer.append(invertCharacters((String) tokenizer.nextElement())).append(" ");
}
return buffer.toString().trim();
}
}
Create JUnit test class
Lets assume that this java code is in located at <project_dir>/java/src/net/qaautomation/examples/utils/StringUtil.java. Let us now create the JUnit test class located in the same package but instead of creating it under src let us keep it under test. So the location would look like <project_dir>/java/test/net/qaautomation/examples/utils/StringUtil.java
package net.qaautomation.examples.utils;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* JUnit test for StringUtil.
*
* @author Rahul Poonekar
* @since May 23, 2010
*/
public class StringUtilJUnitTest {
@Test
public void simpleStringReverse() {
assertTrue(StringUtil.invertCharacters("Rahul").equals("luhaR"));
}
@Test
public void MultipleWordsStringReverse() {
assertTrue(StringUtil.invertCharacters("Rahul advocates test automation").
equals("noitamotua tset setacovda luhaR"));
}
@Test
public void simpleWordReverse() {
assertTrue(StringUtil.reverseWords("Rahul advocates test automation").
equals("automation test advocates Rahul"));
}
@Test
public void emptyStringReverse() {
assertTrue(StringUtil.reverseWords("").equals(""));
}
@Test
public void simpleWordInverse() {
assertTrue(StringUtil.invertWords("Rahul advocates test automation").
equals("luhaR setacovda tset noitamotua"));
}
}
Create Ant targets
Let us now create ant targets to compile and execute your unit tests. In your build.xml file you should add ant targets similar to these:
<property name="unittest.src.dir" value="${basedir}/java/test"/>
<property name="unittest.classes.dir" value="${basedir}/java/classes/test"/>
<property name="unittest.jar" value="${build.dir}/unittest.jar"/>
<path id="unittest.classpath">
<path refid="testautomation.classpath"/>
<file file="${unittest.jar}"/>
</path>
<target name="build-unittest" depends="resources, build">
<mkdir dir="${unittest.classes.dir}"/>
<mkdir dir="${build.dir}"/>
<javac debug="true"
srcdir="${unittest.src.dir}"
destdir="${unittest.classes.dir}"
classpathref="testautomation.classpath"/>
<jar basedir="${unittest.classes.dir}" jarfile="${unittest.jar}"/>
</target>
<target name="run-unittests" depends="build-unittest" description="run all unit tests">
<junit fork="yes" haltonfailure="yes">
<batchtest>
<fileset dir="${unittest.classes.dir}" includes="**/*Test.class"/>
</batchtest>
<formatter type="plain" usefile="false" />
<classpath refid="unittest.classpath" />
</junit>
</target>
NOTE: These targets would work as-is if you have a build.xml that was created by following instructions in the Creating your Java project workspace post.
Executing your unit tests
Now you can run your tests using
ant run-unittests
You should get results that look like this:
Buildfile: build.xml
resources:
build:
build-unittest:
run-unittests:
[junit] Testsuite: net.qaautomation.examples.utils.StringUtilJUnitTest
[junit] Tests run: 5, Failures: 0, Errors: 0, Time elapsed: 0.055 sec
[junit]
[junit] Testcase: simpleStringReverse took 0.018 sec
[junit] Testcase: MultipleWordsStringReverse took 0.001 sec
[junit] Testcase: simpleWordReverse took 0.001 sec
[junit] Testcase: emptyStringReverse took 0 sec
[junit] Testcase: simpleWordInverse took 0 sec
BUILD SUCCESSFUL
Total time: 0 seconds
If you get an error instead that says
the class org.apache.tools.ant.taskdefs.optional.junit.JUnitTask was not found
then that means you do not have the ant optional jars. If you are using ubuntu you can easily get them by running
sudo apt-get install ant-optional
Posted by Rahul Poonekar in : Integration
