vendredi 28 juillet 2017

Gradle build fails with "String Index out of range" when Android Tests Fail

I am experiencing a problem when trying to do instrumentation tests with Android. When one of the tests fails, the build fails, but doesn't state that the test failed. Instead I get FAILURE: Build failed with an exception. For the what went wrong section, I get String index out of range: -1.

In my real app, this is causing it to not generate a html report either, and the xml report is sporadically generated. I have put together a simple test case, but it is generating the report, but otherwise giving the same failure message.

Here is the very simple test app

build.gradle

buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.4.0-alpha7'
    }
}

apply plugin: 'com.android.application'

repositories {
    jcenter()
    mavenCentral()
}

dependencies {
    androidTestCompile "com.android.support.test.espresso:espresso-core:2.2.2"
    androidTestCompile "com.android.support.test.espresso:espresso-intents:2.2.2"
    androidTestCompile "com.android.support.test:runner:0.5"
}

android {
    compileSdkVersion 24
    buildToolsVersion '25.0.2'

    defaultConfig {
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8 
    }

    buildTypes {        
        release {
            minifyEnabled true
            proguardFile getDefaultProguardFile('proguard-android.txt')
        }
    }
}

src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://ift.tt/nIICcg"
      package="com.test.bad"
      android:versionCode="1"
      android:versionName="1">
    <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="24" />     
    <application android:label="bad">
        <activity android:name="BadTestActivity" android:label="bad">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

src/main/java/test/bad/BadTestActivity.java

package com.test.bad;

import android.app.Activity;
import android.os.Bundle;

public class BadTestActivity extends Activity {

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

src/androidTest/java/com/test/bad/BadTest.java

package com.test.bad;

import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.fail;
import android.support.test.runner.AndroidJUnit4;

@RunWith(AndroidJUnit4.class)
public class BadTest {

    @Test
    public void failTest() {
        fail("This test just fails");
    }

}

When I run gradle connectedAndroidTest, I see

:connectedDebugAndroidTest

FAILURE: Build failed with an exception.

* What went wrong:
String index out of range: -1

* Try:
Run with --stacktrace option to get the stack trace.  Run with --info or --debug 
option to get more log output.

I would expect that to give some message about the build failing because of a failed test instead of something strange like that string index. In my real application (which also uses Kotlin and Mockito in tests) the report html is not always generated (there are many more tests, and I think that has something to do with the lack of a report).

Using --info or --debug doesn't seem to show anything useful, but using --stacktrace shows

* Exception is:
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1967)
    at org.gradle.internal.logging.text.AbstractLineChoppingStyledTextOutput$StateContext.flushLineText(AbstractLineChoppingStyledTextOutput.java:115)
    at org.gradle.internal.logging.text.AbstractLineChoppingStyledTextOutput$2.execute(AbstractLineChoppingStyledTextOutput.java:167)
    at org.gradle.internal.logging.text.AbstractLineChoppingStyledTextOutput$2.execute(AbstractLineChoppingStyledTextOutput.java:160)
    at org.gradle.internal.logging.text.AbstractLineChoppingStyledTextOutput$1.execute(AbstractLineChoppingStyledTextOutput.java:146)
    at org.gradle.internal.logging.text.AbstractLineChoppingStyledTextOutput$1.execute(AbstractLineChoppingStyledTextOutput.java:131)
    at org.gradle.internal.logging.text.AbstractLineChoppingStyledTextOutput.doAppend(AbstractLineChoppingStyledTextOutput.java:41)
    at org.gradle.internal.logging.text.AbstractStyledTextOutput.text(AbstractStyledTextOutput.java:73)
    at org.gradle.internal.logging.text.AbstractStyledTextOutput.println(AbstractStyledTextOutput.java:68)
    at org.gradle.internal.logging.events.LogEvent.render(LogEvent.java:48)
    at org.gradle.internal.logging.console.StyledTextOutputBackedRenderer.onOutput(StyledTextOutputBackedRenderer.java:65)
    at org.gradle.internal.logging.sink.ProgressLogEventGenerator.doOutput(ProgressLogEventGenerator.java:72)
    at org.gradle.internal.logging.sink.ProgressLogEventGenerator.onOutput(ProgressLogEventGenerator.java:62)
    at org.gradle.internal.logging.console.BuildLogLevelFilterRenderer.onOutput(BuildLogLevelFilterRenderer.java:42)
    at org.gradle.internal.logging.sink.OutputEventRenderer$4.onOutput(OutputEventRenderer.java:265)
    at org.gradle.internal.logging.sink.OutputEventRenderer$LazyListener.onOutput(OutputEventRenderer.java:368)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
    at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
    at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
    at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
    at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
    at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
    at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
    at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy0.onOutput(Unknown Source)
    at org.gradle.internal.logging.sink.OutputEventRenderer.onOutput(OutputEventRenderer.java:334)
    at org.gradle.launcher.daemon.client.DaemonClient.monitorBuild(DaemonClient.java:216)
    at org.gradle.launcher.daemon.client.DaemonClient.executeBuild(DaemonClient.java:178)
    at org.gradle.launcher.daemon.client.DaemonClient.execute(DaemonClient.java:141)
    at org.gradle.launcher.daemon.client.DaemonClient.execute(DaemonClient.java:92)
    at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:51)
    at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:173)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:287)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:260)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:33)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:253)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:182)
    at org.gradle.launcher.Main.doAction(Main.java:33)
    at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:60)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:37)
    at org.gradle.launcher.GradleMain.main(GradleMain.java:23)

I am using Windows 7, with Gradle 4.0 (the problem exists with 3.5 as well) and Java 8.

What is causing this error message? Is this what I should see?

Aucun commentaire:

Enregistrer un commentaire