AndroidX Espresso Test: No tests were found and Empty test suite - android

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.

Related

No instrumentation registered! Must run under a registering instrumentation. AndroidJUnit4 test case [duplicate]

I'm trying to run a local unit test that depends on the context, and was following this guide: https://developer.android.com/training/testing/unit-testing/local-unit-tests#kotlin and I set up my project like this (following this link : https://developer.android.com/training/testing/set-up-project ):
build.gradle(app)
android {
compileSdkVersion 28
buildToolsVersion '27.0.3'
defaultConfig {
minSdkVersion 21
targetSdkVersion 27
versionCode 76
versionName "2.6.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
useLibrary 'android.test.runner'
useLibrary 'android.test.base'
useLibrary 'android.test.mock'
}
testOptions {
unitTests.returnDefaultValues = true
unitTests.all {
// All the usual Gradle options.
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen { false }
showStandardStreams = true
}
}
unitTests.includeAndroidResources = true
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion", {
exclude group: 'com.android.support', module: 'support-annotations'
})
// Espresso UI Testing dependencies
implementation "androidx.test.espresso:espresso-idling-resource:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
testImplementation 'androidx.test:core:1.0.0'
// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test:rules:1.1.0'
// Espresso Assertions
androidTestImplementation 'androidx.test.ext:junit:1.0.0'
androidTestImplementation 'androidx.test.ext:truth:1.0.0'
androidTestImplementation 'com.google.truth:truth:0.42'
implementation 'androidx.multidex:multidex:2.0.0'
}
My espresso_version is espressoVersion = '3.1.0'
My test that is located in module-name/src/test/java/ looks like this:
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.instacart.library.truetime.TrueTime
import edu.mira.aula.shared.extensions.android.trueDateNow
import edu.mira.aula.shared.network.ConnectivityHelper
import kotlinx.coroutines.experimental.runBlocking
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import java.util.*
import java.util.concurrent.CountDownLatch
class TimeExtensionsUnitTest {
private lateinit var instrumentationCtx: Context
#Before
fun setup() {
instrumentationCtx = ApplicationProvider.getApplicationContext<Context>()
}
#Test
fun testTrueTimeValueReturnsIfInitialized() {
if (ConnectivityHelper.isOnline(instrumentationCtx)) {
runBlocking {
val countDownLatch = CountDownLatch(1)
TrueTime.build()
.withSharedPreferencesCache(instrumentationCtx)
.withConnectionTimeout(10000)
.initialize()
countDownLatch.countDown()
try {
countDownLatch.await()
val dateFromTrueTime = trueDateNow()
val normalDate = Date()
Assert.assertNotEquals(dateFromTrueTime, normalDate)
} catch (e: InterruptedException) {
}
}
}
}
Everytime I run it, it gives me:
java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
at androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:45)
at androidx.test.core.app.ApplicationProvider.getApplicationContext(ApplicationProvider.java:41)
If I run it as a Instrumental Test(changing the package) it runs without errors.
But I thought that this guide was exactly to be able to run unit test using Android Framework classes such as Context.
I even tried run that class UnitTestSample but the same error occurs.
I also removed all android.support dependencies from my project
Any ideas on how to solve it?
Update
You should no longer encounter this error if youre using the latest gradle version.
I also encountered this issue.
If you look at migrating to Robolectric 4.0 here, it suggest to add the following line in your gradle.properties.
android.enableUnitTestBinaryResources=true
The problem is that, if you add this you your gradle.properties, it will output this warning:
WARNING: The option setting
'android.enableUnitTestBinaryResources=true' is experimental and
unsupported.
Now, if you look at Robolectric releases here. You could see that this is a known issue where they state that
Android Gradle Plugin may report the following warning, which may be safely ignored: WARNING: The option setting 'android.enableUnitTestBinaryResources=true' is experimental and unsupported.. Android Gradle Plugin 3.4 will resolve this issue.
I believe unless you could update you gradle to 3.4. You won't be able to solve this issue.
What I did instead was to include Robolectric 4.0 as dependency.
testImplementation "org.robolectric:robolectric:4.0.2"
and annotate my test class with
#RunWith(RobolectricTestRunner::class)
This should make your test work.
Now when you run the test, you'll notice that Robolectric will log the following:
[Robolectric] NOTICE: legacy resources mode is deprecated; see
http://robolectric.org/migrating/#migrating-to-40
Ignore this for now but as soon as you could update your gradle, migrate to the new Robolectric testing.
I follow the official guide also met this issue, fix it with below steps.
Add testImplementation in app build.gradle
// Required -- JUnit 4 framework
testImplementation 'junit:junit:4.13.1'
testImplementation 'androidx.test:core-ktx:1.3.0'
testImplementation 'androidx.test.ext:junit-ktx:1.1.2'
// Robolectric environment
testImplementation 'org.robolectric:robolectric:4.4'
// Optional -- truth
testImplementation 'androidx.test.ext:truth:1.3.0'
testImplementation 'com.google.truth:truth:1.0'
// Optional -- Mockito framework
testImplementation 'org.mockito:mockito-core:3.3.3'
The official guide missed two testImplementations
testImplementation 'androidx.test.ext:junit-ktx:1.1.2'
testImplementation 'org.robolectric:robolectric:4.4'
Add testOptions block in app build.gradle
android {
// ...
testOptions {
unitTests.includeAndroidResources = true
}
}
Add #RunWith(AndroidJUnit4::class) to your test class
Example:
import android.content.Context
import android.os.Build.VERSION_CODES.Q
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
#RunWith(AndroidJUnit4::class)
#Config(sdk = [Q])
class UnitTestWithContextDemoTest {
private val context: Context = ApplicationProvider.getApplicationContext()
fun test_getPackageName() {
assertThat(context.packageName).contains("your_package_name")
}
}
NOTE
#Config(sdk = [Q]) is required when your targetSdkVersion greater than 29. Because robolectric NOT support targetSdkVersion greater than 29.
Spend hours on similar issue, and the problem wasn't in dependencies, rather in AndroidStudio itself Based on the answer:
IDE tries to run local unit tests instead of instrumented
.
Make sure it's run as instrumented test (red is local tests, green - instrumented):
After added instrumented test for the class it's run as expected under instrumented. How I done this? 2 ways I found:
1) Edit configuration (as on the last screenshot) and adding function manually
2) Under Project tap (top left corner) I selected Tests instead of android, found the test, right click - create test. After this step all new tests are run under instrumented tests
I had similar error and was struggling a lot to fix it. My problem was that I was mixing AndroidJUnit4, InstrumentationRegistry, ApplicationProvider and AndroidJUnitRunnerversions / packages. Make sure they all are of the same generation. These are the classes that made it all run for me:
androidx.test.runner.AndroidJUnitRunner
androidx.test.platform.app.InstrumentationRegistry
androidx.test.ext.junit.runners.AndroidJUnit4
androidx.test.core.app.ApplicationProvider
for these I needed the following in the dependencies part of my build.gradle
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
androidTestImplementation 'androidx.test:core:1.1.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation "com.android.support:support-annotations:27.1.1"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
And of course the correct
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
in my defaultConfig of the build.gradle
Next things are not mentioned on google test guide, but they are what I found:
androidx.test in case of unit tests is just an interface/api (I don't know what about instrumented tests) and it needs implementations, which is robolectric library.
That's why robolectric dependency is also required:
testImplementation "org.robolectric:robolectric:{version}"
#RunWith(AndroidJUnit4.class)
is required. To get nondeprecated class you need to add:
testImplementation "androidx.test.ext:junit:{version}". By the way this dependency has transitive junit4 dependensy.
Also you can faced with: Failed to create a Robolectric sandbox: Android SDK 29 requires Java 9 (have Java 8) in case you use java 8 and compileSdkVersion 29 or above. Here you can find how to deal with it.
Make sure to put your instrumentation tests (tests you run with a Runner) in androidTest and not just test
in my case I was using getApplicationContext() in a fragment from the test package, I just change it to getContext(). and this fixed my crash!
In my case, changing the test method name fixed the issue.
Most probably the Android Studio cached the methods with indexes that caused a problem.
[Note : To remember this ]
AndroidJUnit4.class | used to run testcases of intrumentation type inside source set called androidTest [which requires phone or emulator]
AndroidJUnit4ClassRunner | used to run testcases for local test inside source set called test folder. [ no phone /emulator required]
Exception or Improvement Case | Using Robo-electric and supported junit4 dependency, then AndroidJUnit4.class can be used inside test folder to test local test.
Use this dependency[try to add latest]
testImplementation "org.robolectric:robolectric:4.4"
Then in your test class, use #RunWith(AndroidJUnit4::class)
Example : #RunWith(AndroidJUnit4::class)
-------For Reference-----
#RunWith(AndroidJUnit4::class)
class TasksViewModelTest {
#Test
fun addNewTask_setsNewTaskEvent() {
// Given a fresh TasksViewModel
var tasksViewModel = TasksViewModel(ApplicationProvider.getApplicationContext())
// When adding a new task
tasksViewModel.addNewTask()
// Then the new task event is triggered
}
}
Looks like you forgot to annotate your TimeExtensionsUnitTest with #RunWith(AndroidJUnit4::class) re: https://github.com/android/android-test/issues/409. I can reproduce the error by commenting that out in my own tests.
That said, this is not the only way to get your error. I originally encountered it when I was updating some old Robolectric tests to use some AndroidX apis (http://robolectric.org/androidx_test/), including switching away from #RunWith(RobolectricTestRunner::class). In my case, I was trying to use a context in my #BeforeClass with ApplicationProvider.getApplicationContext<Context>(), which is wrong in AndroidX, even though it was ok using Roboletric's runner with appContext = RuntimeEnvironment.getApplication().applicationContextappContext. Fortunately I was able to move the logic into my #Before call to fix things without a significant hit.
More generally, I've noticed documentation out there isn't fully comprehensive all in one place explaining the migration from the very old android.support.test Android Testing Support Library and Roboletric dependencies to AndroidX, but here's some other notes:
If I want to run real instrumentation tests on an emulator/physical device, ensure that the tests are under src/androidTest. This also means I need to change in my build.gradle file the dependencies on androidx.test libraries from testImplementation => androidTestImplementation, and also explicitly set a testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" in the defaultConfig section.
https://developer.android.com/training/testing/local-tests
https://developer.android.com/training/testing/instrumented-tests
If I'm happy with using Robolectric to run those tests as local, I can keep them under src/test, declare the dependencies using testImplementation, and don't need the testInstrumentationRunner. It's nice that I don't have to change the code to do this since I'm using the AndroidX Test APIs, which Roboletric is compatible with as of v4.0.
I got the same problem and here is how i fixed it:
move my test class to the "androidTest" package
annotate the test class with #RunWith(AndroidJUnit4.class)
Hope this can help
Simply check your import section:
import androidx.test.runner.AndroidJUnit4;

AndroidX : No instrumentation registered! Must run under a registering instrumentation

I'm trying to run a local unit test that depends on the context, and was following this guide: https://developer.android.com/training/testing/unit-testing/local-unit-tests#kotlin and I set up my project like this (following this link : https://developer.android.com/training/testing/set-up-project ):
build.gradle(app)
android {
compileSdkVersion 28
buildToolsVersion '27.0.3'
defaultConfig {
minSdkVersion 21
targetSdkVersion 27
versionCode 76
versionName "2.6.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
useLibrary 'android.test.runner'
useLibrary 'android.test.base'
useLibrary 'android.test.mock'
}
testOptions {
unitTests.returnDefaultValues = true
unitTests.all {
// All the usual Gradle options.
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen { false }
showStandardStreams = true
}
}
unitTests.includeAndroidResources = true
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion", {
exclude group: 'com.android.support', module: 'support-annotations'
})
// Espresso UI Testing dependencies
implementation "androidx.test.espresso:espresso-idling-resource:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
testImplementation 'androidx.test:core:1.0.0'
// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test:rules:1.1.0'
// Espresso Assertions
androidTestImplementation 'androidx.test.ext:junit:1.0.0'
androidTestImplementation 'androidx.test.ext:truth:1.0.0'
androidTestImplementation 'com.google.truth:truth:0.42'
implementation 'androidx.multidex:multidex:2.0.0'
}
My espresso_version is espressoVersion = '3.1.0'
My test that is located in module-name/src/test/java/ looks like this:
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.instacart.library.truetime.TrueTime
import edu.mira.aula.shared.extensions.android.trueDateNow
import edu.mira.aula.shared.network.ConnectivityHelper
import kotlinx.coroutines.experimental.runBlocking
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import java.util.*
import java.util.concurrent.CountDownLatch
class TimeExtensionsUnitTest {
private lateinit var instrumentationCtx: Context
#Before
fun setup() {
instrumentationCtx = ApplicationProvider.getApplicationContext<Context>()
}
#Test
fun testTrueTimeValueReturnsIfInitialized() {
if (ConnectivityHelper.isOnline(instrumentationCtx)) {
runBlocking {
val countDownLatch = CountDownLatch(1)
TrueTime.build()
.withSharedPreferencesCache(instrumentationCtx)
.withConnectionTimeout(10000)
.initialize()
countDownLatch.countDown()
try {
countDownLatch.await()
val dateFromTrueTime = trueDateNow()
val normalDate = Date()
Assert.assertNotEquals(dateFromTrueTime, normalDate)
} catch (e: InterruptedException) {
}
}
}
}
Everytime I run it, it gives me:
java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
at androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:45)
at androidx.test.core.app.ApplicationProvider.getApplicationContext(ApplicationProvider.java:41)
If I run it as a Instrumental Test(changing the package) it runs without errors.
But I thought that this guide was exactly to be able to run unit test using Android Framework classes such as Context.
I even tried run that class UnitTestSample but the same error occurs.
I also removed all android.support dependencies from my project
Any ideas on how to solve it?
Update
You should no longer encounter this error if youre using the latest gradle version.
I also encountered this issue.
If you look at migrating to Robolectric 4.0 here, it suggest to add the following line in your gradle.properties.
android.enableUnitTestBinaryResources=true
The problem is that, if you add this you your gradle.properties, it will output this warning:
WARNING: The option setting
'android.enableUnitTestBinaryResources=true' is experimental and
unsupported.
Now, if you look at Robolectric releases here. You could see that this is a known issue where they state that
Android Gradle Plugin may report the following warning, which may be safely ignored: WARNING: The option setting 'android.enableUnitTestBinaryResources=true' is experimental and unsupported.. Android Gradle Plugin 3.4 will resolve this issue.
I believe unless you could update you gradle to 3.4. You won't be able to solve this issue.
What I did instead was to include Robolectric 4.0 as dependency.
testImplementation "org.robolectric:robolectric:4.0.2"
and annotate my test class with
#RunWith(RobolectricTestRunner::class)
This should make your test work.
Now when you run the test, you'll notice that Robolectric will log the following:
[Robolectric] NOTICE: legacy resources mode is deprecated; see
http://robolectric.org/migrating/#migrating-to-40
Ignore this for now but as soon as you could update your gradle, migrate to the new Robolectric testing.
I follow the official guide also met this issue, fix it with below steps.
Add testImplementation in app build.gradle
// Required -- JUnit 4 framework
testImplementation 'junit:junit:4.13.1'
testImplementation 'androidx.test:core-ktx:1.3.0'
testImplementation 'androidx.test.ext:junit-ktx:1.1.2'
// Robolectric environment
testImplementation 'org.robolectric:robolectric:4.4'
// Optional -- truth
testImplementation 'androidx.test.ext:truth:1.3.0'
testImplementation 'com.google.truth:truth:1.0'
// Optional -- Mockito framework
testImplementation 'org.mockito:mockito-core:3.3.3'
The official guide missed two testImplementations
testImplementation 'androidx.test.ext:junit-ktx:1.1.2'
testImplementation 'org.robolectric:robolectric:4.4'
Add testOptions block in app build.gradle
android {
// ...
testOptions {
unitTests.includeAndroidResources = true
}
}
Add #RunWith(AndroidJUnit4::class) to your test class
Example:
import android.content.Context
import android.os.Build.VERSION_CODES.Q
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
#RunWith(AndroidJUnit4::class)
#Config(sdk = [Q])
class UnitTestWithContextDemoTest {
private val context: Context = ApplicationProvider.getApplicationContext()
fun test_getPackageName() {
assertThat(context.packageName).contains("your_package_name")
}
}
NOTE
#Config(sdk = [Q]) is required when your targetSdkVersion greater than 29. Because robolectric NOT support targetSdkVersion greater than 29.
Spend hours on similar issue, and the problem wasn't in dependencies, rather in AndroidStudio itself Based on the answer:
IDE tries to run local unit tests instead of instrumented
.
Make sure it's run as instrumented test (red is local tests, green - instrumented):
After added instrumented test for the class it's run as expected under instrumented. How I done this? 2 ways I found:
1) Edit configuration (as on the last screenshot) and adding function manually
2) Under Project tap (top left corner) I selected Tests instead of android, found the test, right click - create test. After this step all new tests are run under instrumented tests
I had similar error and was struggling a lot to fix it. My problem was that I was mixing AndroidJUnit4, InstrumentationRegistry, ApplicationProvider and AndroidJUnitRunnerversions / packages. Make sure they all are of the same generation. These are the classes that made it all run for me:
androidx.test.runner.AndroidJUnitRunner
androidx.test.platform.app.InstrumentationRegistry
androidx.test.ext.junit.runners.AndroidJUnit4
androidx.test.core.app.ApplicationProvider
for these I needed the following in the dependencies part of my build.gradle
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
androidTestImplementation 'androidx.test:core:1.1.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation "com.android.support:support-annotations:27.1.1"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
And of course the correct
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
in my defaultConfig of the build.gradle
Next things are not mentioned on google test guide, but they are what I found:
androidx.test in case of unit tests is just an interface/api (I don't know what about instrumented tests) and it needs implementations, which is robolectric library.
That's why robolectric dependency is also required:
testImplementation "org.robolectric:robolectric:{version}"
#RunWith(AndroidJUnit4.class)
is required. To get nondeprecated class you need to add:
testImplementation "androidx.test.ext:junit:{version}". By the way this dependency has transitive junit4 dependensy.
Also you can faced with: Failed to create a Robolectric sandbox: Android SDK 29 requires Java 9 (have Java 8) in case you use java 8 and compileSdkVersion 29 or above. Here you can find how to deal with it.
Make sure to put your instrumentation tests (tests you run with a Runner) in androidTest and not just test
in my case I was using getApplicationContext() in a fragment from the test package, I just change it to getContext(). and this fixed my crash!
In my case, changing the test method name fixed the issue.
Most probably the Android Studio cached the methods with indexes that caused a problem.
[Note : To remember this ]
AndroidJUnit4.class | used to run testcases of intrumentation type inside source set called androidTest [which requires phone or emulator]
AndroidJUnit4ClassRunner | used to run testcases for local test inside source set called test folder. [ no phone /emulator required]
Exception or Improvement Case | Using Robo-electric and supported junit4 dependency, then AndroidJUnit4.class can be used inside test folder to test local test.
Use this dependency[try to add latest]
testImplementation "org.robolectric:robolectric:4.4"
Then in your test class, use #RunWith(AndroidJUnit4::class)
Example : #RunWith(AndroidJUnit4::class)
-------For Reference-----
#RunWith(AndroidJUnit4::class)
class TasksViewModelTest {
#Test
fun addNewTask_setsNewTaskEvent() {
// Given a fresh TasksViewModel
var tasksViewModel = TasksViewModel(ApplicationProvider.getApplicationContext())
// When adding a new task
tasksViewModel.addNewTask()
// Then the new task event is triggered
}
}
Looks like you forgot to annotate your TimeExtensionsUnitTest with #RunWith(AndroidJUnit4::class) re: https://github.com/android/android-test/issues/409. I can reproduce the error by commenting that out in my own tests.
That said, this is not the only way to get your error. I originally encountered it when I was updating some old Robolectric tests to use some AndroidX apis (http://robolectric.org/androidx_test/), including switching away from #RunWith(RobolectricTestRunner::class). In my case, I was trying to use a context in my #BeforeClass with ApplicationProvider.getApplicationContext<Context>(), which is wrong in AndroidX, even though it was ok using Roboletric's runner with appContext = RuntimeEnvironment.getApplication().applicationContextappContext. Fortunately I was able to move the logic into my #Before call to fix things without a significant hit.
More generally, I've noticed documentation out there isn't fully comprehensive all in one place explaining the migration from the very old android.support.test Android Testing Support Library and Roboletric dependencies to AndroidX, but here's some other notes:
If I want to run real instrumentation tests on an emulator/physical device, ensure that the tests are under src/androidTest. This also means I need to change in my build.gradle file the dependencies on androidx.test libraries from testImplementation => androidTestImplementation, and also explicitly set a testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" in the defaultConfig section.
https://developer.android.com/training/testing/local-tests
https://developer.android.com/training/testing/instrumented-tests
If I'm happy with using Robolectric to run those tests as local, I can keep them under src/test, declare the dependencies using testImplementation, and don't need the testInstrumentationRunner. It's nice that I don't have to change the code to do this since I'm using the AndroidX Test APIs, which Roboletric is compatible with as of v4.0.
I got the same problem and here is how i fixed it:
move my test class to the "androidTest" package
annotate the test class with #RunWith(AndroidJUnit4.class)
Hope this can help
Simply check your import section:
import androidx.test.runner.AndroidJUnit4;

Type Android Junit4 not present exception

I have an Android project that I am trying to run Instrumentation tests for using AndroidStudio, but when I try to run the whole class file for the tests, I get the exceptions as stated below :
java.lang.TypeNotPresentException: Type android.support.test.runner.AndroidJUnit4 not present
Caused by: java.lang.ClassNotFoundException: android.support.test.runner.AndroidJUnit4
Interestingly, I can run individual methods in this Instrument Test class, just not the whole class. My build.gradle file for the app is below:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
lintOptions {
abortOnError false
}
compileSdkVersion 28
defaultConfig {
applicationId "com.sarpuner.journal"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
buildToolsVersion '27.0.3'
}
repositories {
maven { url "https://dl.bintray.com/ijabz/maven" }
}
dependencies {
androidTestImplementation 'com.android.support:support-annotations:27.1.1'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'dev.dworks.libs:volleyplus:0.1.4'
implementation 'com.google.code.gson:gson:2.8.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.jsoup:jsoup:1.11.3'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.1'
implementation 'net.jthink:jaudiotagger:2.2.3'
api 'com.google.guava:guava:26.0-android'
}
And the InstrumentTest class is as follows:
package com.sarpuner.journal
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import android.util.Log
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
import java.io.File
private const val INSTRUMENT_TAG = "InstrumentTest"
// TODO: There is a problem here with the class run!
#RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
private val appContext = InstrumentationRegistry.getTargetContext()
#Test
fun useAppContext() {
// Context of the app under test.
assertEquals("com.sarpuner.journal", appContext.packageName)
}
#Test
fun downloadAndSaveAudio() {
val url = "http://telechargement.rfi.fr/rfi/francais/audio/jff/201808/journal_francais_facile_20h00_-_20h10_tu_20180809.mp3"
val name = "09-08-2018.mp3"
val f = File(appContext.filesDir, name)
Log.d(INSTRUMENT_TAG, f.absolutePath)
downloadAudio(url, f)
}
#Test
fun downloadAndSaveTranscript() {
val url = "https://savoirs.rfi.fr/fr/apprendre-enseigner/langue-francaise/journal-en-francais-facile-09082018-20h00-gmt"
val name = "09-08-2018.txt"
val f = File(appContext.filesDir, name)
downloadText(url, f)
}
#Test
fun addLyricsToAudio() {
}
}
Any help/guidance is much appreciated, thank you.
This is caused by Android Studio trying to execute an instrumentation test as a JUnit test.
I had to go to 'Edit Configurations...' and delete the configuration from Android JUnit group and manually add to the 'Android Instrumented Tests' group. After this I had no problem executing the tests.
In Android Studio, click Run > Edit Configurations.
https://developer.android.com/studio/run/rundebugconfig
Writing steps if someone facing issue while edit configuration for above #Bohsen's answer
In Android Studio, click Run > Edit Configurations (or press alt + shift + f10 if on Windows) to open the configuration editor.
The left panel of the window shows configurations and their groups.
Android JUnit group
Android instrumented tests
If your test is an instrumentation test, delete it from any JUnit tests groups.
If your test is a JUnit test, delete it from any instrumentation test groups.
For example, my test (DBTest.kt) was appearing in both Android JUnit and Instrumented group's section. So I deleted from JUnit group and ran it again, it was working fine.
Hopefully someone can give you a better answer as to why, but I had this exact same problem. I did the following:
Build > Clean Project,
Ran the app on the emulator
This done, I was able to get back into a state where I could run the tests again.
I had the same with:
Type androidx.test.ext.junit.runners.AndroidJUnit4 not present
I tried a lot of things before manually removing the App from the device and running the test again. Hope this helps!
For me this actually seemed to be caused by an internet connection issue. Turning off and on wifi fixed and rebuilding seemed to fix.
I got this issue when I did my tests on the emulator.
I fixed it by downloading a new project copy from the git repository.

Cannot import android.arch.persistence.room.testing.MigrationTestHelper

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)

