Oops Null Pointer

Java programming related

Category Archives: Testing

EasyMock Generic(ish) Collection Matcher

I wanted to check that a collection is basically the same as another without knowing the collection type. I can only really check that the same elements are present, like a basic set.

The code below is based on the code here but with generics where possible (the matches method is not generic in EasyMock 2.5):


private static class CollectionMatcher<T> implements IArgumentMatcher {
    private Collection<T> collection;
    private String notFound = "";

    public CollectionMatcher(Collection<T> collection) { this.collection = collection; }

    public static <T> Collection<T> collectionEq(Collection<T> collection) {
        reportMatcher(new CollectionMatcher<T>(collection));
        return null;
    }

    public void appendTo(StringBuffer buffer) {
        buffer.append(notFound).append(" not found in {");
        String comma = "";
        for (Object o : collection) {
            buffer.append(comma).append(o.toString());
            comma = ",";
        }
        buffer.append("}");
    }

    public boolean matches(Object otherCollection) {
        if (!(otherCollection instanceof Collection)) return false;

        Collection<T> other = (Collection<T>) otherCollection;
        if (other.size() != collection.size()) return false; // Optionally check sizes
        for (T o : other) {
            if (!collection.contains(o)) {
                notFound = o.toString();
                return false;
            }
        }
        return true;
    }
}

Selenium Handling / Testing Downloads with a custom profile

Selenium and downloads don’t play nicely as the Firefox (et al) download dialogs are out of reach of Selenium. The GWT application I’m working on allows the user to click on an icon and have an Excel file download initiated.

Searching for ways to test downloading files with Selenium came up with methods focused on running some kind of download dialog GUI interaction tool like AutoIT (anyone tried sikuli?).

While this is a practical solution it feels fragile to me.

To avoid this I created a custom Firefox profile to use as a template. This custom profile contains a customised download save path that I use to check files are downloaded, and a mimetype setting to that Excel files are automatically saved.

To do this:

  • Copy the customProfileDirCUSTFF from the Selenium 1.0.1 sources
  • Add a custom prefs.js file with a download path set (at least)
  • Add a mineTypes.rdf and set excel files to auto save (alwaysAsk=false)
  • Start the selenium server with a template profile parameter

The easiest way to create these files is by changing the settings in Firefox and then looking at the prefs.js file and mimeTypes.rdf file in your profile directory.

The line from the prefs.js is:

user_pref("browser.download.dir", "C:\\temp\\ff_selenium_downloads");

And the section from the mimeTypes:

  <RDF:Description RDF:about="urn:mimetype:handler:application/vnd.ms-excel"
                   NC:saveToDisk="true"
                   NC:alwaysAsk="false" />

To start your Selenium server with the template profile use:

-firefoxProfileTemplate

java -jar selenium-server.jar -firefoxProfileTemplate

or in Java:

    RemoteControlConfiguration rcc = new RemoteControlConfiguration();
    rcc.setPort(SeleniumUtils.SELENIUM_SERVER_PORT);
    rcc.setFirefoxProfileTemplate(customFFProfileDir);
    server = new SeleniumServer(rcc);
    server.start();

Creating NUnit reports with Ant

The current project I’m working on is largely Java with a reasonable amount of Microsoft Office connectivity using C#, VB, with COM and JSON as the bridges to the Java server. To get continuous integration rolling I really wanted to end the NUnit GUI based tests and get the NUnit console results built into a HTML report via Ant.

Not having any experience with NAnt (all our .Net building is done via Ant) I needed some way to get Nunit results into JUnit format so I could run the junitreport task on them.

Here are the steps I took:
1) Run the NUnit tests with the nunit-console and create an xml file

2) Use a modified version of Hudson’s NUnit plugin’s nunit-to-junit.xsl file to create a JUnit file per assembly test suite
Hundon’s XSL creates one file for all the tests with a “testsuites” root node. The junitreport task needs one file per testsuite. Hudson has a java file to do this, while I used the XSL 2.0 result-document (with the saxon XSLT engine) to do this. I use Ant’s XSLT task to transform the results

