如何使用Espresso空闲资源进行网络通话

编程入门 行业动态 更新时间:2024-10-10 12:16:50
本文介绍了如何使用Espresso空闲资源进行网络通话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试使用Espresso来测试我的UI.当我登录到我的应用程序时,我将调用Parse API(网络调用)以验证用户名和密码.如果一切顺利,用户将被带到一个新的活动.我想测试一下,但是我似乎无法使用空闲资源.

Im trying to use Espresso to test my UI. When i login into my application, i do a call to Parse API (network call) to verify the username and password. If all is well the user gets directed to a new activity. I want to test this, but i cant seems to work with the idle resource thing.

代码:

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("s@s.nl"), 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()); } } } }

}

我现在得到的异常如下:

The exception i get now is the following:

ndroid.support.test.espresso.IdlingResourceTimeoutException: Wait for [FooServerCalls] to become idle timed out

当我运行测试时,用户名和密码已被填写,但是执行点击从未被调用,几秒钟后我得到了异常.我应该如何正确实现空闲资源?

When i run the test, the username and password are getting filled in but the perform click is never called and i get the exception after a few seconds. How should i implement the idle resource correctly?

编辑-

我建议为Android使用Calabash. Calabash的工作原理类似,但不需要您更改应用程序代码即可进行测试.

I would recommend using Calabash for Android. Calabash works similar but doesn't need you to change your app code for testing.

推荐答案

就像其他答案所示,countingIdlingResource并不真正适用于您的用例.

Like the other answer suggests, the countingIdlingResource does not really apply for your use case.

我通常要做的是添加一个接口-我们将此称为ProgressListener-作为活动/片段的字段,该字段具有要等待的资源(异步后台工作,更长的网络会话等)和一个每次显示或取消进度时都通知它的方法.

What I always do is add an interface - let's call this one ProgressListener - as a field of the activity / fragment that has a resource to be waited on (asynchronous background work, longer networking sessions, etc.) and a method to notify it everytime the progress is shown or dismissed.

我假设您具有凭据验证逻辑,并且在LoginActivity中具有对Parse API的调用,如果成功,它将调用对MainActivity的意图.

I'm assuming you have your credentials validation logic and the call to the Parse API in the LoginActivity, which will then call an intent to the MainActivity if successful.

public class LoginActivity extends AppCompatActivity { private ProgressListener mListener; ... public interface ProgressListener { public void onProgressShown(); public void onProgressDismissed(); } public void setProgressListener(ProgressListener progressListener) { mListener = progressListener; } ... public void onLoginButtonClicked (View view) { String username = mUsername.getText().toString(); String password = mPassword.getText().toString(); // validate credentials for blanks and so on // show progress and call parse login in background method showProgress(); ParseUser.logInInBackground(username,password, new LogInCallback() { @Override public void done(ParseUser parseUser, ParseException e) { dismissProgress(); if (e == null){ // Success!, continue to MainActivity via intent Intent intent = new Intent (LoginActivity.this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); } else { // login failed dialog or similar. } } }); } private void showProgress() { // show the progress and notify the listener ... notifyListener(mListener); } private void dismissProgress() { // hide the progress and notify the listener ... notifyListener(mListener); } public boolean isInProgress() { // return true if progress is visible } private void notifyListener(ProgressListener listener) { if (listener == null){ return; } if (isInProgress()){ listener.onProgressShown(); } else { listener.onProgressDismissed(); } } }

然后,只需实现 IdlingResource 类,通过其 ResourceCallBack

Then, simply implement the IdlingResource class and override its methods to communicate when the resource goes from busy to idle through its ResourceCallBack

public class ProgressIdlingResource implements IdlingResource { private ResourceCallback resourceCallback; private LoginActivity loginActivity; private LoginActivity.ProgressListener progressListener; public ProgressIdlingResource(LoginActivity activity){ loginActivity = activity; progressListener = new LoginActivity.ProgressListener() { @Override public void onProgressShown() { } @Override public void onProgressDismissed() { if (resourceCallback == null){ return ; } //Called when the resource goes from busy to idle. resourceCallback.onTransitionToIdle(); } }; loginActivity.setProgressListener (progressListener); } @Override public String getName() { return "My idling resource"; } @Override public boolean isIdleNow() { // the resource becomes idle when the progress has been dismissed return !loginActivity.isInProgress(); } @Override public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { this.resourceCallback = resourceCallback; } }

最后一步是在测试的setUp()方法中注册您的自定义空闲资源:

Last step is to register your custom idling resource in the test's setUp() method:

Espresso.registerIdlingResources(new ProgressIdlingResource((LoginActivity) getActivity()));

就是这样!现在,espresso将等待您的登录过程完成,然后继续进行所有其他测试.

And that's it! Now espresso will wait for your login process to complete and then continue with all the other tests.

如果我不够清楚,或者这正是您所需要的,请告诉我.

Please let me know if I wasn't clear enough or if that is exactly what you needed.

更多推荐

如何使用Espresso空闲资源进行网络通话

本文发布于:2023-11-26 05:09:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1632761.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何使用   资源   网络   Espresso

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!