Showing posts with label Espresso. Show all posts
Showing posts with label Espresso. Show all posts

Monday 10 October 2016

How to Test AutoComplete Text Box with Espresso

This is the most common test scenario now a days because many apps are using autocomplete textbox / autofill textbox. If you have not yet come across this then you can check out your google map application when you start typing inside location fill then the drop-down list of matching results are displayed and you can select any one from the list to continue.This post is about handing test cases where you need to select a result from autocomplete textbox.

Let us see the below example of google map and let us write Espresso Test Case to handle Autocomplete Textbox value selection.

AutoComplete Textbox Test Automation
AutoComplete Textbox Test Automation

Test Scenario -

1. Type the location name.
2. Check that list of matching results are displayed.
3. Click on any one of the matching results.

Test Case -

1. In the below sample test case we are using Junit Testing Framework.
2. We are defning the main activity of the application by using @Rule Annotation.
3. We are using inRoot() and decor View to select a window inside a Main activity window.
4. First we are typing "Ban" in the location field and then we are checking the first two suggestions are displayed or not.
5. Then we are clicking on the Top suggestion.


@RunWith(AndroidJUnit4.class)
@LargeTest
public class MultiWindowTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
            MainActivity.class);

    private MainActivity mActivity = null;

    @Before
    public void setActivity() {
        mActivity = mActivityRule.getActivity();
    }

    @Test
    public void testAutoCompleteTextView() {
        // Type "ban" to trigger two suggestions.
        onView(withId(R.id.auto_complete_text_view))
                .perform(typeText("ban"), closeSoftKeyboard());

        // Check that both suggestions are displayed.
        onView(withText("Bangalore"))
                .inRoot(withDecorView(not(is(mActivity.getWindow().getDecorView()))))
                .check(matches(isDisplayed()));
        onView(withText("bangalore central mall"))
                .inRoot(withDecorView(not(is(mActivity.getWindow().getDecorView()))))
                .check(matches(isDisplayed()));
    }

        // Tap on a suggestion.
        onView(withText("Bangalore"))
                .inRoot(withDecorView(not(is(mActivity.getWindow().getDecorView()))))
                .perform(click());

        // By clicking on the auto complete term, the text should be filled in.
        onView(withId(R.id.auto_complete_text_view))
                .check(matches(withText("Bangalore")));
    }

    

}

I hope this post helps you to resolve your autocomplete textbox test issue. If you find it useful then please share with your friends and give me feedback or suggestions in the comment section given below.

Thursday 29 September 2016

Record Test Cases using Espresso Test Recorder



Hi everyone it gives me immense pleasure to share with all that Android Studio 2.2 has been launched and as Android App Tester there is something very useful has been launched for us that is Espresso Test Recorder. In our Espresso Tutorials we have seen how to code and run Espresso test cases plus we have studied writing test cases for WebViews and Intents and much more. 

In this post I want to share with you about newly launched Android's Espresso Test Recorder and how we can us it effectively to record and run our test cases. If you are a Manual Tester and not comfortable then you must learn this as it is very simple and quick to learn feature of Espresso. If you are Automation Tester and already using Espresso should must try it out it will reduce you work load and helps you in faster test case development.

Video Tutorial is Also Available - 

 

What is Espresso Test Recorder ?

Espresso is Android's Instrumentation Test Framework which allows developers and testers to write UI test cases to test functionality of the app. Espresso Test Recorder is new feature introduced in Android Studio 2.2 which allows user to Manually perform steps in an device and add assertions to record test cases. 

Pros of Espresso Test Recorder -
1. Allow Us to create effective UI based Test Cases with user interactions.
2.We can capture assertions and interactions without accessing app's structure directly which increases execution speed and optimizes test case.
3.It saves lot of time to search for locators and then writing test cases.
4. It supports multiple assertions making more reliable test cases.
Cons of Espresso Test Recorder -
1. Currently does not Support Recording of WebViews interactions.
2.  Once We complete Recording once for next time Recording it launches the app there is no API to control such behavior.
3. Cannot record Assertions for Toast Messages

Step by Step Recording first Espresso Test Case -

Pre-requisite
1. Android Studio 2.2
2. Java 8
3. Environmental variable Set up for JAVA_HOME and Android_HOME

Mobile Device Settings
1. Go to Phone's Settings
2. Developers option
3. Turn off Windows Animator Scale, Transition Animator Scale & Animation Duration Scale.



Recording UI Interactions
1. Launch Android Studio 
2. Click on Start New Android Studio Project
3. Give Application Name as EspressoTestRecorder
4. Click on Next


5. Click on Next


6. Select Blank Activity and click on Next


7. Your Android Project will be opened
8. Go to Run -> Record Espresso Test 


