簡體   English   中英

測試Activity返回預期結果

[英]Testing that an Activity returns the expected result

我有以下活動:

package codeguru.startactivityforresult;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class ChildActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.child);

        this.resultButton = (Button) this.findViewById(R.id.result_button);
        this.resultButton.setOnClickListener(onResult);
    }

    private View.OnClickListener onResult = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent result = new Intent();
            result.putExtra(ChildActivity.this.getString(R.string.result), ChildActivity.this.getResources().getInteger(R.integer.result));
            ChildActivity.this.setResult(RESULT_OK, result);
            ChildActivity.this.finish();
        }
    };
    private Button resultButton = null;
}

以下JUnit測試:

package codeguru.startactivityforresult;

import android.app.Activity;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.widget.Button;
import junit.framework.Assert;

public class ChildActivityTest extends ActivityInstrumentationTestCase2<ChildActivity> {

    public ChildActivityTest() {
        super(ChildActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();

        this.setActivityInitialTouchMode(false);

        this.activity = this.getActivity();
        this.resultButton = (Button) this.activity.findViewById(R.id.result_button);
    }

    @Override
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @UiThreadTest
    public void testResultButtonOnClick() {
        Assert.assertTrue(this.resultButton.performClick());
        Assert.fail("How do I check the returned result?");
    }
    private Activity activity;
    private Button resultButton;
}

如何確保單擊按鈕設置正確的結果(通過調用setResult() )將返回到任何使用startActivityForResult()啟動此活動的活動?

使用當前Activity實現的問題,即通過單擊ChildActivity中的按鈕設置結果然后立即銷毀活動,我們在ChildActivityTest中沒有太多可以用來測試結果相關的東西。

相關問題的答案測試onActivityResult()顯示了如何在MainActivityTest中單獨測試startActivityForResult()和/或onActivityResult()。 通過獨立意味着MainActivityTest不依賴於ChildActivity的交互,檢測將捕獲ChildActivity創建並立即終止它然后返回一個現成的模擬ActivityResult,因此單元測試 MainActivity。

如果您不希望檢測中斷並返回模擬ActivityResult,則可以讓ChildActivity繼續運行,然后在ChildActivity中模擬交互,並將真實的ActivityResult返回給MainActivity。 如果您的MainActivity啟動ChildActivity獲得結果然后更新TextView,以測試整個端到端的交互/合作,請參閱下面的示例代碼:

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
  ... ...

  public void testStartActivityForResult() {
    MainActivity mainActivity = getActivity();
    assertNotNull(activity);

    // Check initial value in TextView:
    TextView text = (TextView) mainActivity.findViewById(com.example.R.id.textview1);
    assertEquals(text.getText(), "default vaule");

    try {
      Thread.sleep(2000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    // Create an ActivityMonitor that monitor ChildActivity, do not interrupt, do not return mock result:
    Instrumentation.ActivityMonitor activityMonitor = getInstrumentation().addMonitor(ChildActivity.class.getName(), null , false);

    // Simulate a button click in MainActivity that start ChildActivity for result:
    final Button button = (Button) mainActivity.findViewById(com.example.R.id.button1);
    mainActivity.runOnUiThread(new Runnable() {
      public void run() {
        button.performClick();
      }
    });

    try {
      Thread.sleep(2000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    getInstrumentation().waitForIdleSync();
    ChildActivity childActivity = (ChildActivity) getInstrumentation().waitForMonitorWithTimeout(activityMonitor, 5);
    // ChildActivity is created and gain focus on screen:
    assertNotNull(childActivity);

    // Simulate a button click in ChildActivity that set result and finish ChildActivity:
    final Button button2 = (Button) childActivity.findViewById(com.example.R.id.button1);
    childActivity.runOnUiThread(new Runnable() {
      public void run() {
        button2.performClick();
      }
    });

    try {
      Thread.sleep(2000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    getInstrumentation().waitForIdleSync();
    // TextView in MainActivity should be changed:
    assertEquals(text.getText(), "default value changed");
  }

  ... ...
}

我在這里添加了三個Thread.sleep()調用,以便您可以在運行JUnit Test時看到按鈕單擊模擬。 正如你在這里看到的,獨立的ChildActivityTest不足以測試整個合作,我們實際上是通過MainActivityTest間接測試ChildActivity.setResult(),因為我們需要從一開始就模擬整個交互。

我可以建議使用Robotium框架。 Robotium使用Solo類,它有一個非常有用的API。

它允許您查看當前活動的內容。 允許您斷言活動已經開始等。

http://code.google.com/p/robotium/

執行點擊后,您可以執行類似的操作

void assertCurrentActivity(java.lang.String message,java.lang.Class expectedClass,boolean isNewInstance)那么繼承人我會做什么。 單擊代碼后單擊按鈕

Activity callingActvity  = solo.getCurrentActivity();
  solo.assertCurrentActivity("ShouldbeCallingActivity","NameOfCallingActivity");

在不知道回調如何工作的情況下,我無法提供完整的解決方案。 但假設某些文本顯示為RESULT_OK而不是其他一些文本,

你可以做點什么

assertTrue(solo.waitForText("Text that is supposed to show for Result OK");

PS:robotium僅適用於同一應用程序中的活動。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM