Welcome to Qt Jambi’s homepage, the most comprehensive Java toolkit


Unit testing with Qt Jambi

  • Posted by Akos Kemives
  • at October 28, 2010
  • 0 comments

Hi!
This is my first post on planetqt, so a few words about myself: I’m Akos (akoskm on IRC), I’m studying (4th, last year) Informatics. I’m the newest member of the qtjambi-community.

In this guide I’ll show you how to get started with Unit Testing in Qt Jambi. The theory behind Unit Testing is quite interesting: http://mydailyhash.wordpress.com/2010/10/15/getting-started-with-unit-testing/.
You’ll need only 2 things:

    1. Qt Jambi (latest version from git) environment for building Unit Tests (Build Qt Jambi)

    2. JUnit framework (optional, recommended)

I assume that you have the given requirements, lets write your first Unit Test!
For starting pick up a smaller class: qtjambi-4_7/java/src/qtjambi/com/trolltech/qt/GeneratorUtilities.java.
Important: it’s not required to know all of the Qt programming concepts. It’s enough to understand what the functions are doing before you test them!

Take a closer look to the class GeneratorUtilities and to its first function, threadCheck(QObject obj):
public class GeneratorUtilities { private static final boolean threadAsserts; static { threadAsserts = !Utilities.matchProperty("com.trolltech.qt.thread-check", "false", "no"); }

public static void threadCheck(QObject obj) {
if (threadAsserts)
if (obj.thread() != null && obj.thread() != Thread.currentThread()) {
throw new QThreadAffinityException(“QObject used from outside its own thread”,
obj,
Thread.currentThread());
}
}


How to prove that threadCheck(QObject obj) function works properly. What we know about it?
After a short observation you can state the following:


    a) this method executes only if threadAsserts is true.


    b) it will drop an exception if obj.thread() is not null AND obj.thread() is different from the current thread.

    c) it will drop an exception if obj.thread() is null (NullPointerException)

Finally: the threadCheck(QObject obj) functions will succeed if and only if the observed – not null – thread object and the current thread are equal (Why?1). We can interpret this statement in Java in this way:
o1.thread() == Thread.currentThread() .
In any other cases, it will fail (1st and 3rd rows from the table at the bottom of the page, obj.thread() != null is false, which means o1.thread() == null is true):
o1.thread() == null .
Lets code this!

The first characteristic part of JUnit framework are the setUp() and tearDown() methods:
public void setUp() throws Exception { super.setUp(); gu1 = new GeneratorUtilities(); o1 = new QObject(); }

public void tearDown() throws Exception {
super.tearDown();
gu1 = null;
o1 = null;
}

where we need to initialize all variables what we want to use inside our test functions.
Important: setUp() runs every time when JUnit entering to a test function, respectively runs tearDown() every time when JUnit exits from a test function.

In JUnit we have a special way to define when a function succeeds or fails using the assertTrue(boolean) and assertFalse(boolean) functions. With assertTrue(boolean) you must represent the given function in a state when it returns true – if its working correctly of course -, with assertFalse(boolean) the opposite state. assertTrue(boolean) must get true value to succeed, assertFalse(boolean) must get false to succeed.
At the end we get the proof for threadCheck(QObject obj) test function called testThreadCheck(QObject obj)
public void testThreadCheck() throws Exception { //using reflection to access classes private variable Field threadAssertsTest = GeneratorUtilities.class.getDeclaredField("threadAsserts"); threadAssertsTest.setAccessible(true); /*

  • if threadAsserts is false threadCheck won’t run, we test the case only when
  • threadAsserts is true
    */
    if (threadAssertsTest.getBoolean(gu1)) {
    assertFalse(o1.thread() == null);
    assertTrue(o1.thread() == Thread.currentThread());
    }
    }

    Important: JUnit naming conventions: if you create a test class from ExampleClass you must name it ExampleClassTest, for functions see the example above.

The last, characteristic part of JUnit test is the Test class:
public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new GeneratorUtilitiesTest("testThreadCheck")); //you should add every tested function to the suite return suite; }

You can find the completed test classes in our Git repository:
http://qt.gitorious.org/~akoskm/qt-jambi/akoskm-unittests/trees/master/java/test/qtjambi/com/trolltech/qt/test.
It’s recommended to save your Unit Test files under …/java/test/qtjambi/com/trolltech/qt/test under the package name “test”.

1Here is why:
If we assign in the condition() (obj.thread() != null && obj.thread() != Thread.currentThread()) the left side of && with L = obj.thread() != null, and the right side with R = obj.thread() != Thread.currentThread(), we can interpret all of their states with the following table:
|  L  |  R  | +-----+-----+ |false|false| |true |false| |false|true | |true |true | +-----+-----+
From ()
we get the following: L && R. We know that this expression is true if and only if both L and R are true, and regarding to the operation && it will check the second operand only when the first is true.
What does it means?
We can drop two cases (1st, and 3rd) from our table (L = false means the object is null what ends in NullPointerExpcetion so it obviously fail at the test) and need to check only two combinations. From the remaining two cases both are beginning with true, it’s clear that the final value of (*) depends only on the value of obj.thread() != Thread.currentThread().

If you have any question regarding to this guide, contact us.

Other helpful links:
http://www.junit.org/
http://junit.sourceforge.net/doc/faq/faq.htm#tests
http://www.devx.com/Java/Article/9305/0/page/1
http://www.artima.com/lejava/articles/equality.html

Any thoughts, comments are welcome!

Post a comment


(lesstile enabled - surround code blocks with ---)

This page was updated at 24.08.2013