9. Select a Device and click on OK
10. Check your device it will say "Waiting for Debugger" after installing the application when the window closes (Do not click on Force Close) start performing Tap and Type Events on the Mobile Application.


Record Assertions
1. Click on Add Assertions
2. It will take Screenshot of the Device and display it on the screen.


3. In Edit Assertions Section you can select what type of assertions you want to add.


4. Click on Save Assertions.
5. Then Click on Complete Recording to save your test case

Save The Test Case
1. A popup will appear with Name of the Activity on which test is recorded you can edit the name
2. Click on Save


3. The test case will be saved in Android ->app->package name with (androidTest)->TestClassName

Run the Test Case
1. Once you locate the Test Class right click on the name
2. Click on Run.




Isn't it simple and interesting to learn. Write your queries and questions in the comment section and spread the word about New Espresso Test Recorder to Ease work load. Happy Testing :-)



Friday 11 March 2016

How to Match Child View of a View in Espresso



Hi all clicking on child view of a view is mostly used in case ListView whenever we want to click on the perticular column or part inside the row. We have already seen a ListView Example in the previous post where we had around 50 rows containing text and toggle button. We will just use the same example and learn how to match a child view inside a view in espresso.

App Under Test -
Consider that we have  a app with ListView and the ListView is divided into two columns the first column is text and second column is number of characters in the text.The list view has unique text in first column but second column has repetitive entries.

Test Case Scenario-
1. check one row in list where with Text "Dog" and "3".
2. click on 3 where 3 has occurred multiple times for different rows but we want to click on "3" within the row with text "Dog.

Test Case -
As you all are already familiar with espresso. I am just giving you the below simple test case to achieve our test case goal.


@Test
public void testChildView()
{
onData(withItemContent("Dog"))
  .onChildView(withId(R.id.no_char))
  .perform(click());
}

I hope this post helps you find your code coverage for your test suit :)
Please Share your feedback in comments section below and follow QA Automated to get latest post update.Happy Testing :-)

Espresso Resource Idling Example


The advantage of Espresso is its ability to seamlessly synchronize all test operations with the application being tested. By default, Espresso waits for UI events in the current message queue to be handled and for default instances of AsyncTask to complete before it moves on to the next test operation.

However, there are instances where applications perform background operations, such as communicating with web services, using non-standard means, such as direct creation and management of threads.

In such cases, you have to use idling resources to inform Espresso of the app’s long-running operations.

1. Modify  java class MainActivity.java inside app->src->Main.
2. Add method getIdlingResource() as shown in below example.

package com.example.android.testing.espresso.IdlingResourceSample;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.test.espresso.IdlingResource;
import android.support.test.espresso.idling.CountingIdlingResource;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import com.example.android.testing.espresso.IdlingResourceSample.IdlingResource.SimpleIdlingResource;

/**
 * Gets a text String from the user and displays it back after a while.
 */
public class MainActivity extends Activity implements View.OnClickListener,
        MessageDelayer.DelayerCallback {

    // The TextView used to display the message inside the Activity.
    private TextView mTextView;

    // The EditText where the user types the message.
    private EditText mEditText;

    // The Idling Resource which will be null in production.
    @Nullable private SimpleIdlingResource mIdlingResource;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Set the listeners for the buttons.
        findViewById(R.id.changeTextBt).setOnClickListener(this);

        mTextView = (TextView) findViewById(R.id.textToBeChanged);
        mEditText = (EditText) findViewById(R.id.editTextUserInput);
    }

    @Override
    public void onClick(View view) {
        // Get the text from the EditText view.
        final String text = mEditText.getText().toString();

        if (view.getId() == R.id.changeTextBt) {
            // Set a temporary text.
            mTextView.setText(R.string.waiting_msg);
            // Submit the message to the delayer.
            MessageDelayer.processMessage(text, this, mIdlingResource);
        }
    }

    @Override
    public void onDone(String text) {
        // The delayer notifies the activity via a callback.
        mTextView.setText(text);
    }

    /**
     * Only called from test, creates and returns a new {@link SimpleIdlingResource}.
     */
    @VisibleForTesting
    @NonNull
    public IdlingResource getIdlingResource() {
        if (mIdlingResource == null) {
            mIdlingResource = new SimpleIdlingResource();
        }
        return mIdlingResource;
    }
}

3. Register one or more of your idling resources with Espresso by calling Espresso.registerIdlingResource() in the test setup and then in teardown we should unregister using code
 Espresso.unregisterIdlingResources(mIdlingResource);



