I am automating accessibility testing with espresso, but it reports that androidx.test.espresso.contrib.AccessibilityChecks as deprecated.
I surfed the internet and found the non-deprecated AccessibilityChecks class which should be used instead. But would be appreciate if anyone can provide the non-deprecated gradle dependency
This is my testing class
import androidx.test.espresso.contrib.AccessibilityChecks;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
#RunWith(AndroidJUnit4.class)
public class AccessibilityChecksTest {
#BeforeClass
public static void turnOnAccessibility() {
AccessibilityChecks.enable();
}
}
Dependency
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.2.0'
The below is the right dependency for the non-deprecated AccessibilityChecks I found it here along with many other Espresso testing APIs
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.2.0'
Related
I have created a basic Espresso test class that looks like the following:
#LargeTest
#RunWith(AndroidJUnit4.class)
class ConfigurationsActivityTest {
#Rule
public ActivityTestRule<ConfigurationsActivity> mConfigsTestRule =
new ActivityTestRule<>(ConfigurationsActivity.class);
#Test
public void isInView() {
onView(withId(R.id.config_recyclerview)).check(matches(isDisplayed()));
}
}
The problem is, when I try to run this test I get the following error message:
Class not found: "com.name.app.activities.ConfigurationsTest"
I have followed this answer: Android Espresso test: Class not found: ...Empty test suite and taken a look at my run configurations. It seems that my test is being run as an unit test even though it's an instrumented one.
Another problem arises when I delete the unit test configurations, that were created when I tried to run my instrumented test, and try to create an instrumented test run configuration for my test class: the wizard does not allow me to select my instrumented test class containing the test above to be the test class. The problem is visualised here.
I have also taken a look at this answer: TestCase class not found by Android Studio and confirmed that my directory structure in main/java and androidTest/java are the same.
In addition, when I follow what was done in this question: Android Espresso: "No test were found" , "Process crashed" and create a run configuration for the whole package that contains my test class and run that, I get:
java.lang.RuntimeException: Delegate runner 'androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner' for AndroidJUnit4 could not be loaded.
I am suspecting that it's something to do with my imports or dependencies. Here are both:
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.preference:preference:1.1.1'
testImplementation 'junit:junit:4.13'
testImplementation "org.mockito:mockito-core:3.3.1"
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.2.0'
}
Any help appreciated. Thanks!
The rule should be like this
#Rule
public ActivityTestRule<ConfigurationsActivity> mConfigsTestRule =
new ActivityTestRule<>(ConfigurationsActivity.class);
The test class has to be public. That's why it wasn't working.
I am writing an Espresso test to test that my App Links are handled properly by my app. I've setup Android Studio and created a test that passes, but the problem is that the test suite hangs. I have created a class, LinkDispatcherActivity, that is responsible for parsing the incoming links and dispatching their data to the appropriate activity. The tests are setup to use the ActivityTestRule to launch LinkDispatcherActivity and give it an intent with the URL to be tested. The tests are running and passing, so I assume I've set everything up correctly (a challenge all on its own 😜).
I have tried using the new ActivityScenarioRule but can't figure out how to pass an intent to it.
Here's my test class:
import android.content.Intent
import android.net.Uri
import android.widget.TextView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import gov.nih.nlm.wiser.R
import gov.nih.nlm.wiser.link.WiserLinkDispatcherActivity
import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.instanceOf
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
#RunWith(AndroidJUnit4::class)
#LargeTest
class SubstanceLinkTest {
#get:Rule
val activityTestRule: ActivityTestRule<LinkDispatcherActivity>
= ActivityTestRule(LinkDispatcherActivity::class.java, false, false) // initialTouchMode: false, launchActivity: false
#Test
fun shouldOpenLinkDispatcherActivity() {
val i = Intent().apply {
data = Uri.parse("https://mydomain/action?data=338")
}
activityTestRule.launchActivity(i)
onView(allOf(instanceOf(TextView::class.java), withParent(withId(R.id.action_bar))))
.check(matches(withText("My Title"))) // Passes!!
}
}
Here's my added dependencies in by build.gradle:
dependencies {
// Core library
implementation 'androidx.test:core:1.2.0'
// AndroidJUnitRunner and JUnit Rules
implementation 'androidx.test:runner:1.2.0'
implementation 'androidx.test:rules:1.2.0'
// Assertions
implementation 'androidx.test.ext:junit:1.1.1'
implementation 'androidx.test.ext:truth:1.2.0'
implementation 'com.google.truth:truth:0.42'
// Espresso dependencies
implementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.android.support:multidex-instrumentation:1.0.3'
}
Finally, here is what Android Studio shows in it's Run panel:
Cheers!
Edit:
Forgot to add that I'm getting this error in Logcat:
2019-06-21 12:02:24.326 6311-6035/? E/cckz: *~*~*~ Channel {0} was not shutdown properly!!! ~*~*~*
Make sure to call shutdown()/shutdownNow() and wait until awaitTermination() returns true.
java.lang.RuntimeException: ManagedChannel allocation site
at cclc.<init>(:com.google.android.gms#17455040#17.4.55 (100700-248795830):1)
at cckz.<init>(:com.google.android.gms#17455040#17.4.55 (100700-248795830):2)
at ccdo.b(:com.google.android.gms#17455040#17.4.55 (100700-248795830):14)
at rzc.a(:com.google.android.gms#17455040#17.4.55 (100700-248795830):43)
at rzc.a(:com.google.android.gms#17455040#17.4.55 (100700-248795830):58)
at atbl.a(:com.google.android.gms#17455040#17.4.55 (100700-248795830):9)
at atbl.a(:com.google.android.gms#17455040#17.4.55 (100700-248795830):26)
at qbi.run(:com.google.android.gms#17455040#17.4.55 (100700-248795830):1)
at sgs.b(:com.google.android.gms#17455040#17.4.55 (100700-248795830):37)
at sgs.run(:com.google.android.gms#17455040#17.4.55 (100700-248795830):21)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at smq.run(Unknown Source:7)
at java.lang.Thread.run(Thread.java:764)
UPDATE: The test completes properly when run on a physical device. Still not sure what's causing the emulator to hang.
I would suggest using an #After annotation with a method called something like 'tearDown'. You could do final assertions here and clean up any databases or processes that need to end and possibly call publisher.shutdown(); and publisher.awaitTermination(1, TimeUnit.MINUTES) Hope this can help somewhat.
Check this thread out too:
[https://github.com/googleapis/google-cloud-java/issues/3648]
I am trying to run src/androidTest which is Instrument test in my Android Project which uses AndroidX libraries, but I am getting No tests were found error and Empty test suite log.
I have checked all samples and documents which are using AndroidX libraries are doing same.
I have tried to setup Edit Configurations based on following link https://stackoverflow.com/a/53715513/1826656 But still no luck.
Am I doing anything wrong? or missing any steps?
Please check this image for Test Run log
MainActivityTest.java Code:
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
#RunWith(AndroidJUnit4.class)
#LargeTest
public class MainActivityTest {
#Rule
ActivityTestRule mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);
#Test
public void checkViewsVisibility() {
// verify the visibility of recycler view on screen
onView(withId(R.id.record_list_rv)).check(matches(isDisplayed()));
// verify the visibility of progressbar on screen
onView(withId(R.id.progressBar)).check(matches(isDisplayed()));
// verify the visibility of no data TextView on screen By default it should be GONE
onView(withId(R.id.no_data_tv)).check(matches(isDisplayed()));
onView(withId(R.id.no_data_tv)).check(matches(withText("No Data")));
onView(withId(R.id.no_data_tv)).perform(typeText("No Data"));
}
}
Gradle file dependencies:
android {
defaultConfig {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunne"
}
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
}
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestUtil 'androidx.test:orchestrator:1.1.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test:rules:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.1'
}
You have a typo in your defaultConfig. It should probably be:
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
In my case, I also struggled to run UI tests. Checking (and trying) most of the things in similar topics gave no results for me. Finally I ran my instrumentation tests via gradle command:
gradlew connectedProdDebugAndroidTest
or (if you want to run single test, or tests in a single class)
gradlew connectedProdDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class={package.class}#{methodName}
After running tests by command, somehow, it became possible to run them by dedicated button.
For me after ensuring that all dependencies were available, changing the targetSdk from 30 to lower version solved my problem.
I have read Room Persistence Library. I also clone android-architecture-components then I try to add Mirgration test. However, I cannot import
import android.arch.persistence.room.testing.MigrationTestHelper;
I also use latest lib version which is.
android.arch.core:core-testing:1.0.0-alpha3
Here is the code for MigrationTest
import android.arch.persistence.db.SupportSQLiteDatabase;
import android.arch.persistence.db.framework.FrameworkSQLiteOpenHelperFactory;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
import android.arch.persistence.room.testing.MigrationTestHelper;
#RunWith(AndroidJUnit4.class)
public class MigrationTest {
private static final String TEST_DB = "migration-test";
#Rule
public MigrationTestHelper helper;
public MigrationTest() {
helper = new MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
MigrationDb.class.getCanonicalName(),
new FrameworkSQLiteOpenHelperFactory());
}
#Test
public void migrate1To2() throws IOException {
SupportSQLiteDatabase db = helper.createDatabase(TEST_DB, 1);
// db has schema version 1. insert some data using SQL queries.
// You cannot use DAO classes because they expect the latest schema.
//db.execSQL(...);
// Prepare for the next version.
db.close();
// Re-open the database with version 2 and provide
// MIGRATION_1_2 as the migration process.
db = helper.runMigrationsAndValidate(TEST_DB, 2, true, MIGRATION_1_2);
// MigrationTestHelper automatically verifies the schema changes,
// but you need to validate that the data was migrated properly.
}
}
Since the code use AndroidJUnit4 then Just use androidTestCompile instead
androidTestCompile "android.arch.persistence.room:testing:$arch_version"
Official doc use dependency for local unit test. However, the official sample use Android runner...
https://developer.android.com/topic/libraries/architecture/adding-components.html
You are using Android runner (AndroidJUnit4.class), and your test is actualy placed at src/androidTest. It means you are using Instrumented Tests which dependencies should be declared:
// Instrumented Unit Test or UI Test
androidTestComplile ....
Meanwhile, if you are writing Local Unit Test, testing codes is placed at src/test, you can declare the dependencies:
// Local Unit Test
testCompile ....
In Google documentation, they just give an example for local unit tests. No mistake here.
The main issue is google provide documentation for JUnit local tests cases and not instrumental (which means tests on a real device or emulator).
As a result i saw many example with
testImplementation "androidx.room:room-testing:$room_version"
This makes not sense cause you can only test your room db with instrumental test cases. You will get an error otherwise. So you have to use androidTestImplementation and not testImplementation in your gradle file.
def room_version = "2.2.5"
def test_version = "1.2.0"
androidTestImplementation "androidx.test:runner:$test_version"
androidTestImplementation "androidx.test:rules:$test_version"
androidTestImplementation "androidx.room:room-testing:$room_version"
The answers of Quang and UmAnusorn are correct but a little outdated. For those who like to know:
Use androidTestImplementation instead of androidTestCompile
AndroidX: androidx.room:room-testing
Complete implementation in gradle:
androidTestImplementation "androidx.room:room-testing:$room_version"
(2.2.4 is the latest version at the moment of writing)
These 3 annotations #SmallTest, #MediumTest, and #LargeTest has been recently deprecated on Android.
But I couldn't find any documentation which explains the motivation or proposes a new annotation set.
So, is there any way right now for declaring the scope of a test?
Previously these annotations were in the android.test.suitebuilder.annotation package. As of API 24, they were moved to the android.support.test.filters package (documented here for #MediumTest. #SmallTest and #LargeTest are the same).
To use the new versions:
Be sure you're using import android.support.test.filters.<size>Test at the top of your test file.
Ensure your test runner and rules versions are using at least version 0.5 in your build.gradle file:
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
Update for androidx
dependency declared in app's build.gradle:
androidTestImplementation 'androidx.test:runner:1.2.0'
and then imports looks like:
import androidx.test.filters.SmallTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.LargeTest;
import androidx.test.filters.FlakyTest;
Original answer:
Like Chris said, they are moved in the Testing Support Library as of API 24 (apps targeting this api onwards)
In order to use the annotations for JUnit/Unit tests you have to add:
testImplementation 'com.android.support.test:runner:0.5'
in your build.gradle file
and for UI/instrumentation tests add:
androidTestImplementation 'com.android.support.test:runner:0.5'
Then in your test class add one/more of the following imports:
import android.support.test.filters.SmallTest;
import android.support.test.filters.MediumTest;
import android.support.test.filters.LargeTest;
import android.support.test.filters.FlakyTest;
Update for androidx
Step 1: In your app's build.gradle file, inside dependencies add:
testImplementation 'androidx.test:runner:1.1.1'
testImplementation 'androidx.test:rules:1.1.1'
Step 2: In your test class, add the needed imports
import androidx.test.filters.LargeTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
Step 1: In your app's build.gradle file, inside dependencies add:
testImplementation 'com.android.support.test:runner:1.0.2'
Please note that: You have to add this line as testImplementation, not androidTestImplementation
Step 2: In your test class, add one/more of the following imports (Based on your need)
import android.support.test.filters.SmallTest;
import android.support.test.filters.MediumTest;
import android.support.test.filters.LargeTest;