DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Coding
  3. Java
  4. How to Use JUnit to Test your JavaFX Applications with NetBeans IDE

How to Use JUnit to Test your JavaFX Applications with NetBeans IDE

Fabrizio Giudici user avatar by
Fabrizio Giudici
·
Jun. 07, 09 · Interview
Like (0)
Save
Tweet
Share
26.83K Views

Join the DZone community and get the full member experience.

Join For Free
So, we have JavaFX 1.2 and upgraded support for NetBeans IDE 6.5.1. After a few hours of use, I can confirm that the programmer's experience is now really improved, with the editor much more supportive than before. What's missing of importance still? Simple answer: JUnit support.

In fact, strangely enough, there's no support for tests; not even a specific folder to put them in. A few people blogged about some tricks to run JUnit in a JavaFX project, treating JUnit as a simple library; but this approach didn't satisfy me, also because I want something that produces the regular reports (e.g., to be used by Hudson) and doesn't require to write too much extra code (such as explicitly creating TestSuites); in a word, something that will allow me to have all the things working just as they are when JUnit tests will be available in NetBeans IDE.

I was able to do that, at the price of applying two small patches to JUnit. Here it is how to do in six steps.

1. Create a new JavaFX project and put a dependency on your primary project

You need to do that because you don't want to put test sources together with regular sources. You have to create a Dummy.fx class with a void run() function and declare it as the main class in the project properties: NetBeans treats every project as it was a complete application and wants an entry point.

public function run(): Void
{
}

You need to put the JAR of JUnit as a library of your test project - but a patched version of JUnit (see below).

2. Create the tests

Keep the usual conventions, such as putting a test in the same package as the fixture; name the test with the ****Test pattern and test methods test***(). Since in JavaFX there are no annotations, you have to use the JUnit 3.x approach, that is you have to extend TestCase. I'm including a sample of a real test from blueBill Mobile (which just a few not relevant stuff omitted for brevity). Note that to assert the equality of two sequences I had to write a small ad hoc function, as sequences aren't array and aren't known to JUnit. Such code (and other similar) should probably packed in a specific, small library.

package it.tidalwave.bluebillmfx.taxon.controller;

import java.lang.System;
import it.tidalwave.bluebillmfx.taxon.model.Taxon;
import it.tidalwave.bluebillmfx.taxon.model.TaxonomyMock;
import it.tidalwave.bluebillmfx.taxon.model.TaxonomyImpl;
import junit.framework.TestCase;
import org.junit.Assert;

public class TaxonSearchControllerTest extends TestCase
{
def mockTaxonomy = TaxonomyMock{};
def fullTaxonomy = TaxonomyImpl{};

postinit
{
def is = getClass().getResourceAsStream("EBNItalia2003.json");
fullTaxonomy.load(is);
is.close();
}

def fixture = InstrumentedTaxonSearchController
{
taxons: mockTaxonomy.species;
}

def performanceFixture = InstrumentedTaxonSearchController
{
taxons: fullTaxonomy.species;
}

public function testFunction(): Void
{
assertFilter("", ["Airone cinerino", "Airone bianco maggiore", "Airone rosso", "Piro piro", "Piro piro boschereccio"], -1, "");
assertFilter("A", ["Airone cinerino", "Airone bianco maggiore", "Airone rosso"], -1, "Airone ");
...
}

function assertFilter (filter : String, expected : String[], expectedIndex : Integer, expectedLeading : String)
{
fixture.filter = filter;
assertEquals(expected, displayNames(fixture.filteredTaxons));
assertEquals("fixture.selectedTaxonIndex", expectedIndex, fixture.selectedTaxonIndex);
assertEquals("fixture.leading", expectedLeading, fixture.leading);
}

function assertEquals (expected : String[], actual : String[]) : Void
{
Assert.assertTrue("{actual}", expected == actual);
}
}

3. Create a specific Ant target for testing

It is pretty much copied from similar stuff in NetBeans, just patched for getting the right stuff in the classpath (this could be done in a better way, but it presently works).

    <target name="test" depends="init,compile">