/*
 * Copyright 2016, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.testing.espresso.IdlingResourceSample;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

import android.support.test.espresso.Espresso;
import android.support.test.espresso.IdlingResource;
import android.support.test.filters.LargeTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * Same as Espresso's BasicSample, but with an Idling Resource to help with synchronization.
 */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class ChangeTextBehaviorTest {

    private static final String STRING_TO_BE_TYPED = "Espresso";

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
            MainActivity.class);

    private IdlingResource mIdlingResource;

    @Before
    public void registerIdlingResource() {
        mIdlingResource = mActivityRule.getActivity().getIdlingResource();
        // To prove that the test fails, omit this call:
        Espresso.registerIdlingResources(mIdlingResource);
    }

    @Test
    public void changeText_sameActivity() {
        // Type text and then press the button.
        onView(withId(R.id.editTextUserInput))
                .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard());
        onView(withId(R.id.changeTextBt)).perform(click());

        // Check that the text was changed.
        onView(withId(R.id.textToBeChanged)).check(matches(withText(STRING_TO_BE_TYPED)));
    }

    @After
    public void unregisterIdlingResource() {
        if (mIdlingResource != null) {
            Espresso.unregisterIdlingResources(mIdlingResource);
        }
    }
}

I hope this post helps you find your code coverage for your test suit :)
Please Share your feedback in comments section below and follow QA Automated to get latest post update.Happy Testing :-)
 

Sunday 6 March 2016

How to Find Code Coverage with Jacoco and Gradle?




Finding code coverage is very important for testing because it allows you to measure your testing efforts. If you have a test suit prepared for your application but you are not sure whether the test suit is covers how much percentage of code then fining the code coverage will be good practice. Once you get the coverage report you will be know exactly what part of code is not covered in your test case and then you can add test cases to cover the code.

Jacoco is java code coverage tool which allows you to calculate code coverage for your unit tests and functional tests. Jacoco can be used with Ant , maven and gradle. Today I will show you step by step integration of Jacoco with Gradle for Espresso test suit.

I have done this setup for Simple Hello world project to give idea of how Jacoco works and give you proper code coverage report.

Video Tutorial -



1. Create a android project as shown in my previous post.
2. Create a java class inside src->main->androidTest and write your Espresso test case in the class.
3. Create a new class named AndroidJococoTestRunner in src -> main ->androidTest and copy below code inside the class.


import android.os.Bundle;
import android.support.test.runner.AndroidJUnitRunner;
import android.util.Log;

import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;


public class AndroidJacocoTestRunner extends AndroidJUnitRunner {

    private static final Charset UTF8 = Charset.forName("UTF-8");

    static {
//    System.setProperty("jacoco-agent.destfile", "/sdcard/coverage.ec");
    }

    @Override
    public void finish(int resultCode, Bundle results) {
        try {
            Class rt = Class.forName("org.jacoco.agent.rt.RT");
            Method getAgent = rt.getMethod("getAgent");
            Method dump = getAgent.getReturnType().getMethod("dump", boolean.class);
            Object agent = getAgent.invoke(null);
            dump.invoke(agent, false);
        } catch (Throwable e) {
            final String trace = Log.getStackTraceString(e);

            try {
                System.out.write(trace.getBytes(UTF8));
            } catch (IOException ignored) {
            }
        }

        super.finish(resultCode, results);
    }
}

4. Open app-> build.gradle and  copy below code in defaultConfig.

testInstrumentationRunner "com.example.anuja.myapplication1.AndroidJacocoTestRunner"

also add code given below in buidTypes.


debug {
            testCoverageEnabled = true
        }

5. Then click on Gradle on right side of Android studio -> click on refresh -> other -> right click on createDebugAndroidTestCoverageReport -> click on run

Code Coverage for Android Application
Code Coverage for Android Application

6. This action will run all the test cases inside src->main->androidTest and give the report in app->build-> reports ->coverage -> debug.
7. open index.html file in the browser to check the code coverage report as shown in below screenshot.

Jacoco Code Coverage

Detailed Code Coverage for Android Application
Detailed Code Coverage for Android Application

Get Code Coverage from Android Studio
Get Code Coverage from Android Studio

I hope this post helps you find your code coverage for your test suit :)
Please Share your feedback in comments section below and follow QA Automated to get latest post update.Happy Testing :-)

Thursday 25 February 2016

Testing Camera Activity using Intent



We have seen how to use intent for inter app testing and so far we have seen how to test Dialer and Browser activity. In the post I will give you simple example for testing Camera Activity. There are many apps which uses camera to capture image and share it. Testing this scenario is now very easy with Espresso Intent.

App Under Testing -
I have created a simple app as per be below screenshot when you click on the camera it launches camera activity then you can capture the image.

Test Camera Activity with Espresso

Test Case Scenario -
1. Launch the app.
2. Take  a photo 
3. check whether the photo is taken and displayed in Image View box.

