📜 ⬆️ ⬇️

Pleasant testing with Espresso

image
I want to bring to your attention a library for testing Android applications from Google. Espresso was announced on April 23 last year at Google Test Automation Conference 2013. In October last year, it officially became an Open Source project. What is this library, we consider below.

GoogleInstrumentationTestRunner


Google InstrumentationTestRunner, the heir to the standard InstrumentTestRunner, which has been improved. One of its most important advantages is that it guarantees the execution of the test after starting and starting the application. In other words, it guarantees that all tests will start after the execution of onCreate (if this condition is not met, this may lead to unexpected exceptions). It also ensures that all running activations are completed before the end of GoogleInstrumentationTestRunner. Supports tests starting with Api 8.

Version 1.1


January 8, 2014 released a new version. What's new:

From the author


Before moving from theory to practice, I want to share my impressions. The library is very young, it does not even have a year. But it still works stably and it came out immediately from version 1.0, which already indicates that it came out not just for the beta / alpha test. It is very pleasant to write tests with its help, since it takes on a lot of functionality. For example, you do not need to focus on the button, check whether it is available on the screen, etc., with Espresso, you just turn to the button by its id or text / description and Espresso will do everything for you if the button is not visible or not available on the screen, the test machine will not pass. They really placed a lot of emphasis on UI.
The guys with the support (they are also the developers of this miracle) are trying to quickly and fully deploy the answers to your questions. I had a chance to talk with them a little. So, the most important question that they asked "What Espresso is better than Robotium?". They say that Robotium is really good, but the main reason why they decided to write their framework is the speed of the tests and their stability is not always. They assure that Espresso works much faster than other frameworks (although the numbers do not give, I will try to make comparisons in the near future). But one more important feature is the fact that Espresso uses synchronization with Main Thread. Instrumentation is launched in a separate thread, without synchronization of tests with updating the UI, problems arise with speed and critical errors may occur in the tests themselves. Most developers ignore this fact and put delays in the stream (sleep), which is no longer correct. With Espresso, you no longer need to do this. Robotium, in turn, does not use synchronization, which entails streaming streams and slow execution of tests. Initially, all Google applications were tested using Robotium, because at that moment there was no time to write your own tool. You can cover up to 95% of your projects with tests!
There was another situation when I needed to run a test project in my Application. It would seem, everything is simple, redefined the standard, substituted into the manifest and that's it. But as it turned out, the tests all work in the same Application as the application. I understand that this is logical, but this implementation was not possible.

From theory to practice


Main classes:

On the Espresso should go at least for its simplicity. Work with View is written in one line. Let's write a simple example for entering data into EditText and clicking a button:
@SmallTest public void testSendMessageUI() { Espresso.onView(ViewMatchers.withId(com.eleks.espresso.example.app.R.id.etEmail)).perform(ViewActions.typeText("test@test.com")); Espresso.onView(ViewMatchers.withId(com.eleks.espresso.example.app.R.id.etMessage)).perform(ViewActions.typeText("Espresso")); Espresso.onView(ViewMatchers.withId(com.eleks.espresso.example.app.R.id.btnSend)).perform(ViewActions.click()); } 

It's simple. Look for the View on the screen with the help of ViewMatchers by id, enter text simulating human input. Next is the button and the onClick event occurs on it. Try to hide the button and you will see that the test will not pass as Espresso simply will not find it on the screen.
')
  @SmallTest public void testOpenNavigationDrawer() { Espresso.onView(ViewMatchers.withId(com.eleks.espresso.example.app.R.id.content_frame)).perform(ViewActions.swipeRight()); ListView lvDrawerMenu = (ListView) getActivity().findViewById(com.eleks.espresso.example.app.R.id.lvDrawerMenu); Preconditions.checkNotNull(lvDrawerMenu, "lvDrawerMenu is null"); final int count = lvDrawerMenu.getAdapter().getCount(); Preconditions.checkPositionIndex(2, count, "No 1 index " + count + " size"); Object obj = lvDrawerMenu.getItemAtPosition(2); Espresso.onView(Matchers.allOf(ViewMatchers.withId(com.eleks.espresso.example.app.R.id.tvItem), ViewMatchers.hasSibling(ViewMatchers.withText(obj.toString())))).perform(ViewActions.click()); } 

In this example, the swipe is made to the right and the NavigationDrawer opens. Next in the onClick event occurs on the third cell of the sheet. The Preconditions class is used to validate input data. It is convenient for them to check null, go beyond the bounds of the array, check position, check value, etc. Next, we look for any View with a value that we previously pulled from the sheet.
For better reliability and compatibility of tests, the Espresso developers recommend the onView method and the ViewMatcher class, which itself searches for View to activate, instead of the usual findViewById. But in this case, you have to write custom handlers and methods, since if we find the View with the help of a ViewMatcher, then the baggage of methods we can call will be limited. But in any case, Espresso is moving in the right direction and its developers are trying to make the writing of tests as pleasant as possible.
Example on Github
Where to download Espresso

Source: https://habr.com/ru/post/212425/


All Articles