All Projects → parthdave93 → Androidtestingtutorial

parthdave93 / Androidtestingtutorial

Licence: apache-2.0
Getting started with Espresso Unit Testing

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Androidtestingtutorial

Android Jetpack Playground
Pet project for cutting edge Android development with Jetpack
Stars: ✭ 266 (+2560%)
Mutual labels:  espresso
Js Samples
Samples for the Google Maps JavaScript v3 API
Stars: ✭ 362 (+3520%)
Mutual labels:  googlemaps
Kotlin Android Starter
[Kotlin Android] Kotlin Android starter based MVP/Dagger2/RxJava2/Robolectric/Espresso/Mockito. It provides a generator to fast create a Kotlin Android project.
Stars: ✭ 589 (+5790%)
Mutual labels:  espresso
Avenging
MVP pattern example on Android: no Dagger or RxJava example
Stars: ✭ 279 (+2690%)
Mutual labels:  espresso
Android Gif Example
Gif RecyclerView in MVP using Dagger 2 + Retrofit 2 + Moshi + RxJava 2 + Glide 4 with JUnit and Espresso tests written in Kotlin + Kotlin DSL!
Stars: ✭ 334 (+3240%)
Mutual labels:  espresso
Clusterkit
An iOS map clustering framework targeting MapKit, Google Maps and Mapbox.
Stars: ✭ 476 (+4660%)
Mutual labels:  googlemaps
espresso-robot-pattern-sample
Espresso Robot Pattern Sample with Spoon Integration
Stars: ✭ 37 (+270%)
Mutual labels:  espresso
Flutter Cab
Stars: ✭ 19 (+90%)
Mutual labels:  googlemaps
Ideasnprojects
That Project's Source Code
Stars: ✭ 344 (+3340%)
Mutual labels:  espresso
Archapp
Simple Android app to show how to design a multi-modules MVVM Android app (fully tested)
Stars: ✭ 551 (+5410%)
Mutual labels:  espresso
Clean Mvvm Archcomponents
👽 Android app consuming Star Wars API.Built with clean architecture ,MVVM pattern, Koin , Coroutines + Flows ,Architecture Components, Data Binding , Firebase , Unit/UI Tests ,Motion Layout
Stars: ✭ 285 (+2750%)
Mutual labels:  espresso
Cortado
Android Espresso made more fluent ☕️
Stars: ✭ 332 (+3220%)
Mutual labels:  espresso
Android Starter
[Android Architecture] Android starter based on MVP/Dagger2/RxJava2/Robolectric/Espresso/Mockito. It provides a generator to fast create a Android template project.
Stars: ✭ 522 (+5120%)
Mutual labels:  espresso
Covid19 Full Stack Application
Coronavirus - (COVID-19) Full Stack Application
Stars: ✭ 270 (+2600%)
Mutual labels:  googlemaps
Katasuperheroesandroid
Super Heroes Kata for Android Developers. The main goal is to practice UI Testing.
Stars: ✭ 680 (+6700%)
Mutual labels:  espresso
ESPressIoT
This project covers somewhat advances features for an espresso machine controller.
Stars: ✭ 31 (+210%)
Mutual labels:  espresso
Espressoexamples
A collection of examples demonstrating different techniques for automated testing with Espresso.
Stars: ✭ 396 (+3860%)
Mutual labels:  espresso
Mapme
The Android maps adapter
Stars: ✭ 844 (+8340%)
Mutual labels:  googlemaps
Okreplay
📼 Record and replay OkHttp network interaction in your tests.
Stars: ✭ 697 (+6870%)
Mutual labels:  espresso
Flask Googlemaps
Easy way to add GoogleMaps to Flask applications. maintainer: @RiverFount
Stars: ✭ 550 (+5400%)
Mutual labels:  googlemaps

AndroidTestingTutorial

Getting started with Espresso Unit Testing

Why Testing?

testing is the process of evaluation a software item to detect differences between given input and expected output.

Categories of Testing

  1. Black box testing
  2. White box testing
    etc... others can be found here

Black box testing

Tests are based on requirements and functionality.

White box testing

Tests are based on coverage of code statements, branches, paths, conditions.

TDD

Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: requirements are turned into very specific test cases, then the software is improved to pass the new tests, only.

Android Testing Tools

  1. Espresso by google team
  2. Roboletric
  3. Appium

Espresso

Mainly focused on UI and Thread idealization, which helps the unit tests to run without worring about api response state It checks the threads and waits for ui thread to be idealize which is dismiss progress bar or any event which shows that activity is performing some event.

Why Espresso

Other tools like Roboletric is also famous for testing android apps but it has it's own android jar which is our basic android kit classes. As google updates their support library often it's hard to keep in update for Roboletric. And to mock the android classes becomes hard with Roboletric. Check out link here Roboletric vs Espresso for more details.

Let's start with testing

Let's check how to write test so in Espresso we have

@Rule
public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<>(LoginActivity.class, true);

Above test rule defines for which activity you'r going to write test class
Now new ActivityTestRule<>(LoginActivity.class, true); if you do want to open activity which is not launcher activity then pass true in constructor else pass nothing for second parameter new ActivityTestRule<>(LoginActivity.class);
There is multiple ways to open activity so do checkout Espresso Doc.


@RunWith(AndroidJUnit4.class)
public class PerfomClickAndCheckTextError {
    
    @Rule
    public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<>(LoginActivity.class, true);
    .......
}

You need to define that your going to use junit4 test class to run with below test class. if your test case is large then mention @LargeTest above class

