I am currently new to Android programming and I am trying to test parts of UI using espresso. Currently, I have a problem with a testing toast message.
Toast toast = Toast.makeText(context, R.string.some_message, duration);
toast.show();
And then in my test file, I define the Activity Scenario Rule.
public ActivityScenarioRule<CreateActivity> activityScenarioRule =
new ActivityScenarioRule<>(SomeActivity.class);
At the end the best solution that I get for testing this part looks like this.
ActivityScenario<SomeActivity> scenario = activityScenarioRule.getScenario();
scenario.onActivity(activity ->
Espresso.onView(ViewMatchers.withText(R.string.error_message)).inRoot(RootMatchers.withDecorView
(not(is(activity.getWindow().getDecorView())))).check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
);
When I run the test it never stops. Any help would be useful. :)
Related
I have an android PrintService launched by an Application.
I would like to be able to display toasts from the PrintService when I'm selecting the printer on which to print etc. (UI generated by the android system, picture here).
On Android <11 it works fine, however for 11+, I'm not able to display a toast...
I've tried several code (Kotlin) :
Toast.makeText(<context>, message, Toast.LENGTH_LONG).show()
Handler(Looper.getMainLooper()).post {
Toast.makeText(context.applicationContext, message, Toast.LENGTH_LONG).show()
}
Where I tried the following values of :
this (the PrintService)
this.applicationContext
this.baseContext
Still, I'm never able to display a toast on the printer selection page...
Is it possible ? What is wrong in my code ?
Hi i have written testCases using espresso for the Android app.
Below is my code. my requirement is i need to manally Login to my app by entering credentials before i test the title bar Text.
So i am going into sleep for 2 min. when i enter credentials and click Login button below error is coming.
"D/InputEventConsistencyVerifier: TouchEvent: Touch event stream contains events from multiple sources: previous device id 0, previous source 2, new device id 0, new source 1002 "
Please let me know how to achieve this....
#Test
public void checkTitleBarText() throws InterruptedException {
sleep(120000);
onView(withId(R.id.drawer_layout)).perform(actionOpenDrawer());
Assert.assertEquals("SomeText", (String) textView.getText());
}
Why can't you just login with espresso? I'd be much easier...
However, If it's really your requirement, You can always launch tests with debuger attached and put a breakpoint in test code (which is stopping test thread). Login manually then and resume execution.
I'm working with espresso for testing. I'm following Espresso Intents
and problem happened when I try to work like this site. First is validateIntentSentToPackage method:
public void validateIntentSentToPackage() {
user.clickOnView(system.getView(R.id.callButton));
intended(toPackage("com.android.phone"));}
Android Studio display error at "user" and "system". I don't understand this error what does this mean.
Second is activityResult_IsHandledProperly method:
public void activityResult_IsHandledProperly() {
Intent resultData = new Intent();
String phoneNumber = "123-345-6789";
resultData.putExtra("phone", phoneNumber);
ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData);
intending(toPackage("com.example.unittestdemo")).respondWith(result));
onView(withId(R.id.pickButton)).perform(click());
onView(withId(R.id.phoneNumber).check(matches(withText(phoneNumber)));}
Android Studio display error java.lang.NullPointerException and in line intending(toPackage("com.example.unittestdemo")).respondWith(result);
Please help!!!
Android Studio display error at "user" and "system". I don't understand this error what does this mean.
I guess, you don't have previously declared these variables.
I don't see any logs or whole code of this testing class, so I can only recommend you to check this example
Here you would find all methods which you're looking for in one file.
Also please visit Google Samples - Espresso Testing repository
I show the toast, it doesn't disappear, even after the app is closed. How do I fix?
#Override
public void onClipStoreLoadedClipsNotification(ClipStoreLoadedClipsNotification notif)
{
final ClipStoreLoadedClipsNotification notification = notif;
runOnUiThread(new Runnable() {
#Override
public void run()
{
Dialogs.DismissAll();
list.onRefreshComplete();
TextView text = (TextView)findViewById(R.id.loadclipstext);
ProgressBar pb = (ProgressBar)findViewById(R.id.loadclipsprogress);
if (notification.moreClipsAvailable)
{
text.setText(context.getString(R.string.loading_clips));
pb.setVisibility(View.VISIBLE);
}
else
{
text.setText(context.getString(R.string.no_clips));
pb.setVisibility(View.INVISIBLE);
int duration = Toast.LENGTH_SHORT;
Toast.makeText(SugarLoafContext.playbackTabContext, "No clips found.", duration).show();
}
SugarLoafContext.currentCamera = notification.camera;
clipList = notification.clips;
refreshListView();
readyToLoadMoreClips = true;
if (!firstClipsLoaded)
firstClipsLoaded = true;
}
});
}
Is it running inside a IntentService???
If it is so, the problem is that the Intent Services in Android run in a different thread than the main one, so the Toast is shown in a different thread than the main one, after the time to show is finished, the Android system is unable to find where is the Toast, so it can´t remove it.
I had the same problem, and now, i recommend everyone NOT to show Toast inside a IntentService, instead try to run one commom Service, or to open an Activity, or try something different if it is completely necessary to show the Toast.
The fact that the Toast doesn´t dissapear when you close the App is that the IntentService is still running, and you have to reboot the system or to uninstall the App for the Intent Service to be close.
The only explanation is that your Toast is called in a loop. You should track the toast .show() and see if it is not called an infinite times.
An other visual way would be to do this
Toast.makeText(SugarLoafContext.playbackTabContext, "No clips found.", duration).show();
Toast.makeText(SugarLoafContext.playbackTabContext, "Do you understand now?", duration).show();
I am sure you will see both toast alternatively during a looong time...
This can also happen if your device has no network connection, and your app does a license check and shows a Toast of results. One of my apps had this problem, as I was displaying a Toast when checking the app was licensed. Without a network connection the Toast telling the user that a license retry was to be done remained, and when I connected the Toast was removed, because the license check could work.
I'm currently building an app in Android, and using Robotium to do functional tests (By the way, don't use Robotium on anything less that Android 1.6, it is way too buggy).
Some of these tests have a random tendency to fail, mainly Robotium missing a text field, or timing out, not reading text. I am trying to use the #FlakyTest annotation, so they will run two or three times before throwing out a failed test error. However, the annotation is not working, the tests do not re-run after a failure.
Here is how I am using the annotation:
public class ClassName extends ActivityInstrumentationTestCase2<HomeActivity>{
#LargeTest
#FlakyTest(tolerance=3)
public void testMethod(){
//Here I run my roboitium scripts.
}
}
Then I run it from the command line:
adb shell am instrument -w com.jayway.test/android.test.InstrumentationTestRunner
Neither eclipse nor the command line execution of the tests takes into account the flaky test annotation. Does anyone see an error with how I am trying to apply #FlakyTest?
I can't see any issue with your use of the #FlakyTest annotation.
I put together a quick test case to test #FlakyTest and Robotium (v2.2):
public class FlakyTestCase extends ActivityInstrumentationTestCase2<Main> {
private static int count = 0;
private Solo solo;
public FlakyTestCase() {
super("com.stackoverflow.example", Main.class);
}
#Override
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
#LargeTest
#FlakyTest(tolerance=3)
public void testFlaky(){
Log.e("FlakeyTestCase", "Execution Count:" + ++count);
solo.assertCurrentActivity(null,Main.class);
solo.clickOnText("Doesn't Exist");
Log.e("FlakeyTestCase", "Shouldn't make it here");
}
}
LogCat showed the following messages:
Execution Count: 1
Execution Count: 2
Execution Count: 3
So the #FlakyTest annotation was definitely being invoked. The (final) failure of the test was shown as:
junit.framework.AssertionFailedError: The text: Doesn't Exist is not found!
And the message "Shouldn't make it here" was never logged.
So as far as I can see, there is no issue with how you've declared your annotation or any problems with #FlakyTest and Robotium, v2.2 anyway.
Perhaps there is an issue with another part of your test code?
In general, when writing tests for Android (with or without Robotium) you have to be much more careful. You can't just say "is this visible". You need to wrap everything in a "wait for" cycle, so would say "wait for this to be visible". This is particularly a problem when running in the emulators, because sometimes things take long without any good reason. Without the waiting cycles, you will never have a consistent run. We have a few hundred tests and we have never needed to use the FlakyTest annotation.
Robotium missing a text field, or timing out, not reading text means
We have to check clearly if the text or any existed on the screen then only need to perform the actions like
if(solo.searchText("Doesn't Exist", true){
solo.clickOnText("Doesn't Exist");
}
Similar if any components like button or others we can achieve this by above logic.
Add this to your code:
import android.util.Log;