TestNG

Poll: which test framework do you use?

I’m finding more and more people are using TestNG and JUnit 4, so I’m curious to see what this copasetic poll brings. This is, obviously, Java specific and does make the assumption you actually write tests, man– of course, you can always select the last option if that’s you.

Also, if you are using another hip framework not listed, I’m interested in hearing about it! Leave a comment, man.

Which test framework do you use?
View Results

As always, many thanks for your participation!

Supplementing your diet with Selenium and TestNG

Selenium is a hip testing framework that makes it ooohhh so easy to run user acceptance tests on Web applications. This month’s “In pursuit of code quality” article, entitled “Programmatic testing with Selenium and TestNG” shows you how to run Selenium tests programmatically, using TestNG as the test driver. Once you’ve added TestNG’s flexible testing features to Selenium’s native toolkit, all you need is a little help from DbUnit and Cargo to write fully automated, logically repeatable acceptance tests.

Don’t forget to keep on truckin’ at the “Improve Your Java Code Quality” forum too!

Cosmopolitan fixtures in TestNG

As I’ve written about before, TestNG supports parametric testing quite copaseticly; in fact, not only can you obtain parameters for tests, but TestNG also supports parametric fixtures. This means you can effectively create generic fixture objects that tailor themselves to particular environments.

For example, because it’s my bag, I often find myself needing a hip DbUnit fixture to handle managing a state of a database during testing; however, in order for DbUnit to work, at a minimum, you must provide:

  • a database driver to load
  • a connection URL
  • the database user
  • the database password
  • a path to a seed file

DbUnit uses the first 4 aspects to connect to a database, which it’ll seed with the contents found in item #5. These 5 items are often hard coded in testing scenarios; however, with TestNG’s smokin’ parametric fixtures, you can force the actual values to be defined at test time by placing them into TestNG’s testng.xml file.

First I can define a cosmopolitan DbUnit fixture like so:

public class DatabaseFixture {

 @Parameters({"seed-path","db-driver","db-url","db-user","db-psswrd"})
 @BeforeTest
 public void seedDatabase(String seedpath, String driver,
   String url, String user, String pssword) throws Exception {
  IDatabaseConnection conn =
     this.getConnection(driver, url, user, pssword);
  IDataSet data = this.getDataSet(seedpath);
  try {
   DatabaseOperation.CLEAN_INSERT.execute(conn, data);
  }finally {
   conn.close();
 }
}

private IDataSet getDataSet(String path) throws IOException,
 DataSetException {
  return new FlatXmlDataSet(new File(path));
}

private IDatabaseConnection getConnection(String driver, String url,
  String user, String pssword ) throws ClassNotFoundException,
   SQLException {
  Class.forName(driver);
  Connection jdbcConnection =
   DriverManager.getConnection(url, user, pssword);
  return new DatabaseConnection(jdbcConnection);
 }
}

Note how the tripping 5 items listed earlier are now parameters to this fixture via the Parameters annotation, which decorates the seedDatabase method. Wiring actual values to these parameters is done via the parameter element, which can be placed in TestNG’s testng.xml file as follows:

<suite name="Acceptance Tests">

 <parameter name="seed-path" value="test/conf/seed.xml"/>
 <parameter name="db-driver" value="org.hsqldb.jdbcDriver"/>
 <parameter name="db-url" value="jdbc:hsqldb:hsql://127.0.0.1"/>
 <parameter name="db-user" value="foo"/>
 <parameter name="db-psswrd" value="bar"/>

 <test name="CRUDs" >
  <packages>
   <package name="test.org.acme.web" />
   <package name="test.org.acme.web.fixtures" />
  </packages>
 </test>
</suite>

With these parameters defined in TestNG’s configuration file, I can now vary their values at runtime for different environments by defining different test groups within the testng.xml file– or, I can even use Ant’s replace task to replace these values with environment specific values. Either way, using TestNG’s parametric fixtures is a sure fire way to create generic fixtures that can be reused in different scenarios easily, man! Dig it?

Easily validate GUI components with TestNG-Abbot

As I’ve written about before, TestNG-Abbot is a newly minted testing framework that breathes new life into testing GUI components. If you are currently writing or maintaining Swing or AWT applications, then check out developerWorks‘ “Automate GUI testing with TestNG-Abbot” and you see how surprisingly easy it is to isolate GUI components and then verify them using TestNG-Abbot’s handy fixture objects.

As always, don’t forget to Swing (no pun intended) over to the “Improve Your Java Code Quality” forum and let it all hang out, man!

Become a GUI testing cleric with TestNG-Abbot in 4 steps