<mkdir dir="${build.test.unit.results.dir}"/>
<junit showoutput="true" fork="true" failureproperty="tests.failed" errorproperty="tests.failed" filtertrace="${test.filter.trace}" tempdir="${build.test.unit.results.dir}">
<batchtest todir="${build.test.unit.results.dir}">
<fileset dir="${build.test.unit.classes.dir}">
<include name="**/*Test.class"/>
</fileset>
</batchtest>
<classpath>
<fileset dir="${platform.fxhome}/lib/shared">
<include name="*.jar"/>
</fileset>
<fileset dir="${platform.fxhome}/lib/desktop">
<include name="*.jar"/>
</fileset>
<pathelement path="${javac.classpath}"/>
<pathelement path="${build.classes.dir}"/>
<pathelement path="${build.test.unit.classes.dir}"/>
</classpath>
<!-- syspropertyset refid="test.unit.properties"/ -->
<jvmarg value="-ea"/>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
</junit>
<fail if="tests.failed" unless="continue.after.failing.tests">Some tests failed; see details above.</fail>
</target>

4. Add a few properties in nbproject/project.properties

build.test.unit.classes.dir=${build.dir}/compiled
build.test.unit.results.dir=${build.dir}/test/results/

5. Patch JUnit

Now the most annoying part. Everything would already work, but for a detail: JUnit will complain about test classes having more than one constructor. Unfortunately, while JavaFX has got no constructors in the language, it creates synthetic code with two constructors in the bytecode (one with no parameters and one with a boolean parameter). I don't know what's it for, but for sure it makes JUnit complain. We have to patch JUnit. I downloaded JUnit 4.6 (I bet it's ok also 4.5) and patched these two files:

src/main/java/org/junit/runners/model/TestClass.java
src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java
diff TestClass.java TestClass.java.orig 
31,33c31,33
< // if (klass != null && klass.getConstructors().length > 1)
< // throw new IllegalArgumentException(
< // "Test class can only have one constructor");
---
> if (klass != null && klass.getConstructors().length > 1)
> throw new IllegalArgumentException(
> "Test class can only have one constructor");


diff BlockJUnit4ClassRunner.java BlockJUnit4ClassRunner.java.orig
118,121c118,121
< // if (!hasOneConstructor()) {
< // String gripe= "Test class should have exactly one public constructor";
< // errors.add(new Exception(gripe));
< // }
---
> if (!hasOneConstructor()) {
> String gripe= "Test class should have exactly one public constructor";
> errors.add(new Exception(gripe));
> }

This basically removes the enforcement of a single constructor.

I believe that JUnit is rather extensible and one can specify his own runner. Perhaps one could write some code and embed it together with tests, rather than patching the original, but unfortunately configuring this stuff requires annotations, and in JavaFX no annotations...

 

6. Create a small wrapper Ant script (for Hudson only)

Ok, at this time we have two NetBeans projects, the regular one and the one with tests. If you want to run this stuff under Hudson, put both of them into a directory and create this small script:

<?xml version="1.0" encoding="UTF-8"?>
<project name="blueBillMFX-global" default="hudson-fast" basedir=".">

<target name="hudson-fast">
<ant dir="blueBill-mobileFX" target="clean" inheritall="false"/>
<ant dir="blueBill-mobileFX" target="default" inheritall="false"/>
<ant dir="blueBill-mobileFXTest" target="clean" inheritall="false"/>
<ant dir="blueBill-mobileFXTest" target="test" inheritall="false"/>
</target>

</project>

Basically, the first call to ant might be redundant, as building the test project will make the first project to compile.

 

Ok, this can be surely improved, but in the meantime it just works, and you can start writing tests as they should be. The only important limitation it's that it won't work for a project configured with the Mobile profile, because of what sounds as a JavaFX compiler bug. My project is for the mobile profile, but I make sure that Hudson configures it as a desktop profile. I hope to fix this soon. Maybe in the meantime we will have NetBeans 6.7 final with JavaFX + JUnit support? Who knows.

What are you saying? Oh, you'd like to see an example project to try. Ok, blueBill Mobile isn't ready for primetime, but if you just want to look at how I configured tests you can check it out from Kenai:

svn co -r 141 https://kenai.com/svn/bluebill-mobile~svn/trunk/src/FX

 

JUnit Testing Integrated development environment JavaFX NetBeans mobile app

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How To Set Up and Run Cypress Test Cases in CI/CD TeamCity
  • Best Practices for Writing Clean and Maintainable Code
  • Use Golang for Data Processing With Amazon Kinesis and AWS Lambda
  • Implementing PEG in Java

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: