停止按钮不停止当前的android单元测试

时间:2014-05-07 08:13:10

标签: android junit adt

需要一种解决方法来阻止从ADT在AVD上运行的长单元测试。 JUnit视图中的停止按钮不起作用,调试视图中的停止按钮都不起作用。即使它打印出VM被终止。例如:

public class StopTest extends AndroidTestCase {

    public void testSleep() throws Exception {
        Thread.sleep(20000);
    }
}

可能的解决方案:

在设备屏幕上显示取消按钮。

我设法在我的测试项目中创建了一个带有按钮的新Activity。不幸的是,测试套件是在我测试的应用程序的上下文中执行的。因此,要开始此活动,我需要编辑应用程序清单,这是我不想要的。所以我将此活动添加到测试清单中,然后从InstrumentationTestCase.getInstrumentation().getContext()开始。

这样我的屏幕上会显示一个带按钮的活动,但它在另一个过程中启动。现在我需要一些东西来从活动向我测试的应用程序发送消息。

不想在我的应用中添加服务,因为正如我所说,我不想编辑应用清单。

是否可以向活动发送Binder并使用它来发回消息?

1 个答案:

答案 0 :(得分:0)

setUp()我用按钮开始活动。按下后,我重新开始操作,并在接收方中呼叫System.exit()

==> ./src/org/foo/StopButtonInstrumentationTestCase.java <==
...
public class StopButtonInstrumentationTestCase extends InstrumentationTestCase {

        public void testSleep() throws Exception {
                Thread.sleep(10000);
        }

        public void testSleep2() throws Exception {
                Thread.sleep(10000);
        }

        @Override
        protected void setUp() throws Exception {
                super.setUp();
                showStopButton(getInstrumentation(), getName());
        }

        @Override
        protected void tearDown() throws Exception {
                hideStopButton(getInstrumentation());
                super.tearDown();
        }

        private static final BroadcastReceiver receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                        System.exit(1);
                }
        };

        public static void showStopButton(Instrumentation instrumentation, String testName) {
                // register stop tests receiver
                Context targetCtx = instrumentation.getTargetContext();
                targetCtx.registerReceiver(receiver, new IntentFilter(StopperActivity.ACTION));

                // show stop tests button
                Context ctx = instrumentation.getContext();
                Intent intent = new Intent(ctx, StopperActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                intent.putExtra(StopperActivity.PARAM_TEST_NAME, testName);
                ctx.startActivity(intent);
        }

        public static void hideStopButton(Instrumentation instrumentation) {
                Context targetCtx = instrumentation.getTargetContext();
                targetCtx.unregisterReceiver(receiver);
                // hide stop tests button
                Context ctx = instrumentation.getContext();
                Intent intent = new Intent(ctx, StopperActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); // android:launchMode="singleTop" doesn't work in old versions
                intent.putExtra(StopperActivity.PARAM_KILL, true);
                ctx.startActivity(intent);
        }
}

==> ./src/org/foo/StopperActivity.java <==
...
public class StopperActivity extends Activity {

        public static final String ACTION = StopperActivity.class.getName() + ".ACTION";
        public static final String PARAM_TEST_NAME = "testName";
        public static final String PARAM_KILL = "kill";

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);

                setContentView(R.layout.activity_stopper);

                findViewById(R.id.stop_button).setOnClickListener(
                                new View.OnClickListener() {
                                        @Override
                                        public void onClick(View view) {
                                                stopTest();
                                        }
                                });
                Intent intent = getIntent();
                Bundle extras = intent.getExtras();
                if (extras != null) {
                        displayTestName(extras);
                }
        }

        @Override
        protected void onNewIntent(Intent intent) {
                super.onNewIntent(intent);
                Bundle extras = intent.getExtras();
                if (extras != null) {
                        if (extras.containsKey(PARAM_KILL)) {
                                finish();
                        } else {
                                displayTestName(extras);
                        }
                }
        }

        private void stopTest() {
                sendBroadcast(new Intent(ACTION));
                finish();
        }

        private void displayTestName(Bundle extras) {
                String testName = extras.getString(PARAM_TEST_NAME);
                if (testName == null)
                        testName = "";
                setTitle(testName);
        }
}

==> ./res/layout/activity_stopper.xml <==
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="org.foo.StopperActivity" >

    <Button
        android:id="@+id/stop_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"

        android:layout_marginTop="16dp"
        android:paddingLeft="32dp"
        android:paddingRight="32dp"

        tools:ignore="HardcodedText"
        android:text="Stop test" />

</merge>

==> AndroidManifest.xml <==
...
<!-- android:exported="true" - allow launch test activity in context of testee -->
<activity
    android:name="org.foo.StopperActivity"
    android:exported="true"
    android:windowSoftInputMode="adjustResize|stateVisible">
</activity>
...