As a deacon of developer testing, I found my programming pilgrimage into the realm of TestNG-Abbot quite hip (and you thought I’d use another ecclesiastical word– this is the disco blog, man!). As the current documentation is rather sparse, here are four easy steps to TestNG-Abbot bliss-ness:

  1. First download the current version of TestNG-Abbot, which right now is 0.2. Keep in mind, that this hip version was built using Java 5; accordingly, if you’d like to use this framework, you’ll also be required to run on Java 5.
  2. Then download the current version of Abbot, which is 1.0.0.rc5. TestNG-Abbot is essentially a wrapper for the copasetic Abbot framework and thus delegates a lot of the work to it. It is important to use this version of Abbot as this is what TestNG-Abbot assumes.
  3. Of course, TestNG-Abbot also was designed to be utilized in concert with TestNG; consequently, you’ll need at least TestNG version 5.4. As of right now, the current version of TestNG is 5.5; however, I’ve only tried out things with 5.4.
    • If you want to use the TestNG Eclipse plugin, I’ve got things working with version 5.4.0.0 and it isn’t clear to me which version of TestNG it assumes but my best guess is that it’s following the same versioning scheme as TestNG.
  4. Write a test that employs TestNG-Abbot’s disco AbbotFixture class in concert with it’s GUI component fixture classes, which makes the process of GUI testing quite simple.

Now you’re ready to become a full fledged clergyman– but before you drift into verification veniality with TestNG-Abbot, let me share with you some thoughts.

Keep in mind that in order to actually test a smokin’ GUI, you’ll need a way to create an instance of the GUI that is some descendent of java.awt.Window. While this may seem like common sense, I’ve thus far run into a few different GUIs that either extend from JPanel or are boot strapped via a heavy main method.

If you have challenges with GUI initialization, you may need to specify the dimensions of the GUI explicitly to the AbbotFixture– for example, if you find that when you start running tests that the only thing that pops up is a tinny little GUI, force the GUI’s size via the overloaded showWindow method.

One particularly hip feature of TestNG-Abbot is its collection of GUI fixture classes, which, when used in concert with the AbbotFixture class, make the testing process simple– all you need to do to employ these handy classes is specify the component’s name and your desired behavior and the fixture class handles the rest. Plus, if you’d like to assert certain behavior, the fixture classes have a series of validation methods, which start with should.

For example, below is some code that creates a JTextField for use in a GUI. Note how the JTextField instance is named widgetName. It is this logical name by which you can obtain a handle to this object via the Abbot framework.

private JTextField getWidgetName() {
 if (widgetName == null) {
  widgetName = new JTextField();
  widgetName.setName("widgetName");
  widgetName.setBounds(new Rectangle(109, 20, 71, 26));
 }
 return widgetName;
}

Once you have a handle to a GUI component, you can programmatically change it– like in my case, because it’s my bag baby, I can add text to it via TestNG-Abbot’s TextComponentFixture object like so:

TextComponentFixture text1 = new TextComponentFixture(this.fixture, "widgetName");
text1.enterText("Cab01-21");

In GUIs (and also web applications), the easiest way to verify if things are working correctly is to assert the presence of precise text after some known copasetic event. Consequently, with TestNG-Abbot’s fixture classes, you can assert that a dialog shouldBeModal or that a label displays certain text with the LabelFixture’s shouldHaveThisText method. For example, I can verify that a certain label displays some status text after a click a button:

ButtonFixture bfix = new ButtonFixture(this.fixture, "widgetCreate");
bfix.click();

LabelFixture fix = new LabelFixture(this.fixture, "statusLabel");
fix.shouldHaveThisText("Widget price isn't valid");    

One thing to remember as you write GUI focused tests– changes to the GUI will affect your hip tests and you may not realize it until runtime due to the logical matching of names (note how the names are Strings, man). This is the same issue that affects web tests too, by the way. Abbot’s matching of names, however, is much more robust that positional matching that some frameworks of old utilized.

As you can see, becoming a vicar of GUI validation isn’t too challenging with the nifty combination of the Abbot framework hitched up with the caste and revered…errr, I mean the copasetic and tripping TestNG. Dig it?

Parametric testing show down

One of my favorite features of TestNG is its hip parametric testing ability, which allows you to create generic test cases and then vary the test values– you can use parameters from XML files or even use the DataProvider feature for a more rich parameter type. In fact, for awhile, because it’s my bag baby, I’ve been espousing TestNG’s out of the box parametric testing features as a reason to use TestNG as a opposed to JUnit for higher level testing. JUnit 4 , however, now supports parametric tests– and you’ll find that its parametric testing is rather similar to TestNG’s DataProvider.