Android Studio Espresso Testing Error: Empty Test Suite

I keep running into the following error when trying to execute my tests in Android Studio: Test running failed: Unable to find instrumentation info for: ComponentInfo{.test/android.support.test.runner.AndroidJUnitRunner}
My test class is in the androidTest/java directory and has a constructor. My build.gradle is correct too. Any help is appreciated.
Test Class
#RunWith(AndroidJUnit4.class)
#LargeTest
public class AndroidUITests extends ActivityInstrumentationTestCase2<UserActivity>{
private UserActivity userActivity;
public AndroidUITests() {
super(UserActivity.class);
}
#Before
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
userActivity = getActivity();
}
#Test
public void testPhoneIconIsDisplayed() {
// When the phone_icon view is available,
// check that it is displayed.
onView(ViewMatchers.withId(R.id.groupCreate)).perform(click())
.check(matches(withText("Enter a name")));
}
}
app/build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
packagingOptions {
exclude 'LICENSE.txt'
}
}
dependencies {
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
}
While the question is already answered, figured it was worth posting for future visitors.
Make sure you check the logcat logs to ensure something isn't causing issues (crash) before the test is even run. I had bad code in my #BeforeClass block which resulted in the "Empty Test Suite" message in Android Studio despite having properly set the test runner.
You have to update the test "Edit Configuration" and include the AndroidJUnitRunner as the instrumentation runner.
I found the solution in this video:
https://youtu.be/TGU0B4qRlHY?t=9m36s
Updated
Adding what #loeschg suggest:
Make sure you check the logcat logs to ensure something isn't causing issues (crash) before the test is even run. Bad code in the #BeforeClass block could resulted in the "Empty Test Suite" message in Android Studio despite having properly set the test runner.
If you get such error message:
Class not found: "com.example.product.package.name.SomeSpecificTest" Empty test suite.
You need to make sure if your Espresso test is added under Android Instrumented Tests section in Run/Debug Configurations.
It seems like Android Studio 3.1.3 is sometimes adding it incorrectly to Android JUnit section instead.
Make sure it looks something like this:
Also, worth mentioning that I've noticed, that this issue occurs for me while a non Debug build variant is selected.
I'm fairly certain android.support.test.runner.AndroidJUnitRunner is provided by the runner library.
Install the Android Support Repository (which you've already done)
Add runner to your dependencies
it should look like this
dependencies {
...
androidTestCompile 'com.android.support.test:runner:0.2'
}
If anyone still bother with this in 2018, here is working setup:
build.gradle (required):
<...snip...>
android {
defaultConfig {
<...snip...>
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// ^^^ here it is (first)!
}
<...snip...>
dependencies {
<...snip...>
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
// ^^^ all three required ^^^ (second)
}
And in instrumented tests (required too):
import androidx.test.espresso.Espresso.onData
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.*
import androidx.test.espresso.assertion.ViewAssertions.*
import androidx.test.espresso.matcher.RootMatchers.*
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import org.hamcrest.Matchers.*
import org.junit.Test
import org.junit.runner.RunWith
#RunWith(AndroidJUnit4::class)
#LargeTest
class ApplicationTest {
#Test
fun thruStillThrullyThrue() {
// do interaction with some UI
onView(withId(R.id.myButtonOnMyActivity)).perform(click())
// assert expected result
onView(withId(R.id.myTextViewOnMyActivity)).check(matches(isDisplayed()))
}
}
// (third)
My issue was that the field 'testInstrumentationRunner' is specified in the build.gradle (app). Change that to the androidx if you are using it (androidx.test.runner.AndroidJUnitRunner)
Hope it helps someone, cheers!

Categories

Resources