Android – JUnit testing Models/Controllers (which only use java imports) without the Android Emulator deploy

I’ve got two different UnitTest Projects for my Android App Project. One for the Model Classes (which only uses java imports), and one for the Activities (which obviously uses both java & android imports).

In Eclipse, when I use the option Run As -> Android JUnit Test on either of those two UnitTest Projects, I’m getting the following in my Console:

[2014-05-23 11:02:23 - MyProject.test] Android Launch!
[2014-05-23 11:02:23 - MyProject.test] adb is running normally.
[2014-05-23 11:02:23 - MyProject.test] Performing android.test.InstrumentationTestRunner JUnit launch
[2014-05-23 11:02:23 - MyProject.test] Automatic Target Mode: using existing emulator 'emulator-5554' running compatible AVD 'MyEmulator'
[2014-05-23 11:02:27 - MyProject.test] Application already deployed. No need to reinstall.
[2014-05-23 11:02:27 - MyProject.test] Project dependency found, installing: MyProject
[2014-05-23 11:02:30 - MyProject] Application already deployed. No need to reinstall.
[2014-05-23 11:02:30 - MyProject.test] Launching instrumentation android.test.InstrumentationTestRunner on emulator-5554
[2014-05-23 11:03:03 - MyProject.test] Sending test information to Eclipse
[2014-05-23 11:03:40 - MyProject.test] Test run finished

Both UnitTest Projects work and give test-results, but since it’s using the Emulator to test, it takes a bit of time before the results show up.

Now my question: Is it possible to run an Android UnitTest Project, which only uses java imports, as a JUnit, without having to use the Emulator? Which would result in much faster test-results.

When I try the option Run As -> JUnit Test I’m getting the following error:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (classFileParser.cpp:3494), pid=388, tid=1680
#  Error: ShouldNotReachHere()
#
# JRE version: 6.0_31-b05
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.6-b01 mixed mode windows-amd64 compressed oops)
# An error report file with more information is saved as:
# C:Users...MyProject.tesths_err_pid388.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

Answer

My Test-Classes used to be:

public class MyUnitTest extends android.test.AndroidTestCase
{
    public void aTest(){
        ...
        assertSomething(...);
        ...
    }

    ...
}

And I used to run them with Run As -> Android JUnit Test.


I’ve changed it by the following steps:

  1. First I’ve followed the instructions here.
  2. Then in all my Test-Classes I’ve removed the extends android.test.AndroidTestCase.
  3. Added the following two imports: import junit.framework.Assert; and import org.junit.Test; (WARNING: Make sure you use junit.framework.Assert instead of org.junit.Assert).
  4. Added @Test before every Test-Method.
  5. Changed all assertSomething(...); to Assert.assertSomething(...); and all fail(...); to Assert.fail(...);
  6. Removed some Android-Logs I still had in some of my Model/Controller classes..

Now my Test-Classes are:

import junit.framework.Assert;

import org.junit.Test;

public class MyUnitTest
{
    @Test
    public void aTest(){
        ...
        Assert.assertSomething(...);
        ...
    }

    ...
}

And now I’m able to run the Project by Run As -> JUnit Test.


UPDATE:

When you have this Project up and running, testing all UnitTests at the same time in Eclipse by right-clicking the Project -> Run as -> JUnit Test isn’t a problem. But when you try to Test individual UnitTest-classes (like the ones you’ve just added), the same error as in my question might occur.

These are the steps when you want to add a Java-only UnitTest-class in your Test-Project, which only uses Java libraries and enabling individual testing of the Test-classes without getting the error:

  1. Add a class (right-click a folder inside src) -> New -> Class
  2. Add the import junit.framework.Assert; and import org.junit.Test; like mentioned above.
  3. Create some UnitTest-methods with the synthax like above (so including the @Test and Assert.assertSomething(...);)
  4. Right-click the new UnitTest -> Run as -> JUnitTest
  5. Select Eclipse JUnit Launcher
  6. Now the error will occur that is displayed at the bottom of my question-post
  7. Right-click the Test-Project -> Properties -> Run/Debug Settings
  8. Select the new UnitTest that gives the error -> Edit…
  9. Go to the Classpath tab -> Under Bootstrap Entries remove Google APIs [Android 4.4.2]. (This might be different in your case, but you should remove the Android API or Android Google API.)
  10. After you’ve removed it click Apply -> OK -> Apply again at the Run/Debug Settings -> OK

Now you are successfully able to use Run As -> JUnit Test on this individual Test-class, instead of being forced to Test the entire Project every time.


I hope this helps anyone trying to make JUnit Tests for an Android project. PS: I also have a second Test-Project with the JUnit Tests that require Android libraries. Just make sure none of the classes you want to test uses Android Libraries (like Logcat-messages, Test-Toasts, or something like Patterns.WEB_URL.matcher(url).matches()) [android.util.Patterns] which validates a String URL) are being used inside your JUnit-only Test Project.

Leave a Reply

Your email address will not be published. Required fields are marked *