For example, in TestNG, if I’d like to create a generic test and vary its parameters, I have to do three things:

  1. Create a generic test whose parameters are the parameterized values
  2. Create a DataProvider method, which feeds the values for the test
  3. Link the DataProvider method to the test via the @Test annotation

Hence, I can create a copasetic generic test method as follows:

public void verifyHierarchies(Class clzz, String[] names)
 throws Exception{
  Hierarchy hier = HierarchyBuilder.buildHierarchy(clzz);
  assertEquals(hier.getHierarchyClassNames(), names, "values were not equal");
}

Then I can create a feeder method as follows:

@DataProvider(name = "class-hierarchies")
public Object[][] dataValues(){
 return new Object[][]{
   {Vector.class, new String[] {"java.util.AbstractList",
      "java.util.AbstractCollection"}},
   {String.class, new String[] {}}
  };
}

Note how I have to declare a name for DataProvider, in my case, I dub it class-hierarchies. I can now link the two methods by using the @Test annotation and setting the dataProvider value to the name of my feeder method:

@Test(dataProvider = "class-hierarchies")

That was fairly disco, no? JUnit 4 takes a somewhat similar approach that requires a bit more legwork though:

  1. Create a generic test that takes no parameters
  2. Create a static feeder method that returns a Collection type and decorate it with the @Parameter annotation
  3. Create class members for the parameter types required in the generic method defined in step 1
  4. Create a constructor that takes these parameter types and correspondingly links them to the class members defined in step 3
  5. Specify the test case be run with the Parameterized class via the @RunWith annotation

If I take the same code above and rework it to use JUnit 4 parameterizations, I first must create the generic test:

@Test
public void verifyHierarchies() throws Exception {
 Hierarchy hier = HierarchyBuilder.buildHierarchy(clzz);
 assertEquals("values were not equal",hier.getHierarchyClassNames(), names);
}

Second, I need to create a dynomite feeder method, which functions much like TestNG in that it requires an Object array with matching parameter types.

@Parameters
public static Collection hiearchyValues() {
 return Arrays.asList(new Object[][] {
  {Vector.class, new String[] { "java.util.AbstractList",
     "java.util.AbstractCollection" } },
  {String.class, new String[] {} } });
}

Note how this method is decorated with the @Parameter annotation, man. Next, because the parameters are of types Class and String[], I create two class members:

private Class clzz;
private String[] names;

Step 4 requires I create a constructor, which links values:

public HierarchyBuilderParameterTest(Class clzz, String[] names) {
 this.clzz = clzz;
 this.names = names;
}

Lastly, make sure you specify at the class level that this test be run with the Parameterized class like so:

@RunWith(Parameterized.class)

As you can see, JUnit makes you jump through a few more hoops, yet the fundamental requirements are quite similar to TestNG’s DataProvider feature. When push comes to shove, I still find TestNG’s semantics much simpler, but it’s nevertheless a disco feature to find in JUnit 4. Dig it?

Copasetic categorization with TestNG

Implementing test categories with TestNG couldn’t be any more copasetic, man! With TestNG’s group annotation, logically dividing tests by category (like unit, component, or system) is as easy as applying a specific tag to a desired test– then bingo, baby!

I’d explain how to do it all here, but the tripping crew at Dev2Dev has just published “Test Categorization Techniques with TestNG” by yours truly! Outta sight!

Four steps to TestNG nirvana

Getting started with TestNG couldn’t be easier! First, define a POJO– note that your disco POJO doesn’t need to extend anything specific:

public class HierarchyTest {

}

Next, define a tripping test, which can follow any naming pattern you see fit. The test’s accessibility modifier doesn’t matter either, man.

import java.util.Vector;         

public class HierarchyTest {   

 public void verifyHierarchyValue() throws Exception{
  Hierarchy tst = HierarchyBuilder.buildHierarchy(Vector.class);
  assert tst.getHierarchyClassNames().length == 2: "length wasn't 2";
 }
}

Incidentally, I usually declare that all my tests throw Exception unless I’m trying to verify a specific exception type.

Thirdly, add the @Test annotation. If your bag is Java 1.4, simply create a JavaDoc style comment in the form of @testng.test.

import java.util.Vector;
import org.testng.annotations.Test;

public class HierarchyTest {
 @Test
 public void verifyHierarchyValue() throws Exception{
  Hierarchy tst = HierarchyBuilder.buildHierarchy(Vector.class);
  assert tst.getHierarchyClassNames().length == 2: "length wasn't 2";
 }
}

