I am digging for more than one week for an android tests with espresso.
I can not make Idle resourses work properly in my project (integrate into project).
Here is what I added to build.gradle :
dependencies {
// Testing-only dependencies
androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
}
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
What is in test class:
SetUp:
countingResource = new CountingIdlingResource("HelloWorldServerCalls");
Espresso.registerIdlingResources(countingResource);
In Test method:
Espresso.onView(ViewMatchers.withId(R.id.btnLogIn)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
Log.d(TAG, "We are in WalkthroughActivity, user is not logged in");
//press button - walk to next activity
Espresso.onView(ViewMatchers.withId(R.id.btnLogIn)).perform(ViewActions.click());
//register MyUserHelperV2 - this is Server decorator
final LoginActivity act = (LoginActivity) getCurrentActivity();
LoginActivity.Server aHelper = act.getUserHelper();
MyUserHelperV2 helper = new MyUserHelperV2(aHelper, countingResource);
act.setUserHelper(helper);
//set password and email
Espresso.onView(ViewMatchers.withId(R.id.email)).perform(ViewActions.typeText("test#mail.ru"));
Espresso.onView(ViewMatchers.withId(R.id.password)).perform(ViewActions.typeText("password111"));
//Check if button R.id.btnLogInApp exists:
Espresso.onView(ViewMatchers.withId(R.id.btnLogInApp)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
Espresso.closeSoftKeyboard();
Espresso.onView(ViewMatchers.withId(R.id.btnLogInApp)).perform(ViewActions.click());
//in last line we have PerformException - can not find R.id.btnLogInApp,
But for sure this button exist - I can emulate not-idle(sync) call and all is working OK.
I am thinking I can make a mistake in settings - on android 5 all works, on other androids <5 - does not.
I have dug through a lot of samples, and for sure implemented Idle res perfectly. But I am too bad with gradle system.
Please help, I am desperate with espresso and gradle, I can attach more spec code if needed.
Here is a build.gradle example file
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22"
defaultConfig {
applicationId "com.my.awesome.app"
minSdkVersion 10
targetSdkVersion 22.0.1
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
dependencies {
// App's dependencies, including test
compile 'com.android.support:support-annotations:22.2.0'
// Testing-only dependencies
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
}
And a test class exemple
Android Studio create test by default in src/androidTest/java/com.example.package/
#RunWith(AndroidJUnit4.class)
#LargeTest
public class HelloWorldEspressoTest {
#Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class);
#Test
public void listGoesOverTheFold() {
onView(withText("Hello world!")).check(matches(isDisplayed()));
}
}
Related
I have used Admob in several projects already, but this time I encounter a strange problem.
I followed all instructions from the official documentary (here), and everything basically works, at least the test ads.
But I've encountered the problem, that some classes just can't be imported.
For example, when I take this code from the documentation:
MobileAds.initialize(act, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
}
});
My project just cannot find OnInitializationCompleteListener, nor initializationStatus. This was never like that in my older projects. MobileAds though can be imported just perfectly. (What I did to make it work is just omit the not working part: MobileAds.initialize(act);)
Same problem with some other classes as well, e.g. LoadAdError, AdError, or ResponseInfo.
They just cannot be imported.
Android Studio does not give any hints to classes with that name that could be imported and when I add import XXX and take XXX from the official documentation as the full class name (with packages), it cannot find that.
This is very odd, since first of all, this has never happened before in my projects, and secondly, because only some imports cannot be found.
MY APP BUILD GRADLE
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
android {
compileSdkVersion 29
buildToolsVersion "30.0.0"
defaultConfig {
applicationId "..."
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
buildTypes {
release {
// proguard stuff
}
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'com.google.android.material:material:1.2.1'
// Firebase Stuff
...
// ads
implementation 'com.google.android.gms:play-services-ads:17.1.0'
actually, you have to add a dependency on build.gradle. I wrote the dependency below
implementation 'com.google.android.gms:play-services-ads:20.1.0'
My Espresso tests were running until I had to support multidex.
My build.gradle, I have
minSdkVersion 14
targetSdkVersion 23
multiDexEnabled = true
testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.1'
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'
dexOptions {
jumboMode true
javaMaxHeapSize "4g"
incremental true
}
Test1AuthenticationEspressoTest
#RunWith(AndroidJUnit4.class)
#SmallTest
public class Test1AuthenticationEspressoTest {
#Rule
public ActivityTestRule<WelcomeActivity> mActivityRule = new ActivityTestRule(WelcomeActivity.class);
}
Here is the Error I get
junit.framework.AssertionFailedError: No tests found in
com.livestrong.tracker.test.Test1AuthenticationEspressoTest
Any help will be appreciated. Any one has espresso working with multidex ?
I was having this same problem and it turns out you need to build a custom runner that enables MultiDex and extends from the AndroidJUnitRunner. You then need to set that runner as your testInstrumentationRunner in the build.gradle, and as your runner in your run configuration. There is no need to modify the test class (keep the #RunWith(AndroidJunit4.class)).
Here's a step-by-step of what to do:
Create a class for your custom runner:
package com.bla.bla.bla; // your package
import android.os.Bundle;
import android.support.multidex.MultiDex;
import android.support.test.runner.AndroidJUnitRunner;
public class CustomTestRunner extends AndroidJUnitRunner
{
#Override
public void onCreate(Bundle arguments)
{
MultiDex.install(getTargetContext());
super.onCreate(arguments);
}
}
In your build.gradle, set the runner to your custom runner:
android {
// ...
defaultConfig {
// ...
testInstrumentationRunner "com.bla.bla.bla.CustomTestRunner"
}
}
In your run configuration, make sure the instrumentation runner is also set to the same runner.. Note: This step should not be required on Android Studio 3.x and maybe also some previous versions. This option does not exist anymore.
Using the above, I was able to run Espresso tests on our multi-dex enabled app.
I should note that many other posts on the net regarding this topic, suggest setting your runner to com.android.test.runner.MultiDexTestRunner and exculde some dependencies in com.android.support:multidex-instrumentation:1.0.1 in your build.gradle. That solution appears to no longer be the case and doesn't work as of gradle 1.5.0. If you have any of that stuff set, then it'll prevent the above from working. See the comments in this stack overflow post for more information.
When I run my test method that uses Espresso, it prompts me to choose an emulator, and I pick my existing emulator with my application already started. The emulator subsequently automatically reboots my application, and then displays that that the test suite is empty.
My espresso test case is located in the androidTest folder of the same module as the activity I'm trying to test. I wrote a simple "isDisplayed()" type of a test and right clicked the method and clicked run. I've taken a look at the other questions on Stack Overflow and other resources, but I can't figure out what is causing this problem. The logcat displays nothing and when I tried putting Log.d("debug", "hello hello") in the test method (shown below), nothing shows up in the logcat, nor does anything display when I try putting a System.out.println("hello") in the test method. It seems that although I run the method, none of my code is being run!
Below is some of my build.grade.
apply plugin: 'com.android.application'
android {
compileSdkVersion 17
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "x"
minSdkVersion 17
targetSdkVersion 17
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'LICENSE.txt'
}
}
configurations.all {
resolutionStrategy.force 'com.android.support:support-annotations:22.2.0'
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'com.android.support.test:rules:0.3'
androidTestCompile 'com.android.support.test:runner:0.3'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2'
}
Here is the test case that I'm trying to run.
#RunWith(AndroidJUnit4.class)
public class EspressoTest1 extends ActivityInstrumentationTestCase2<P1>{
private P1 mActivity;
public EspressoTest1() {
super(P1.class);
}
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
mActivity = getActivity();
}
public void Happy_test() {
onView(withId(R.id.Btn)).check(matches(isDisplayed()));
}
}
And this is the test run configuration.
Your test is missing #Test annotation. So as your setup method is missing #Before
Maybe this will help other people (like Igor Ganapolsky).
When you are using annotations from Espresso library you have to add testInstrumenatationRunner to your gradle file. Missing this line occurs the same error message "Empty test suite"
defaultConfig {
applicationId "com.test.app"
minSdkVersion 16
targetSdkVersion 24
versionCode 1
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
The page http://developer.android.com/tools/building/multidex.html#testing
advises
dependencies {
compile 'com.android.support:multidex:1.0.1'
androidTestCompile 'com.android.support:multidex-instrumentation:1.0.1'
}
android {
defaultConfig {
multiDexEnabled true
testInstrumentationRunner "android.support.multidex.MultiDexTestRunner"
}
}
But that produces a ClassNotFoundException when the tests are run.
The API documentation and dexdump show that there is com.android.test.runner.MultiDexTestRunner.
So if I disbelieve the documentation and instead specify
dependencies {
compile 'com.android.support:multidex:1.0.1'
androidTestCompile 'com.android.support:multidex-instrumentation:1.0.1'
}
android {
defaultConfig {
multiDexEnabled true
testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"
}
}
Then I get
com/company/myapp/MyApp; had used a different Landroid/support/multidex/MultiDexApplication; during pre-verification
...
IllegalAccessExceptionIllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
I suspect that the doc page is wrong and the correct path is com.android.test.runner.MultiDexTestRunner ... plus I have some other issue.
Note the multidex application works fine. Somehow a second MultiDexApplication is included in the test apk.
Questions:
Which is the correct path for MultiDexTestRunner?
Why am I getting a second MultiDexApplication in the test apk?
UPDATE: here's the fix. That's a common pattern, when you see such error message had used a different L<package>; during pre-verification, you need to exclude the package when running the test.
build.gradle
android {
// ...
defaultConfig {
// ...
multiDexEnabled true
testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"
}
}
dependencies {
// ...
// Need to exclude this when running test
androidTestCompile('com.android.support:multidex-instrumentation:1.0.1') {
exclude group: 'com.android.support', module: 'multidex'
}
}
Application.java
public class Application extends android.app.Application {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
Note: When you write instrumentation tests for multidex apps, no additional configuration is required if you use a MonitoringInstrumentation (or an AndroidJUnitRunner) instrumentation.
Thus, don't use MultiDexTestRunner, which is deprecated; use AndroidJUnitRunner instead. (This applies to multidex support library v1.0.2+)
android {
// ...
defaultConfig {
// ...
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
Only if you have a custom implementation of the test runner bootstrap with:
public void onCreate(Bundle arguments) {
MultiDex.install(getTargetContext());
super.onCreate(arguments);
...
}
See: https://developer.android.com/studio/build/multidex.html#testing
The exact problems described in the original question may be related to older versions. I'm adding my experience here, because this is one of the first Google hits when researching the problem.
With recent versions of tools and android plugin you don't need anything else than this in build.gradle:
...
android {
...
defaultConfig {
...
testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"
}
}
(I have com.android.tools.build:gradle:1.5.0)
EDIT: As #igor-ganapolsky pointed out, MultiDexTestRunner is deprecated.
I don't have access to the sources where this came up anymore, but I suspect problems with MultiDexTestRunner arise when the whole testing setup of the project is in need of overhaul.
The documentation points to the new Testing Support Library as the solution
So I've set up a gradle project with android and tried to get some tests to run. Unfortunately they don't seem to. It's possible that I'm missing something obvious but here goes...
I am running gradle 1.11 and as I understand the documentation that's the new folder (since 0.9 I believe?) that should be used for tests.
So I have my testclass ::
package se.coinhunter.multigradle.test;
import org.junit.Test;
import static org.junit.Assert.*;
public class HelloAndroidTests {
#Test
public void testHelper() {
assertEquals(1,1);
}
}
}
That lives in src/androidTest and here is my build.gradle:
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 11
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:appcompat-v7:+'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':MultiGradleSubmodule')
}
This is a multi-project build and the submodule mentioned in the dependencies block is a plain java project that has its' own scource and unit tests running quite smoothly. I was able to specify that it should tell me when it runs its' tests and give me some feedback and that works fine. That was achieved for that project using
test {
testLogging {
events 'started', 'passed'
}
}
in its' build.gradle. I havn't come across anything like this for android projects. The whole project builds and runs, but I either can't get the tests to run, or they're running but I'm not getting any output.
You're using jUnit 4 (package name "org.junit" with #Test annotation). Android gradle only works with jUnit 3 (package name "junit.framework" with no annotations).
Android tests run in the Dalvik virtual machine on a device or emulator so your test class should also extend "AndroidTestCase" (or one of the other junit subclasses in Android - depending on what you're testing).
UPDATED: also add the following to default config:
testInstrumentationRunner "android.test.InstrumentationTestRunner"
testFunctionalTest true
Run the test using
gradle connectedCheck