0

所以我有这个包含 3 个元素的测试活动:TextView、EditText、Button。当用户单击按钮时,Activity 会将 EditText 中的文本转换为 TextView 中的某些文本。

问题是:我如何为此类活动编写单元测试?

我的问题:我应该在一个线程中的一个按钮上“单击”(.performClick),但在另一个线程中异步等待,但这会破坏单元测试的逻辑,因为它会运行以“test”前缀开头的每个测试并将测试标记为“好的”,如果没有不成功的断言。

单元测试代码:

public class ProjectToTestActivityTest extends ActivityInstrumentationTestCase2<ProjectToTestActivity> {

    private TextView resultView;
    private EditText editInput;
    private Button   sortButton;

    public ProjectToTestActivityTest(String pkg, Class activityClass) {
        super("com.projet.to.test", ProjectToTestActivity.class);
    }

public void onTextChanged(String str)
{
    Assert.assertTrue(str.equalsIgnoreCase("1234567890"));
}


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

           Activity activity = getActivity();  
           resultView = (TextView) activity.findViewById(R.id.result);
           editInput = (EditText) activity.findViewById(R.id.editInput);
           sortButton = (Button) activity.findViewById(R.id.sortButton);

       resultView.addTextChangedListener(new TextWatcher() {

        public void afterTextChanged(Editable arg0) {
            onTextChanged(arg0.toString());
        }
           }
       }  

       protected void testSequenceInputAndSorting()
       {
           editInput.setText("1234567890");
           sortButton.performClick();   
       }
}
4

1 回答 1

1

假设业务逻辑在应用程序项目下的Activity中正确实现,换句话说,当单击按钮时,将文本从EditText复制到TextView。

我如何为此类活动编写单元测试?

public void testButtonClick() {

  // TextView is supposed to be empty initially.
  assertEquals("text should be empty", "", resultView.getText());

  // simulate a button click, which copy text from EditText to TextView.
  activity.runOnUiThread(new Runnable() {
    public void run() {
      sortButton.performClick();
    }
  });

  // wait some seconds so that you can see the change on emulator/device.
  try {
    Thread.sleep(3000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }

  // TextView is supposed to be "foo" rather than empty now.
  assertEquals("text should be foo", "foo", resultView.getText());
}

更新:

如果你在主应用代码中不使用线程,主应用中只有 UI 线程,所有 UI 事件(按钮单击、textView 更新等)都在 UI 线程中连续处理,这种连续的 UI 不太可能事件将卡住/延迟超过几秒钟。如果您仍然不太确定,请使用waitForIdleSync()让测试应用程序等待,直到主应用程序的 UI 线程上没有更多 UI 事件要处理:

getInstrumentation().waitForIdleSync();
assertEquals("text should be foo", "foo", resultView.getText());

但是,getInstrumentation().waitForIdleSync();不会等待在您的主应用程序代码中产生的线程,例如,当单击按钮时,它会启动 AsyncTask 进程耗时的作业,并在完成后(例如 3 秒),它会更新 TextView,在这种情况下,您必须使用Thread.sleep();才能让您测试应用程序停止并等待,请查看此链接中的答案以获取代码示例。

于 2012-07-25T04:59:40.497 回答