单元测试:从TextView跟踪输出结果的位置

时间:2012-07-23 10:33:12

标签: android unit-testing junit

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

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

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

单元测试代码:

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();   
       }
}

1 个答案:

答案 0 :(得分: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();让测试应用程序停止并等待,请查看答案in this link以获取代码示例。