Now before going any further with real test code other things to mention here is if we want to run some method before activity launches you can do it by specifying @Before annotation above your method.


    @RunWith(AndroidJUnit4.class)
    public class PerfomClickAndCheckTextError {
    
        @Rule
        public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<>(LoginActivity.class, true);
    
        //To get resources in testing
        Resources resources;
        
        @Before
        public void initThingsHere() {
            //do stuff like database or preference or image copying here
            resources = InstrumentationRegistry.getTargetContext().getResources();
        }
    }

Like above I had taken resources.

Tutorial 1

We have started programming with hello world! program and for testing we will do the same. Simple step check the text is on the screen. but before that let's check how to find view from the screen in Espresso

To check there is 2 steps:

  1. Find view on screen
  2. Check if exists or displayed

Find view on screen


As we have findViewById in android, so in background what android system will do is it will check for that id view from rootview and give it back, we have onView() but to find views we can use multiple methods not by just ids. we have withId(), withText(), withTagKey() etc.

Check if exists or displayed

To check we have check() method in which we will give matcher which will conditionalize the view like if it displayed or not.

So we have

    onView(withText("Hello Floks!")).check(matches(isDisplayed()));

above code checked that screen has some textview having text Hello Floks!



Tutorial 2

Now that we have successed in finding view and performing checks we will move to step 2 which is perform events like typing and clicking. to click

    onView(withText("Login")).perform(click());


Tutorial 3

Merge click and checks in one

    onView(withId(R.id.btnLoginButton)).perform(click());
    onView(withId(R.id.edUsername)).check(matches(hasErrorText(resources.getString(R.string.msg_enter_valid_email))));


Your browser does not support HTML5 video.

Tutorial 4

open activity with data in bundle as it's important to pass data with activity

you want to check activity with custom data so before writing test if

    @RunWith(AndroidJUnit4.class)
    public class PassDataInActivityTest {
    
        @Rule
        public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<LoginActivity>(LoginActivity.class, true) {
            @Override
            protected Intent getActivityIntent() {
                Log.d(PassDataInActivityTest.class.getCanonicalName(), "getActivityIntent() called");
                Context targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
                Intent intent = new Intent(targetContext, LoginActivity.class);
                intent.putExtra("testingcheck", true);
                return intent;
            }
        };
    
    
        @Before
        public void initThingsHere() {
            //do stuff like database or preference or image copying here
        }
    
        @Test
        public void checkBlankEmailError() {
            //to check view on screen
            Bundle bundle = mActivityTestRule.getActivity().getIntent().getExtras();
            assertThat(bundle.getBoolean("testingcheck"), is(true));
            System.out.println("testingcheck:" + bundle.getBoolean("testingcheck"));
        }
    }

Tutorial 5

Responding to external intents like gallery picks It's hard to control external apps as with device applications can have different views so it's not steady like your UI. in this condition what you can do is develop dependency injected code where you can mock the intents results or you can give result of intents in testing. We are trying to archive this:

Your browser does not support HTML5 video.

Let's check without DI(Dependency Injection)

For this you need to have espresso intents dependency in build.gradle file

    androidTestCompile ('com.android.support.test.espresso:espresso-intents:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

excludes are important to exclude support libraries inside the espresso and use libs what you have included.

Now after dependency added we can move on to the main course which is to mock the intent results.

2 things to keep in mind is intending and intended

  1. Intending It is used for specifying Espresso that when unit test wants to open this type of intent please respond with intended result which i'm giving you to give.
2. Intended It is used to check if the event intended to open some activity or package? we can check that thing by this.
    Intent resultData = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    resultData.setData(Uri.parse(("content://media/external/images/media/162")));
    Matcher<Intent> MediaPickIntent = allOf(hasAction(Intent.ACTION_PICK), hasData(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
    Intents.init();
    intending(MediaPickIntent).respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData));

In above example we have action pick event matcher which gives espresso hint that i'm finding this intent and by initlizing the intent we are starting intent checks for every intents. while intending tells that when I intend to do respond with the intent i'm giving. Output:

Tutorial 6

Espresso works like charm for views with view hierarchy but it's difficult to find if view is not bound by viewgroup like google map.

It's hard to find marker in map as it's part of google map but not actual viewgroup so to perform the click event on google map marker what we can do here is Use UiAutomator.

UiAutomator is a library which uses accessiblity nodes to determine the views and performs assertions or actions upon that.

add UiAutomator in build.gradle


    androidTestCompile("com.android.support.test.uiautomator:uiautomator-v18:2.1.1", {
        exclude group: "com.android.support", module: "support-annotations"
    })

After adding in build.gradle your ready to go We will create map activity for testing this feature. now to use UiAutomator we need to start with finding UIDevice.

    UiDevice mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

and to find the marker we need to find marker view or in UiAutomator world it is UiSelector.

    UiObject marker = mDevice.findObject(new UiSelector().descriptionContains("Marker in Sydney"));

in above we are finding the view or object which has "Marker in sydney" as their description. and our marker had one. once we found the object we can perform click operation.

this is easy to find marker as it is bound to node but info window has been drawn to canvas so it can not be clicked and i had used a trick to click on info window. basically info window is drawn above marker icon and so i already got marker object so i had taken marker bounds and performed click on it.

        try {
            marker.click();
            marker.clickTopLeft();
            Rect rects = marker.getBounds();
            mDevice.click(rects.centerX(), rects.top - 30);
        } catch (UiObjectNotFoundException e) {
            e.printStackTrace();
        }

If you do like the Tutorials please rate this repo and do share your own testing class or methodology. output:

Your browser does not support HTML5 video.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].