warning(junit.framework.TestSuite$1): Exception in constructor when executing Android Test by Maven


Ask by : Bevor November 04, 2012 09:41

I setup an Android test project by Maven and followed the instructions from here. Basically I was able to setup the test project, even the emulator is being recognized, but I still can't run the tests by Maven when executing mvn install (in Eclipse). If I try to execute it, I get the following errors:

Failed tests: warning(junit.framework.TestSuite$1): Exception in constructor: testPersistAndRead (java.lang.RuntimeException: Stub!(..) warning(junit.framework.TestSuite$1): Exception in constructor: testFileNotExists (java.lang.RuntimeException: Stub!(..) warning(junit.framework.TestSuite$1): Exception in constructor: testCreateFiles (java.lang.RuntimeException: Stub!(..) warning(junit.framework.TestSuite$1): Exception in constructor: testFilesExist (java.lang.RuntimeException: Stub!(..) warning(junit.framework.TestSuite$1): Exception in constructor: testAndroidTestCaseSetupProperly (java.lang.RuntimeException: Stub!(..)

The output from surfire tells me that it is nested in AndroidTestCase:

junit.framework.AssertionFailedError: Exception in constructor: testPersistAndRead (java.lang.RuntimeException: Stub! at android.test.AndroidTestCase.(AndroidTestCase.java:5) [...]

This is the test I try to run.

public class PersistenceManagerTest extends AndroidTestCase {

    private final String FILENAME_PREFIX = "test.";

    protected void setUp() throws Exception {
        super.setUp();
        deleteInternalStorageFile();

        MockContentResolver resolver = new MockContentResolver();
        RenamingDelegatingContext renamingDelegatingContext = new RenamingDelegatingContext(new MockContext(), getContext(), FILENAME_PREFIX);
        Context context = new IsolatedContext(resolver, renamingDelegatingContext);

        setContext(context);
    }

    //AfterClass
    protected void tearDown() {
        deleteInternalStorageFile();
    }

    public void testPersistAndRead() throws IOException {
        String testData = "foobar";

        PersistenceManager.persist(testData, FileType.JSONDATA);

        String result = PersistenceManager.getFileData(FileType.JSONDATA);

        assertEquals(testData, result);
    }

    public void testFileNotExists()  {
        try {
            PersistenceManager.getFileData(FileType.JSONDATA);
            fail("PersistenceManager.getFileData should throw an exception!");
        } 
        catch (IOException e) {
            //expected
        }
    }

    public void testCreateFiles()  {
        try {
            PersistenceManager.createNewFiles();
        } 
        catch (IOException e) {
            fail("PersistenceManager.createNewFiles() threw an exception");
        }   
        try {
            PersistenceManager.getFileData(FileType.JSONDATA);
        } 
        catch (IOException e) {
            fail("PersistenceManager.getFileData should not throw an exception!");
        }
    }

    public void testFilesExist() throws IOException  {
        assertFalse(PersistenceManager.filesExist());

        PersistenceManager.createNewFiles();

        assertTrue(PersistenceManager.filesExist());
    }

    private void deleteInternalStorageFile() {
        getContext().deleteFile(PersistenceManager.JSONDATAFILE);
        getContext().deleteFile(PersistenceManager.TIMESTAMPFILE);
    }
}

...and this is the pom.xml from the test project.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'>
    <modelVersion>4.0.0</modelVersion>
    <groupId>net.mydomain.android</groupId>
    <artifactId>myproject-androidtests</artifactId>
    <packaging>apk</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>Testproject</name>

    <properties>
        <platform.version>2.1.2</platform.version>
        <android.sdk.path>/opt/android-sdk-linux</android.sdk.path>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <android.device>emulator</android.device>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.google.android</groupId>
            <artifactId>android</artifactId>
            <version>${platform.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.google.android</groupId>
            <artifactId>android-test</artifactId>
            <version>${platform.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>net.mydomain.android</groupId>
            <artifactId>myartifact</artifactId>
            <type>apk</type>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>net.mydomain.android</groupId>
            <artifactId>myartifact</artifactId>
            <scope>provided</scope>
            <type>jar</type>
            <version>1.0-SNAPSHOT</version>
        </dependency>

    </dependencies>
    <build>
        <outputDirectory>bin/classes</outputDirectory>
        <testOutputDirectory>bin/test-classes</testOutputDirectory>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.jayway.maven.plugins.android.generation2</groupId>
                <artifactId>android-maven-plugin</artifactId>
                <version>3.1.1</version>
                <configuration>
                    <sdk>
                        <path>${android.sdk.path}</path>
                        <platform>7</platform>
                    </sdk>
                </configuration>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
</project>

Any ideas why this isn't working?

View original question

Answer by : BevorNovember 04, 2012 09:41

I found the solution here.

dtmilano's answer is basically not wrong, but I didn't know what that means for my test. The solution is to tell Maven that instrumentation tests must not be run as JUnit tests, so the instrumentation tests must not be in src/test/java but in src/main/java. Instead they have to be included into the apk, so they are getting deployed on the device and triggered to run.

View original answer