The Source for Java Technology Collaboration
User: Password:



Alexey Popov

Alexey Popov's Blog

ME application testing - MIDlet instantiation

Posted by alexeyp on July 08, 2007 at 03:09 AM | Comments (2)

The very common problem people meet when trying to unit-test their MIDlets is that you generally can not do something like this:

public class MyTest extends TestCase {

    public void test() {
        MyMIDletApplication myma = new
MyMIDletApplication();
        assertEquals("Never get here", 7, 8);
    }
}

MIDP spec prohibits calling MIDlet constructor from application code, for security reasons MIDlet can be instantiated only by AMS, Application Management Software. All MIDP xUnit-like test frameworks, I am aware of, assume that test execution is done by a special utility MIDlet, lets call it MIDletTester, for example. Since it is not possible to get instance of your application MIDlet class from the MIDletTester, unit testing should be limited to library classes.

Here are couple of ideas, we consider implementing some of them for ME Framework.

Provisioning server and instrumentation

Ideally, testing should be done on the instance, that runs in the environment, that is closest to real. Though you have to test every unit of the program in isolation, it would also be useful to have possibility to execute some tests on the MIDP application, that is packaged and instantiated in a regular way, not on library classes, packaged with your test application.

This can be done by adding hooks to the application, where you can embed your tests. This approach will require the control over the application code, may not always be possible.

If you supply minimalistic xUnit-like test framework with a server, responsible for  packaging and provisioning of the test application, you can implement a solution for this and for some other MIDP-specific testing problem by using instrumentation of the compiled application class files to embed whatever hooks you need. Check the picture:

MIDletinstr1.PNG


You need to modify the MIDlet class of your application under test with:
  • one or many methods, that will run tests. For example instantiate a test class by a classname and call its methods.
  • for each test to pass its classname, for example hardcode to the newly generated method or in a resource file
  • add a mechanizm to call these methods. 
Interesting question is where calling of a test method makes sense. I think having a UI for it, a Command is not a good idea - after all we do all this so that testers click mouse less. Placing it into any specific place in startRun may not work well ... may be I want this MIDlet instance after startRun was called by AMS.

Potential approach here would be to rename all MIDlet methods that can be called by AMS and replace them with testing hook methods. Allow to bypass them or call original MIDlet methods from them. MIDlet.startUp method after instrumentation may look like:

    public final void startApp() {       
       test_startUp_preconditions();
       _original_startUp();
       test_startUp_postconditions();       
    }

Any comments will be appreciated.


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Parts of your article are unclear to me -- regardless, I wonder why you wouldn't package your app code and test code as separate MIDlets in a single suite... if done correctly, you could then call the app code from the test code for testing purposes without polluting your app code with test code. Also, the size of your deployed (probably obfuscated) MIDlet would be reduced. Even with obfuscation, one goal should be to reduce extraneous code in any mobile application. Agreed?

    Regards,
    Evan J. Goff

    Posted by: evan_j_goff on July 13, 2007 at 12:59 PM

  • Hi Evan

    thank you for the comment and questions, sorry that I was not completely clear

    The approach you describe is the one that is used for this purpose now. When two midlets are packaged into a single MIDlet suite, we can launch one (test) MIDlet and access all classes in the MIDlet suite from the running MIDlet
    This has two limitations and proposed approach with instrumentation is a potential solution:

    Doing so will not allow you to instantiate one MIDlet from another - calling new MIDlet() will result in SecurityException.
    this can not be used for automation of functional testing where you need application under test to be launched by AMS and go through full application life cycle.

    There are non-standard exceptions, like some implementations allow to call new MIDlet from inside of MIDlet constructor, we can not rely on this
    I am not aware of a standard way in MIDP2.0 to have multiple MIDlets from the MIDlet suite running simultaneously and access classes of one MIDlet from another.
    Completely agree with your point about reducing extraneous code from the application. In the described approach we instrument and repackage class files of the application in the test process only, this modification is applied to already built application by a server, that provisions these applications to test devices. Source code is left unchanged, we modify built MIDlet suite (that may be previously obfuscated).

    Thank you
    Alexey

    Posted by: alexeyp on July 14, 2007 at 03:28 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds