Java.lang.NoClassDefFoundError with Espresso and Proguard

女生的网名这么多〃 提交于 2019-12-10 18:24:05

问题


I'm not very experienced with Espresso, but I finally succeed to run it.

I have an app that need to be shrink by Proguard in order to be under the 56K methods.

The app starts with a 3 sec animation, so I need to wait until this animation is over in order to continue. This is what I tried to do with the method waitFor(long delay)

I tried to put this method as a standalone class, inner class and even project class = same error.

Here is the Proguard file:

android {
    ...
    compileSdkVersion ANDROID_BUILD_SDK_VERSION
    buildToolsVersion ANDROID_BUILD_TOOLS_VERSION

    productFlavors {
        // Define separate dev and prod product flavors.
        dev {
            // dev utilizes minSDKVersion = 21 to allow the Android gradle plugin
            // to pre-dex each module and produce an APK that can be tested on
            // Android Lollipop without time consuming dex merging processes.
            minSdkVersion 21
        }
        prod {
            // The actual minSdkVersion for the application.
            minSdkVersion ANDROID_BUILD_MIN_SDK_VERSION
        }
    }
    defaultConfig {
        applicationId "fr.xs.app.y"
        targetSdkVersion ANDROID_BUILD_TARGET_SDK_VERSION
        minSdkVersion ANDROID_BUILD_MIN_SDK_VERSION
        versionCode ANDROID_BUILD_VERSION_CODE
        versionName ANDROID_BUILD_APP_VERSION_NAME
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    // point sur le build de test
    testBuildType = "validation"

    buildTypes {
        release {
            debuggable false
            ext.enableCrashlytics = true
            renderscriptOptimLevel 3
            signingConfig android.signingConfigs.release
            zipAlignEnabled true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules-release.pro'
        }
        debug {
            debuggable true
            renderscriptOptimLevel 3
            applicationIdSuffix ".debug"
            versionNameSuffix "debug"
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro', 'proguard-rules-dontobfuscate.pro'
        }

        validation.initWith(debug)

        validation {
            debuggable false
            renderscriptOptimLevel 3
            applicationIdSuffix ".validation"
            versionNameSuffix "validation"
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro', 'proguard-rules-dontobfuscate.pro'
            testProguardFile('proguard-rules-test.pro')
        }
    }
...
}

Proguard Configuration

The following in is both Proguard files (debug and test) -keep class fr.xs.app.y.** { *; } -dontobfuscate

I checked that this class is in the mapping.txt (build/output/mapping/androidTest/dev) and not transformed to another string.

Here is the Test Class:

import android.app.Activity;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.IdlingPolicies;
import android.support.test.espresso.IdlingResource;
import android.support.test.espresso.core.deps.guava.collect.Iterables;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import android.support.test.runner.lifecycle.Stage;
import android.test.suitebuilder.annotation.LargeTest;

import com.squareup.spoon.Spoon;

import org.apache.commons.lang3.StringUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.concurrent.TimeUnit;

import fr.xs.app.y.Activity.SplashScreenActivity;

import static android.support.test.InstrumentationRegistry.getInstrumentation;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.CoreMatchers.allOf;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class HelloWorldEspressoTest {

    @Rule
    public ActivityTestRule<SplashScreenActivity> mActivityRule = new ActivityTestRule<>(SplashScreenActivity.class);

    @Test
    public void seeHomeScreen() throws Throwable {

        // SpashScreen
        takeScreenShot("Chargement Application");
        onView(allOf(withText("Réveille l'amateur qui est en toi"),
                withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
                .check(matches(isCompletelyDisplayed()));
        takeScreenShot("Splash Screen en cours");
        waitForDelay(3000);
        takeScreenShot("Splash Screen à la fin");

        // HomeScree
        onView(allOf(withText("Nouvelle Dégustation"),
                withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
                .check(matches(isCompletelyDisplayed()));
        takeScreenShot("Home Screen");

        // Preference
        onView(withId(R.id.iv_seeParameters)).perform(click());
        onView(withId(R.id.content_frame_sign_unsign)).check(matches(isDisplayed()));
        takeScreenShot("Preferences Screen");


    Activity getCurrentActivity() throws Throwable {
        getInstrumentation().waitForIdleSync();
        final Activity[] activity = new Activity[1];

        getInstrumentation().runOnMainSync(new Runnable() {
            @Override
            public void run() {

                java.util.Collection activites = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED);
                activity[0] = (Activity) Iterables.getOnlyElement(activites);
            }
        });
        return activity[0];
    }

    private static void waitForDelay(long waitingTime) {

        // Make sure Espresso does not time out
        IdlingPolicies.setMasterPolicyTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);
        IdlingPolicies.setIdlingResourceTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);

        // Now we wait
        IdlingResource idlingResource = new ElapsedTimeIdlingResource(waitingTime);
        Espresso.registerIdlingResources(idlingResource);


        // Clean up
        Espresso.unregisterIdlingResources(idlingResource);
    }

    private void takeScreenShot(String title) throws Throwable {
        String string = StringUtils.stripAccents(title).replace(" ", "_");
        Spoon.screenshot(getCurrentActivity(), string);
    }

    static class ElapsedTimeIdlingResource implements IdlingResource {
        private final long startTime;
        private final long waitingTime;
        private ResourceCallback resourceCallback;

        public ElapsedTimeIdlingResource(long waitingTime) {
            this.startTime = System.currentTimeMillis();
            this.waitingTime = waitingTime;
        }

        @Override
        public String getName() {
            return ElapsedTimeIdlingResource.class.getName() + ":" + waitingTime;
        }

        @Override
        public boolean isIdleNow() {
            long elapsed = System.currentTimeMillis() - startTime;
            boolean idle = (elapsed >= waitingTime);
            if (idle) {
                resourceCallback.onTransitionToIdle();
            }
            return idle;
        }

        @Override
        public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
            this.resourceCallback = resourceCallback;
        }
    }
}

Here is the log:

04-26 10:15:52.322 ? D/LifecycleMonitor: Lifecycle status change: fr.xs.app.y.Activity.SplashScreenActivity@6f8513d in: PAUSED 04-26 10:15:52.322 ? D/LifecycleMonitor: Lifecycle status change: fr.xs.app.y.Activity.SplashScreenActivity@6f8513d in: RESUMED 04-26 10:15:52.702 ? D/ActivityManager: bindService callerProcessName:fr.xs.app.y.validation, calleePkgName: com.google.android.gms, action: com.google.android.gms.analytics.service.START 04-26 10:15:53.012 ? I/ActivityManager: Displayed fr.xs.app.y.validation/fr.xs.app.y.Activity.SplashScreenActivity: +1s745ms (total +36m45s584ms) 04-26 10:15:53.762 ? I/Timeline: Timeline: Activity_windows_visible id: ActivityRecord{2b3eacb1 u0 fr.xs.app.y.validation/fr.xs.app.y.Activity.SplashScreenActivity t5952} time:259410459 04-26 10:15:54.592 ? I/art: Rejecting re-init on previously-failed class java.lang.Class 04-26 10:15:54.622 ? I/TestRunner: failed: seeHomeScreen(fr.xs.app.y.HelloWorldEspressoTest) 04-26 10:15:54.622 ? I/TestRunner: java.lang.NoClassDefFoundError: fr.xs.app.y.HelloWorldEspressoTest$ElapsedTimeIdlingResource at fr.xs.app.y.HelloWorldEspressoTest.waitForDelay(HelloWorldEspressoTest.java:166) at fr.xs.app.y.HelloWorldEspressoTest.seeHomeScreen(HelloWorldEspressoTest.java:56) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55) at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runners.Suite.runChild(Suite.java:128) at org.junit.runners.Suite.runChild(Suite.java:27) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at org.junit.runner.JUnitCore.run(JUnitCore.java:115) at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59) at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1873) 04-26 10:15:54.622 ? I/TestRunner: finished: seeHomeScreen(fr.xs.app.y.HelloWorldEspressoTest) 04-26 10:15:54.642 ? D/LifecycleMonitor: Lifecycle status change: fr.xs.app.y.Activity.SplashScreenActivity@6f8513d in: PAUSED 04-26 10:15:54.672 ? I/TestRunner: started: initializationError(fr.xs.app.y.suites.system.LogSupportUser) 04-26 10:15:54.732 ? I/TestRunner: failed: initializationError(fr.xs.app.y.suites.system.LogSupportUser) 04-26 10:15:54.732 ? I/TestRunner: finished: initializationError(fr.xs.app.y.suites.system.LogSupportUser) 04-26 10:15:55.692 ? D/KidsModeInstallReceiver: onReceive intent data = package:fr.xs.app.y.validation.test 04-26 10:15:56.752 ? E/SPPClientService: [PackageInfoChangeReceiver] [handlePkgRemovedEvent] PackageName : fr.xs.app.y.validation.test, true, false 04-26 10:15:56.932 ? D/LifecycleMonitor: Lifecycle status change: fr.xs.app.y.Activity.SplashScreenActivity@6f8513d in: STOPPED 04-26 10:15:56.932 ? D/LifecycleMonitor: Lifecycle status change: fr.xs.app.y.Activity.SplashScreenActivity@6f8513d in: DESTROYED 04-26 10:15:57.302 ? I/ActivityManager: Force stopping fr.xs.app.y.validation appid=10582 user=0: finished inst

no way to run it until now !

来源:https://stackoverflow.com/questions/36859528/java-lang-noclassdeffounderror-with-espresso-and-proguard

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!