代码之家  ›  专栏  ›  技术社区  ›  SingleShot

如何跨多个活动测试Android应用程序?

  •  78
  • SingleShot  · 技术社区  · 15 年前

    我们正在构建一个复杂的Android应用程序,它由许多屏幕和分布在许多活动中的工作流组成。我们的工作流程与您在银行ATM机上看到的类似,例如,有一个 Activity 要登录,请切换到主菜单 可以根据用户的选择转换到其他活动。

    由于我们有如此多的工作流,我们需要创建跨多个活动的自动化测试,以便我们可以从端到端测试工作流。例如,以ATM为例,我们希望输入一个有效的PIN码,验证是否将我们发送到主菜单,选择取款,验证我们是否在取款屏幕上,等等,然后最终发现自己回到主菜单或“注销”。

    ActivityInstrumentationTestCase2 )还有 Positron ,但两者似乎都无法超出单个测试的范围

    我们欢迎使用xUnit框架、脚本、GUI记录器/回放等,如有任何建议,我们将不胜感激。

    14 回复  |  直到 13 年前
        1
  •  65
  •   SingleShot    15 年前

    我对回答我自己的悬赏问题感到有点尴尬,但这是。。。

    package com.mycompany;
    
    import android.app.*;
    import android.content.*;
    import android.test.*;
    import android.test.suitebuilder.annotation.*;
    import android.util.*;
    import android.view.*;
    import android.widget.*;
    
    import static org.hamcrest.core.Is.*;
    import static org.hamcrest.core.IsNull.*;
    import static org.hamcrest.core.IsInstanceOf.instanceOf;
    import static org.junit.Assert.*;
    import static com.mycompany.R.id.*;
    
    public class LoginTests extends InstrumentationTestCase {
    
       @MediumTest
       public void testAValidUserCanLogIn() {
    
          Instrumentation instrumentation = getInstrumentation();
    
          // Register we are interested in the authentication activiry...
          Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor(AuthenticateActivity.class.getName(), null, false);
    
          // Start the authentication activity as the first activity...
          Intent intent = new Intent(Intent.ACTION_MAIN);
          intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          intent.setClassName(instrumentation.getTargetContext(), AuthenticateActivity.class.getName());
          instrumentation.startActivitySync(intent);
    
          // Wait for it to start...
          Activity currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5);
          assertThat(currentActivity, is(notNullValue()));
    
          // Type into the username field...
          View currentView = currentActivity.findViewById(username_field);
          assertThat(currentView, is(notNullValue()));
          assertThat(currentView, instanceOf(EditText.class));
          TouchUtils.clickView(this, currentView);
          instrumentation.sendStringSync("MyUsername");
    
          // Type into the password field...
          currentView = currentActivity.findViewById(password_field);
          assertThat(currentView, is(notNullValue()));
          assertThat(currentView, instanceOf(EditText.class));
          TouchUtils.clickView(this, currentView);
          instrumentation.sendStringSync("MyPassword");
    
          // Register we are interested in the welcome activity...
          // this has to be done before we do something that will send us to that
          // activity...
          instrumentation.removeMonitor(monitor);
          monitor = instrumentation.addMonitor(WelcomeActivity.class.getName(), null, false);
    
          // Click the login button...
          currentView = currentActivity.findViewById(login_button;
          assertThat(currentView, is(notNullValue()));
          assertThat(currentView, instanceOf(Button.class));
          TouchUtils.clickView(this, currentView);
    
          // Wait for the welcome page to start...
          currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5);
          assertThat(currentActivity, is(notNullValue()));
    
          // Make sure we are logged in...
          currentView = currentActivity.findViewById(welcome_message);
          assertThat(currentView, is(notNullValue()));
          assertThat(currentView, instanceOf(TextView.class));
          assertThat(((TextView)currentView).getText().toString(), is("Welcome, MyUsername!"));
       }
    }
    

    type("myUsername").intoThe(username_field);
    click(login_button);
    

    我已经对大约4项活动进行了深入测试,并对该方法的有效性感到满意。尽管如我所说,似乎偶尔会出现一个我还没有完全弄清楚的时间问题。我仍然有兴趣听到任何其他跨活动的测试方法。

        2
  •  22
  •   Jonas Söderström    15 年前

    机器人

    主页: http://www.robotium.org/
    资料来源: http://github.com/jayway/robotium

    请注意,Robotium项目由我工作的公司维护

        3
  •  8
  •   Renas    15 年前

        4
  •  4
  •   Community CDub    7 年前

    我很惊讶没有人提到一些主要的 自动功能测试工具 . 与Robotium相比,它们不需要编写Java代码。

    MonkeyTalk :由Gorilla Logic公司支持的开源工具。优点:为非技术用户提供录制和更高级别的脚本语言,并且是跨平台的(包括iOS)。考虑到这些好处,我们发现这是最好的解决方案。它还允许 customization 除了使用Javascript在脚本语言中可以做什么之外。

    Calabash-Android :用于Cucumber样式功能的开源工具。优点:用小黄瓜语言编写特性,这是一种商业可读的、领域特定的语言,可以让您描述软件的行为,而无需详细说明该行为是如何实现的。中的iOS提供了类似但不精确的支持 cucumber-ios . 录制功能并不是很好,因为它们会产生二进制输出。

        5
  •  3
  •   Brian Kyckelhahn    13 年前

    我为Android创建了一个录制和播放工具,并在 GitHub

        6
  •  3
  •   Lew Bloch    12 年前

    首先,使用“ActivityInstrumentationTestCase2”而不是“InstrumentationTestCase”作为基类。我使用Robotium并在多个活动中进行常规测试。我发现必须将登录活动指定为泛型类型(以及构造函数的类参数)。

    从Javadocs: 此构造函数已弃用。改用ActivityInstrumentationTestCase2(类)

    使用推荐的基类允许框架处理某些样板文件,比如启动活动。如有必要,可通过调用“getActivity()”来完成此操作。

        7
  •  3
  •   Ajinkya Amit Jain    10 年前

    经过几次修改后,发现这很有用。 首先 getInstrumentation().waitForIdleSync() 会治愈单枪所说的片状皮肤病吗 InstrumentationTestCase 有一个 lauchActivity 可以替换开始活动行的函数。

        8
  •  2
  •   chewpoclypse j2emanue    8 年前

    您可以这样做以避免薄片等待时间不同步:

    final Button btnLogin = (Button) getActivity().findViewById(R.id.button);
    Instrumentation instrumentation = getInstrumentation();
    
    // Register we are interested in the authentication activity...
    Instrumentation.ActivityMonitor aMonitor = 
            instrumentation.addMonitor(mynextActivity.class.getName(), null, false);
    
    getInstrumentation().runOnMainSync(new Runnable() {
             public void run() {
                 btnLogin.performClick();
             }
         });
    
    getInstrumentation().waitForIdleSync();
    
    //check if we got at least one hit on the new activity
    assertTrue(getInstrumentation().checkMonitorHit(aMonitor, 1)); 
    
        9
  •  1
  •   Peter Ajtai    13 年前

    我正在做几乎相同的事情,我可能会对这个问题的公认答案进行修改,但我确实遇到了一些问题 Calculuon ( gitHub ) 在我寻找解决方案的过程中。

        10
  •  0
  •   Eric Gulzar Bhat    15 年前

        11
  •  0
  •   user643154    14 年前

        12
  •  0
  •   sandeep    13 年前

    还有另一种方法可以使用ActivityInstrumentation类执行多个活动。。 这是一个正常的自动化场景。。。 示例代码

    button.requestFocus();
    sendKeys(KeyEvent.KEYCODE_ENTER);
    

        13
  •  0
  •   pajato0    10 年前

    这个答案基于公认的答案,但经过修改以解决时间问题,对我来说,在添加了大约六个测试后,时间问题变得一致@pajato1因解决了时间问题而获得了荣誉,如公认的答案评论中所述。

    /**
     * Creates a test Activity for a given fully qualified test class name.
     *
     * @param fullyQualifiedClassName The fully qualified name of test activity class.
     *
     * @return The test activity object or null if it could not be located.
     */
    protected AbstractTestActivity getTestActivity(final String fullyQualifiedClassName) {
        AbstractTestActivity result = null;
    
        // Register our interest in the given activity and start it.
        Log.d(TAG, String.format("Running test (%s) with main class: %s.", getName(), fullyQualifiedClassName));
        instrumentation = getInstrumentation();
    
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setClassName(instrumentation.getTargetContext(), fullyQualifiedClassName);
        // Wait for the activity to finish starting
        Activity activity = instrumentation.startActivitySync(intent);
    
        // Perform basic sanity checks.
        assertTrue("The activity is null!  Aborting.", activity != null);
        String format = "The test activity is of the wrong type (%s).";
        assertTrue(String.format(format, activity.getClass().getName()), activity.getClass().getName().equals(fullyQualifiedClassName));
        result = (AbstractTestActivity) activity;
    
        return result;
    }
    
        14
  •  0
  •   Ranjithkumar    9 年前

    尝试Monkey工具测试

    打开android studio终端(工具->开放式终端)

    为了使用monkey,打开一个命令提示符,只需导航到以下目录。

     export PATH=$PATH:/home/adt-bundle-linux-x86-20140702/sdk/platform-tools
    

    步骤3:

    将此monkey命令添加到终端并按enter键。。

    adb shell monkey -p com.example.yourpackage -v 500
    

    你可以改变这个计数。。

    http://www.tutorialspoint.com/android/android_testing.htm

    http://androidtesting.blogspot.in/2012/04/android-testing-with-monkey-tool.html