测试失败后,从ActivityTestRule重新启动活动



我修改了ActivityTestRule以重试执行失败的测试用例。每当测试失败时,我需要重新启动活动并重新运行执行。我已尝试调用mActivity.finish(),但当前活动未完成,也未重新启动。但测试已经重新开始。我从这里开始采用这种方法

public class MyActivityTestRule<T extends Activity> extends ActivityTestRule<T> {
private final Class<T> mActivityClass;
private T mActivity;
private static final String TAG = "ActivityInstrumentationRule";
private boolean mInitialTouchMode = false;
private Instrumentation mInstrumentation;

public MyActivityTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity) {
    super(activityClass, initialTouchMode, launchActivity);
    mActivityClass = activityClass;
    mInitialTouchMode = initialTouchMode;
    mInstrumentation = InstrumentationRegistry.getInstrumentation();
}
@Override
public Statement apply(Statement base, Description description) {
    final String testClassName = description.getClassName();
    final String testMethodName = description.getMethodName();
    final Context context =  InstrumentationRegistry.getTargetContext();
   /* android.support.test.espresso.Espresso.setFailureHandler(new FailureHandler() {
        @Override public void handle(Throwable throwable, Matcher<View> matcher) {
            if(AutomationTestCase.mEnableScreenshotOnFailure)
            SpoonScreenshotOnFailure.perform("espresso_assertion_failed", testClassName, testMethodName);
            new DefaultFailureHandler(context).handle(throwable, matcher);
        }
    });*/
     // return super.apply(base, description);
     return statement(base, description);
}
private Statement statement(final Statement base, final Description description) {
    return new Statement() {
        @Override
        public void evaluate() throws Throwable {
            Throwable caughtThrowable = null;
            //retry logic
            for (int i = 0; i < 3; i++) {
                try {
                    launchAppActivity(getActivityIntent());
                    base.evaluate();
                    return;
                } catch (Throwable t) {
                    caughtThrowable = t;
                    System.err.println(description.getDisplayName() + ": run " + (i+1) + " failed");
                    finishActivity();
                } finally {
                    finishActivity();
            }
            }
            System.err.println(description.getDisplayName() + ": giving up after " + 3 + " failures");
            throw caughtThrowable;
        }
    };
}
void finishActivity() {
    if (mActivity != null) {
        mActivity.finish();
        mActivity = null;
    }
}
public T launchAppActivity(@Nullable Intent startIntent) {
    // set initial touch mode
    mInstrumentation.setInTouchMode(mInitialTouchMode);
    final String targetPackage = mInstrumentation.getTargetContext().getPackageName();
    // inject custom intent, if provided
    if (null == startIntent) {
        startIntent = getActivityIntent();
        if (null == startIntent) {
            Log.w(TAG, "getActivityIntent() returned null using default: " +
                    "Intent(Intent.ACTION_MAIN)");
            startIntent = new Intent(Intent.ACTION_MAIN);
        }
    }
    startIntent.setClassName(targetPackage, mActivityClass.getName());
    startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    Log.d(TAG, String.format("Launching activity %s",
            mActivityClass.getName()));
    beforeActivityLaunched();
    // The following cast is correct because the activity we're creating is of the same type as
    // the one passed in
    mActivity = mActivityClass.cast(mInstrumentation.startActivitySync(startIntent));
    mInstrumentation.waitForIdleSync();
    afterActivityLaunched();
    return mActivity;
}}

如果您的测试在与ActivityTestRule初始化时不同的活动中结束,则必须关闭后台包中的所有活动。这个例子可能会有所帮助:

https://gist.github.com/patrickhammond/19e584b90d7aae20f8f4

如果您使用activityScenarioRule,您可以简单地将重试规则包装起来,它将在每次重试时重新启动活动。

我就是这么做的:

@get:Rule
var rule: RuleChain =
    RuleChain.outerRule(RetryRule()) //
        .around(hiltAndroidRule) //
        .around(activityScenarioRule<MainActivity>())

RetryRule类看起来像这个

class RetryRule(private val retryCount: Int = 3) : TestRule {
    override fun apply(base: Statement, description: Description): Statement = object : Statement() {
        private var caughtThrowable: Throwable? = null
        override fun evaluate() {
            for (i in 1..retryCount) {
                try {
                    base.evaluate()
                    return
                } catch (t: Throwable) {
                    caughtThrowable = t
                    Log.e("RetryRule", "${description.displayName}: test failed, retrying $i of $retryCount")
                }
            }
            throw caughtThrowable!!
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新