問(wèn)題描述
我們正在構(gòu)建一個(gè)復(fù)雜的 Android 應(yīng)用程序,該應(yīng)用程序由分布在許多活動(dòng)中的許多屏幕和工作流組成.我們的工作流程類(lèi)似于您在銀行的 ATM 機(jī)上看到的工作流程,例如,有一個(gè) Activity
可以登錄,轉(zhuǎn)換到主菜單 Activity
可以轉(zhuǎn)換到基于用戶選擇的其他活動(dòng).
We are building a complex Android application consisting of many screens and workflows spread across many Activities. Our workflows are similar to what you might see on a Bank's ATM machine, for example, there is an Activity
to login in that transitions to a main menu Activity
which can transition to other activities based on the user's choices.
由于我們有如此多的工作流程,我們需要?jiǎng)?chuàng)建跨越多個(gè)活動(dòng)的自動(dòng)化測(cè)試,以便我們可以端到端地測(cè)試工作流程.例如,使用 ATM 示例,我們想輸入一個(gè)有效的 PIN,驗(yàn)證將我們發(fā)送到主菜單,選擇提取現(xiàn)金,驗(yàn)證我們是否在提取現(xiàn)金屏幕上等等,最終找到自己返回主菜單或退出".
Since we have so many workflows we need to create automated tests that span multiple activities so we can test a workflow from end to end. For example, using the ATM example, we would want to enter a valid PIN, verify that sends us to the main menu, choose withdraw cash, verify that we are on the withdraw cash screen, etc., etc., and eventually find ourselves back on the main menu or "logged" out.
我們玩弄了 Android 附帶的測(cè)試 API(例如 ActivityInstrumentationTestCase2
)以及 Positron,但似乎都無(wú)法測(cè)試超出單個(gè) Activity
的范圍,雖然我們可以在這些工具中找到一些實(shí)用程序來(lái)進(jìn)行某些單元測(cè)試,但它們不會(huì)無(wú)法滿足我們對(duì)跨越多個(gè)活動(dòng)的測(cè)試場(chǎng)景的需求.
We've toyed with the test APIs that come with Android (e.g. ActivityInstrumentationTestCase2
) and also with Positron, but neither seem capable of testing beyond the bounds of a single Activity
, and while we can find some utility in these tools for some unit testing, they won't meet our needs for testing scenarios that cut across multiple Activities.
我們對(duì) xUnit 框架、腳本、GUI 記錄器/回放等持開(kāi)放態(tài)度,并希望得到任何建議.
We are open to an xUnit framework, scripting, GUI recorders/playbacks, etc. and would appreciate any advice.
推薦答案
回答我自己的懸賞問(wèn)題有點(diǎn)尷尬,但這里是......
I feel a bit awkward about answering my own bounty question, but here it is...
我對(duì)此進(jìn)行了高低搜索,無(wú)法相信任何地方都沒(méi)有發(fā)布答案.我已經(jīng)非常接近了.我現(xiàn)在絕對(duì)可以運(yùn)行跨越活動(dòng)的測(cè)試,但我的實(shí)現(xiàn)似乎有一些時(shí)間問(wèn)題,測(cè)試并不總是可靠地通過(guò).這是我所知道的成功跨多個(gè)活動(dòng)進(jìn)行測(cè)試的唯一示例.希望我對(duì)它的提取和匿名化不會(huì)引入錯(cuò)誤.這是一個(gè)簡(jiǎn)單的測(cè)試,我在登錄活動(dòng)中輸入用戶名和密碼,然后觀察在不同的歡迎"活動(dòng)中顯示正確的歡迎消息:
I've searched high and low on this and can't believe there is no answer published anywhere. I have come very close. I can definitely run tests that span activities now, but my implementation seems to have some timing issues where the tests don't always pass reliably. This is the only example that I know of that tests across multiple activities successfully. Hopefully my extraction and anonymizing of it did not introduce errors. This is a simplistic test where I type a username and password into a login activity, and then observe a proper welcome message is shown on a different "welcome" activity:
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!"));
}
}
這段代碼顯然不是很可讀.我實(shí)際上已經(jīng)將它提取到一個(gè)帶有類(lèi)似英語(yǔ) API 的簡(jiǎn)單庫(kù)中,所以我可以這樣說(shuō):
This code is obviously not very readable. I have actually extracted it into a simple library with an English-like API so I can just say things like this:
type("myUsername").intoThe(username_field);
click(login_button);
我已經(jīng)對(duì)大約 4 項(xiàng)活動(dòng)進(jìn)行了深度測(cè)試,并且對(duì)這種方法的工作感到滿意,盡管正如我所說(shuō),似乎偶爾會(huì)出現(xiàn)一個(gè)我還沒(méi)有完全弄清楚的時(shí)間問(wèn)題.我仍然有興趣了解跨活動(dòng)的任何其他測(cè)試方式.
I've tested to a depth of about 4 activities and am satisfied that the approach works though as I said, there appears to be an occasional timing issue I have not completely figured out. I am still interested in hearing of any other ways of testing across activities.
這篇關(guān)于如何跨多個(gè)活動(dòng)測(cè)試 Android 應(yīng)用程序?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!