Tôi đang cố gắng sử dụng Espresso để kiểm tra giao diện người dùng của mình. Khi tôi đăng nhập vào ứng dụng của mình, tôi thực hiện cuộc gọi đến Parse API (cuộc gọi mạng) để xác minh tên người dùng và mật khẩu. Nếu tất cả là tốt, người dùng sẽ được chuyển hướng đến một hoạt động mới. Tôi muốn thử nghiệm điều này, nhưng tôi không thể dường như làm việc với các nguồn tài nguyên nhàn rỗi.Cách sử dụng Espresso Idling Resource cho các cuộc gọi mạng
Code:
public class ApplicationTest extends ActivityInstrumentationTestCase2<LoginActivity> {
private CountingIdlingResource fooServerIdlingResource;
public ApplicationTest() {
super(LoginActivity.class);
}
@Before
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
getActivity();
CountingIdlingResource countingResource = new CountingIdlingResource("FooServerCalls");
this.fooServerIdlingResource = countingResource;
Espresso.registerIdlingResources(countingResource);
}
public void testChangeText_sameActivity() {
// Type text and then press the button.
onView(withId(R.id.username))
.perform(typeText("[email protected]"), closeSoftKeyboard());
onView(withId(R.id.password))
.perform(typeText("s"), closeSoftKeyboard());
if(performClick())
onView(withId(R.id.main_relative_layout))
.check(matches(isDisplayed()));
// Check that the text was changed.
}
public boolean performClick(){
fooServerIdlingResource.increment();
try {
onView(withId(R.id.login)).perform(click());
return true;
} finally {
fooServerIdlingResource.decrement();
}
}
@SuppressWarnings("javadoc")
public final class CountingIdlingResource implements IdlingResource {
private static final String TAG = "CountingIdlingResource";
private final String resourceName;
private final AtomicInteger counter = new AtomicInteger(0);
private final boolean debugCounting;
// written from main thread, read from any thread.
private volatile ResourceCallback resourceCallback;
// read/written from any thread - used for debugging messages.
private volatile long becameBusyAt = 0;
private volatile long becameIdleAt = 0;
/**
* Creates a CountingIdlingResource without debug tracing.
*
* @param resourceName the resource name this resource should report to Espresso.
*/
public CountingIdlingResource(String resourceName) {
this(resourceName, false);
}
/**
* Creates a CountingIdlingResource.
*
* @param resourceName the resource name this resource should report to Espresso.
* @param debugCounting if true increment & decrement calls will print trace information to logs.
*/
public CountingIdlingResource(String resourceName, boolean debugCounting) {
this.resourceName = checkNotNull(resourceName);
this.debugCounting = debugCounting;
}
@Override
public String getName() {
return resourceName;
}
@Override
public boolean isIdleNow() {
return counter.get() == 0;
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}
/**
* Increments the count of in-flight transactions to the resource being monitored.
* <p/>
* This method can be called from any thread.
*/
public void increment() {
int counterVal = counter.getAndIncrement();
if (0 == counterVal) {
becameBusyAt = SystemClock.uptimeMillis();
}
if (debugCounting) {
Log.i(TAG, "Resource: " + resourceName + " in-use-count incremented to: " + (counterVal + 1));
}
}
/**
* Decrements the count of in-flight transactions to the resource being monitored.
* <p/>
* If this operation results in the counter falling below 0 - an exception is raised.
*
* @throws IllegalStateException if the counter is below 0.
*/
public void decrement() {
int counterVal = counter.decrementAndGet();
if (counterVal == 0) {
// we've gone from non-zero to zero. That means we're idle now! Tell espresso.
if (null != resourceCallback) {
resourceCallback.onTransitionToIdle();
}
becameIdleAt = SystemClock.uptimeMillis();
}
if (debugCounting) {
if (counterVal == 0) {
Log.i(TAG, "Resource: " + resourceName + " went idle! (Time spent not idle: " +
(becameIdleAt - becameBusyAt) + ")");
} else {
Log.i(TAG, "Resource: " + resourceName + " in-use-count decremented to: " + counterVal);
}
}
checkState(counterVal > -1, "Counter has been corrupted!");
}
/**
* Prints the current state of this resource to the logcat at info level.
*/
public void dumpStateToLogs() {
StringBuilder message = new StringBuilder("Resource: ")
.append(resourceName)
.append(" inflight transaction count: ")
.append(counter.get());
if (0 == becameBusyAt) {
Log.i(TAG, message.append(" and has never been busy!").toString());
} else {
message.append(" and was last busy at: ")
.append(becameBusyAt);
if (0 == becameIdleAt) {
Log.w(TAG, message.append(" AND NEVER WENT IDLE!").toString());
} else {
message.append(" and last went idle at: ")
.append(becameIdleAt);
Log.i(TAG, message.toString());
}
}
}
}
}
Ngoại lệ tôi có được bây giờ là như sau:
ndroid.support.test.espresso.IdlingResourceTimeoutException: Wait for [FooServerCalls] to become idle timed out
Khi tôi chạy thử nghiệm, tên người dùng và mật khẩu có được lấp đầy trong nhưng thực hiện nhấp chuột không bao giờ được gọi và tôi nhận được ngoại lệ sau một vài giây. Làm thế nào tôi nên thực hiện các nguồn tài nguyên nhàn rỗi một cách chính xác?
EDIT -
Tôi khuyên bạn nên sử dụng Calabash cho Android. Calabash hoạt động tương tự nhưng không cần bạn thay đổi mã ứng dụng của bạn để thử nghiệm.
Tôi sẽ dùng thử tối nay !! cảm ơn ! sẽ lấy lại cho bạn :) –
Chúc may mắn, Nó có vẻ giống như một chút công việc phụ, nhưng đăng nhập là cực kỳ hữu ích cho tôi – appoll
Tôi đã thử nó và nó đã làm việc !! tôi đã được tắt với mã của tôi! không mong muốn triển khai bất kỳ mã nào trong mã "ứng dụng" của tôi. Đó là một nhược điểm thực sự để thay đổi mã ứng dụng của tôi để làm cho các bài kiểm tra của tôi hoạt động. Tôi nhận được rất nhiều cuộc gọi API Parse. Tôi tin rằng mã của tôi sẽ là một mớ hỗn độn với tất cả điều này! Nhưng đó không phải là câu hỏi, bạn đã trả lời câu hỏi thực sự của tôi. Vì vậy, cảm ơn bạn vì điều đó ! –