The modified section of the nunit-to-junit.xsl looks like this:

<!-- I need to replace any non file system compatible chars with '_'-->
<xsl:variable name="assemblyName">
  <xsl:analyze-string select="$assembly" regex="[\*/:&lt;li&gt;\?\|;&quot;&apos;]+">
    <xsl:matching-substring>
      <xsl:value-of select="." />
    </xsl:matching-substring>
    <xsl:non-matching-substring>
      <xsl:value-of select="." />
    </xsl:non-matching-substring>
  </xsl:analyze-string>
</xsl:variable>

<xsl:result-document href="{$outputpath}/TEST-{$assemblyName}.xml" format="xml">
  <testsuite name="{$assemblyName}" ...>
   ...

3) Run Ant’s junitreport task on the result and voila: a junit-y looking HTML report for my NUnit tests.

The ant target is:

<target name="create-nunit-test-report" description="NUnit result into junit report">

  <delete dir="${test.nunit.reports.dir}" failonerror="false"/>
  <mkdir dir="${test.nunit.reports.dir}"/>

  <xslt in="${test.nunit.console.file}"
    out="${test.nunit.results.dir}\temp-nunit-to-junit.xml"
    style="${antBuild}\nunit-to-junit.xsl" force="true"
    processor="org.apache.tools.ant.taskdefs.optional.TraXLiaison">

    <outputproperty name="method" value="xml"/>
    <outputproperty name="standalone" value="yes"/>
    <outputproperty name="encoding" value="iso8859_1"/>
    <outputproperty name="indent" value="yes"/>

    <classpath location="${vendor.lib.dir}/xslt/saxon9he.jar" />

    <!--Split file location for results-document XSLT function  -->
    <param name="outputpath" expression="file:///${full.path.test.nunit.results.dir}"/>
  </xslt>

  <junitreport todir="${test.nunit.results.dir}">
    <fileset dir="${test.nunit.results.dir}">
      <include name="TEST-*.xml" />
    </fileset>
    <report todir="${test.nunit.reports.dir}" />
  </junitreport>
</target>

Update 1/12/2010: Ant 1.8.1 has a bug that will cause the saxon jar not to be found and a “Unsupported XSL element” error.
I found the solution here http://stackoverflow.com/questions/919692/how-to-execute-xslt-2-0-with-ant/4211575#4211575
You need to add the following attribute to the xslt task:

processor="org.apache.tools.ant.taskdefs.optional.TraXLiaison"

Capturing Integration Testing Input/Output with XStream

A co-worker was looking for a way to capture input and results during a debug session for certain scenarios that were occurring at run time. Ideally they were looking for a tool that could be used in Eclipse and capture parameters and return values from frames in the debug session and then be able to reuse those values in jUnit tests.

A quick search couldn’t find any tools that find the bill, but as a quick and dirty method you can use XStream in an Eclipse “Display” view to dump out input and return variables. Then in a jUnit test you unserialise the XML back into objects and tests the inputs against the results.

The XML format gives you two instant advantages:

  • No need to reconstruct the input / result objects from scratch (which can be difficult, especially in complex or legacy systems)
  • Easy tweaking of the the XML to get the results you want

A disadvantage is that if the objects structure changes then re-factoring tools will miss the XML data and the test may no longer work.

To use this technique:

  • Put XStream in your project classpath
  • Show the Display view in eclipse (Widnow->Show View-> Display)
  • Put breakpoints in the code to capture input and result objects
  • At a breakpoint run the following code in the Display view to serialise the objects to XML
(new com.thoughtworks.xstream.XStream()).toXML(someObjectToSerialise)
  • Save the XML to files and load the files into a jUnit test (say with Commons FileUtils.readFileToString())

If you know of any other tools to do this in a more automated fashion then let me know (it would be cool to do this with a few clicks via a plugin – even generate the test classes).