Test Case Code Description -
1. We need to create a Custom Matcher to check the image view contains image. So create a new Java Class in androidTest folder with name ImageViewMatcher and copy the code given below.
2. In our Test Case class we will stub the camera activity using the app launcher icon image so that we can cross check it. So the method createImageCaptureStub() we put the app drawable image in the bundle and create Intent with the bundle and then pass the same intent as ActivityResult.
3.Before Test case execute we stub the intent so when the app launches camera the drawable image will be passed as part of intend stub.
4. Then In our test case we click on camera button which calls intend and we get the drawable image which we stubbed earlier and we can assert it in our test case.
Custom Matcher -

package com.example.anuja.cameraintentsample;

/**
 * Created by Anuja on 24-02-2016.
 */
import android.support.test.espresso.matcher.BoundedMatcher;
import android.view.View;
import android.widget.ImageView;

import org.hamcrest.Description;
public class ImageViewMatcher {

    public static BoundedMatcher<View, ImageView> hasDrawable() {
        return new BoundedMatcher<View, ImageView>(ImageView.class) {
            @Override
            public void describeTo(Description description) {
                description.appendText("has drawable");
            }

            @Override
            public boolean matchesSafely(ImageView imageView) {
                return imageView.getDrawable() != null;
            }
        };
    }
}

Test Case -


package com.example.anuja.cameraintentsample;

import android.app.Activity;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.test.espresso.intent.rule.IntentsTestRule;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static android.app.Instrumentation.ActivityResult;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.intent.Intents.intending;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction;
import static android.support.test.espresso.matcher.ViewMatchers.withId;

import static com.example.anuja.cameraintentsample.ImageViewMatcher.hasDrawable;
import static org.hamcrest.Matchers.not;

/**
 * Created by Anuja on 24-02-2016.
 */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class CameraIntentTest {

        @Rule
        public IntentsTestRule<ImageViewerActivity> mIntentsRule = new IntentsTestRule<>(
                ImageViewerActivity.class);

        @Before
        public void stubCameraIntent() {
            ActivityResult result = createImageCaptureStub();

            // Stub the Intent.
            intending(hasAction(MediaStore.ACTION_IMAGE_CAPTURE)).respondWith(result);
        }

        @Test
        public void testTakePhoto() {
            // Check that the ImageView doesn't have a drawable applied.
            onView(withId(R.id.imageView)).check(matches(not(hasDrawable())));

            // Click on the button that will trigger the stubbed intent.
            onView(withId(R.id.button_take_photo)).perform(click());

            // With no user interaction, the ImageView will have a drawable.
            onView(withId(R.id.imageView)).check(matches(hasDrawable()));
        }

        private ActivityResult createImageCaptureStub() {
            // Put the drawable in a bundle.
            Bundle bundle = new Bundle();
            bundle.putParcelable(ImageViewerActivity.KEY_IMAGE_DATA, BitmapFactory.decodeResource(
                    mIntentsRule.getActivity().getResources(), R.drawable.ic_launcher));

            // Create the Intent that will include the bundle.
            Intent resultData = new Intent();
            resultData.putExtras(bundle);

            // Create the ActivityResult with the Intent.
            return new ActivityResult(Activity.RESULT_OK, resultData);
        }
    }

I hope this post helps you find your code coverage for your test suit :)
Please Share your feedback in comments section below and follow QA Automated to get latest post update.Happy Testing :-)

Wednesday 24 February 2016

Espresso Intent to Test Launch of Browser Activity



In my previous post we have seen how to use Espresso Intent to test dialer activity.We know sometimes our app launches activities which are outside our app liker dialer, camera or browser etc. In this post we will learn how to test browser activity using intent.

App Under Test -
Consider you have an app with a button "Click Here". Once you click it launches chrome browser and opens url www.google.com

Test Case Scenario -
Our test case is to click on the button and check the browser activity is launched and opens the right url.

Test Case-


import android.content.Intent;
import android.support.test.espresso.intent.rule.IntentsTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import org.junit.FixMethodOrder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.intent.Intents.intended;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasData;
import static android.support.test.espresso.intent.matcher.IntentMatchers.toPackage;
import static android.support.test.espresso.intent.matcher.UriMatchers.hasHost;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.equalTo;
@RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@LargeTest
public class BrowserIntentTest {

    private static final String PACKAGE_NAME="com.android.chrome";
    @Rule
    public IntentsTestRule<MainActivity> mActivityRule = new IntentsTestRule<>(
            MainActivity.class);

    @Test
    public void test1()throws Exception
    {
            Thread.sleep(3000);
            onView(withId("Click Here")).perform(click());
            Thread.sleep(1000);
            intended(allOf(hasData(hasHost(equalTo("www.google.com"))),
                    hasAction(Intent.ACTION_VIEW),
                    toPackage(PACKAGE_NAME)));

    }
}

I hope this post helps you find your code coverage for your test suit :)
Please Share your feedback in comments section below and follow QA Automated to get latest post update.Happy Testing :-)