Unit Testing of J2ME Applications or Using Inheritance in Tests Development

It is not a secret that, using of JUnit test framework for testing J2ME applications is problematic. The main problem is that J2ME is almost JDK 1.0. It doesn't include reflection API and, of course, it doesn't support annotations. In this case it is impossible to designate method that implements test via method signature or annotation. In other words, it is impossible to maintain implicit association between the test method and name of test case.

In my humble option, if it is not possible, we shouldn't do this. To my mind, the solution is not to use "test<TestName>" method name signature to implement tests, and designate only one method:

   
        public void test() throws Throwable

as method for test implementation. In this approach we will not implement tests per method and will not maintain implicit association between the test method name and name of test case, that (recall) is not possible. Instead we will create test per class. in J2ME it is possible to keep implicit association between class name and test case name. Another problem that arises is a sharing of fixture between group of tests. Here is a place where Inheritance can help.

In MoMEUnit we implement different tests by different subclasses of TestCase. Sharing of the same fixture between different tests is realized via inheritance (as mentioned above). The one approach to do this is to create one subclass of TestCase by defining instance variables to store the state of the fixture, overriding setUp() and/or tearDown() methods to initialize fixture and to release resources after test run, implementing test() method. Other tests will extend this test sharing the same fixture. Instance variables, of course, should be declared as at least "protected" to be accessible by subclasses. Another more general approach is to create abstract TestCase subclass by defining instance variables and overriding setUp() and/or tearDown() methods. All test cases will extend this abstract class sharing the same fixture. The second approach is of course more structural but, to my mind, this is a bit a waste of time and memory.

For example instead of classical JUnit TestCase subclass

// sorry for stupid examples.
import junit.framework.TestCase;

public class ArithmeticTest extends TestCase
{

  private int arg1;

  private int arg2;

  public ArithmeticTest( String name)
  {
    super(name);
  }

  protected void setUp()
  {
    this.arg1 = 2;
    this.arg2 = 5;
  }

  public void testAdd()
  {
    int res = arg1 + arg2;
    assertEquals("I don't know what happened", 7, res);
  }

  public void testSubtract()
  {
    int res = arg2 - arg1;
    assertEquals("And what again ?", 3, res);
  }
}

In MoMEUnit we will have :

//"AddTest.java" file

import momeunit.framework.TestCase;

// Usage of Test suffix of class name is not required. You can use any name.
// This is only for illustration purposes.

public class AddTest extends TestCase 
{
  protected int arg1; // at least protected to be accessible by subclasses

  protected int arg2; // at least protected to be accessible by subclasses

  protected void setUp() 
  {
    this.arg1 = 2;
    this.arg2 = 5;
  }

  public void test()
  {
    int res = arg1 + arg2;
    assertEquals("I don't know what happened", 7, res);
  }
}



// "SubtractTest.java" file

// No imports because SubtractTest and AddTest are in the same package

// Usage of Test suffix of class name is not required. You can use any name.
// This is only for illustration purposes.
public class SubtractTest extends AddTest
{
  public void test()
  {
    int res = arg2 - arg1;
    assertEquals("And what again ?", 5, res);
  }
}

Using inheritance gives the other nice feature. We can define one fixture for a one group of test cases and add additional fixture or change existing one for another group. That can be helpful in some cases. For example


public class AdditionalFetureTest extends OtherTest
{
  protected AnObject arg3 = null;
  
  protected void setUp()
  {
    super.setUp()
    this.arg3 =	new AnObject( ... )
  }
  
  public void test()
  {
    assertTrue("Why additional feature doesn't work ?",
      target.additionalFeature( arg3, ... )); 
  }
}

Maybe it looks like implementing different tests as different classes is cumbersome. To my mind, it is not true. By using IDEs like Eclipse or NetBeans it is almost as simple and easy as creating additional method. Besides, writing class like this


public class MultiplyTest extends AddTest
{
  public void test()
  {
		...
  }
}

even by hand is not complex.

MoMEUnit has of course other changes to JUnit framework, that overcome other restrictions of J2ME platform and minimize memory usage. See MoMEUnit Guide or API