Care to add a fixture? It’s as simple as creating a method to handle the set up logic and attaching the desired fixture granularity to it– in my case, I’d like this fixture to run once; hence, I’ll add a @BeforeMethod annotation to my method, man. Accordingly, if I wanted a tear down style method, I’d attach a @AfterMethod annotation to it. Java 1.4 users require a JavaDoc comment, such as @testng.before-method.

import java.util.Vector;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;

public class HierarchyTest {
 private Hierarchy tst;

 @BeforeClass
 private void fixture(){
  this.tst = HierarchyBuilder.buildHierarchy(Vector.class);
 }

 @Test
 public void verifyHierarchyValue() throws Exception{
  assert this.tst.getHierarchyClassNames().length == 2: "length wasn't 2";
 }
}

TestNG supports a myriad of runners from Ant to Eclipse to Maven to IntelliJ also. Running the newly created test via a desired mechanism, by the way, is step four. Was that easy or what, man?

more moreUnit with TestNG

moreUnit is a copasetic Eclipse plug-in that provides two interesting features:

  1. It marks up classes, which have a corresponding developer test
  2. It generates a test case stub for desired methods

The tool is heavily focused on JUnit style testing; however, moreUnit works for TestNG as well. As I’ve already advocated, TestNG and JUnit play nicely together, so it shouldn’t be a surprise to see moreUnit complement TestNG.

moreUnit discovers corresponding tests via naming patterns; hence, if you have a hip class named Hierarchy, it’ll scan a project for a HierarchyTest or a TestHierarchy class. Because it’s my bag, I have quite a few code bases that have both TestNG and JUnit tests, I tend to specify TestNG tests via the TestNG suffix and leave JUnit tests with the traditional Test suffix.

Accordingly, I just had to add the new suffix to the moreUnit preference dialog shown below.

If you already have a TestNG test defined for a class (and moreUnit has spotted it), you can right click on non-tested methods and test cases will be generated. Just make sure you’ve unclicked “Create JUnit4 methods” option– otherwise you’ll have to fix an errant JUnit import. With the option unclicked, you’ll be left with a tripping old style JUnit test case (returning void and starting with test).

As you can see in the above figure, you can either right click over an untested method or type Ctrl+U to generate a test case stub.

All that’s left after the stub is created is an annotation (1.5 or 1.4 JavaDoc) and of course, the test logic. Dig it?

TestNG is so Groovy

As I wrote about previously, TestNG can execute an existing suite of JUnit tests, thus providing a unified reporting mechanism for all developer tests. This means that TestNG can also execute developer test written in Groovy.

In order for this process to work, however, you must compile any Groovy tests into byte code and add references in TestNG’s testng.xml file. You can either:

  • Reference the corresponding class directly or
  • Reference the package the class resides in

and ensure that the junit attribute of the test element these classes are defined in is set to true.

The following test, for instance, defined in a testng.xml file, is designated as a JUnit test. It will be run JUnit style– a fixture (if defined) for every test found in the class.

<test name="junits" junit="true">
  <classes>
   <class name="test.com.acme.sedo.frmwrk.filter.impl.ClassInclusionTest" />
  </classes>
</test>

In order to run all copasetic unit tests (defined in both TestNG and Groovy) in an Ant build, I create a TestNG task, which depends on a compilation of Groovy files, shown below.

<groovyc destdir="${classesdir}"
    srcdir="./test/groovy" >
   <classpath>
    <path refid="build.classpath"/>
    <pathelement path="${testclassesdir}"/>
    <pathelement path="${classesdir}"/>
   </classpath>
</groovyc>

The task above compiles any associated Groovy tests (found in the test/groovy directory) and puts the class files in a specific location.

Now, when testng-unit is invoked, any corresponding hip tests written in Groovy will be compiled into normal .class files and therefore picked up by TestNG (and run as normal JUnit tests). The TestNG task is accordingly defined to pick up a testng.xml file designated for running unit tests.

<target name="testng-unit" depends="compile,groovy-compile">
 <testng outputDir="${testng.output.dir.unit}"
        sourceDir="${testng.source.dir}"
        classpath="${testclassesdir};${classesdir}">

   <xmlfileset dir="${testng.suitexml.dir}"
        includes="${testng.suitexml-unit.name}"/>

   <classpath>
     <path refid="build.classpath"/>
   </classpath>
  </testng>
</target>

Now that this process has been defined, I can write tests in either JUnit, TestNG, or even Groovy and one runner will run them all. Dig it, man?

Next »