如何跨多个活动testingAndroid应用程序?

我们正在构build一个复杂的Android应用程序,其中包含许多屏幕和工作stream,分布在许多活动中 我们的工作stream程类似于您在银行的ATM机上可能会看到的,例如,有一个Activitylogin到主菜单Activity ,可以根据用户的select转换到其他活动。

由于我们有这么多的工作stream程,所以我们需要创build跨越多个活动的自动化testing,以便我们可以从头到尾testing工作stream程。 例如,使用ATM示例,我们想input一个有效的PIN码,validation是否将我们发送到主菜单,select提取现金,确认我们正在提取现金屏幕等等,最终find我们自己回到主菜单或“login”出来。

我们已经玩弄了Android(例如ActivityInstrumentationTestCase2 )和Positron附带的testingAPI,但是它们看起来都不能在单个Activity之外进行testing,虽然我们可以在这些工具中find一些用于某些unit testing的实用工具,他们将不能满足我们对跨多个活动的testing场景的需求。

我们打开一个xUnit框架,脚本,graphics用户界面录像机/播放等,将不胜感激任何意见。

回答我自己的赏金问题,我感到有些尴尬,但这里是…

我已经在这个高低search,不能相信没有任何地方发表的答案。 我走得很近。 我可以肯定地运行testing,跨越活动现在,但我的实现似乎有一些时间问题,testing不总是可靠地传递。 这是我所知道的成功进行多项活动testing的唯一例子。 希望我的提取和匿名它没有引入错误。 这是一个简单的testing,我在login活动中键入用户名和密码,然后在不同的“欢迎”活动中显示正确的欢迎信息:

 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!")); } } 

这段代码显然不是很可读。 我实际上已经将它提取到一个简单的库中,并带有类似英语的API,所以我只能说这样的事情:

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

我已经testing了大约4个活动的深度,并且很满意这个方法,但是正如我所说的那样,似乎偶尔有一个我没有完全弄清楚的时间问题。 我仍然有兴趣听到其他各种活动的testing方法。

看看Robotium
“这个开源testing框架的创build使得Android应用程序的自动黑盒testing比使用Android仪器testing开箱即用的方式更快,更容易。

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

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

你可以随时使用Robotium。 它支持像Selenium一样的黑盒testing,但支持Android。 你可以在Robotium.orgfind它

我很惊讶没有人提到一些领先的自动化functiontesting工具 。 与Robotium相比,这些不需要编写Java代码。

MonkeyTalk :由Gorilla Logic公司支持的开源工具。 优点:为非技术用户提供录音以及更高级的脚本语言,并且是跨平台的(包括iOS)。 鉴于这些好处作为要求,我们发现这是最好的解决scheme。 它还允许使用Javascript在脚本语言之外进行自定义 。

Calabash-Android :黄瓜式function的开源工具。 优点:使用商业可读的特定于领域的语言来编写Gherkin语言的特性,使您可以描述软件的行为,而不用详细说明如何实现该行为。 类似的,但不是确切的支持可用于在黄瓜-ios的iOS 。 录音function不如他们产生二进制输出。

其他几个参考文献:

  • 以下是Robotium,Monkeytalk和Calabash之间的一些其他比较 。 它提到TestDroid是另一种可能性。
  • 这个博客提到了上面加上了NativeDriver和Bot-bot。

我为Android创build了一个录制和回放工具,并在GitHub上提供 。 它很容易configuration和使用,不需要编程,可以在真实的设备上运行(不必根植),并在播放testing时自动保存截图。

首先,使用“ActivityInstrumentationTestCase2”而不是“InstrumentationTestCase”作为你的基类。 我使用Robotium并定期testing多个活动。 我发现我必须指定login活动作为genericstypes(和构造函数的类参数)。

“ActivityInstrumentationTestCase2”构造函数忽略了package参数,不需要它。 采用该包的构造函数已被弃用。

从Javadocs:“ActivityInstrumentationTestCase2(String pkg,Class activityClass)此构造函数已被弃用。使用ActivityInstrumentationTestCase2(Class)而不是”

使用推荐的基类允许框架处理特定的样板,就像开始活动一样。 这是通过调用“getActivity()”来完成的,如果需要的话。

发现这个有用的几个修改。 首先getInstrumentation().waitForIdleSync()将治愈SingleShot所说的lauchActivityInstrumentationTestCase还有一个lauchActivity函数可以代替开始活动行。

你可以这样做,以避免片状等待时间不同步:

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

我正在做几乎相同的事情,我可能会去接受这个问题的接受的答案,但我在我的search解决scheme时遇到了Calculuon ( gitHub )

我没有亲自使用它,但ApplicationTestCase看起来像它可能是你在找什么。

将接受的方法与不同的应用程序的不同活动,由不同的证书签署? 如果不是,则Robotium是在同一应用程序内testing活动的最佳方法。

还有一种方法可以使用ActivityInstrumentation Class来完成多个活动。它是一个正常的自动化场景…首先获得所需的对象的焦点,然后发送一个简单的示例代码

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

唯一的事情是理解每个API调用将帮助我们。

这个答案是基于公认的答案,但修改,以解决时间问题,我join了大约六个testing后,一致。 正如接受的答案评论所引用的,@ 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; } 

尝试猴子工具testing

步骤1:

打开android studioterminal(工具 – >打开terminal)

第2步:

为了使用猴子,请打开一个命令提示符,然后导航到以下目录。

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

第3步:

添加这个猴子命令到terminal并按回车..

看你的模拟器的魔力。

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

500-这是频率计数或要发送testing的事件数量。

你可以改变这个数字

更多参考,

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

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