Espresso 2.1 doesn't find my tests

2019-07-21 16:32发布

问题:

I have looked through all the questions on stack I found with similar problem, but none has given me an answer that actually work (https://stackoverflow.com/search?q=espresso+empty+test+suite).

I have a simple project I want to try espresso on. My class file looks like this:

package com.example.myapplication;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class FirstActivity extends Activity implements View.OnClickListener {

    Button mClickMeButton;
    TextView mHelloWorldTextView;

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

        setupView();
    }

    private void setupView() {
        mHelloWorldTextView = (TextView) findViewById(R.id.helloWorldTextView);
        mHelloWorldTextView.setText(getTitleText());
        mClickMeButton = (Button) findViewById(R.id.clickMeBtn);
        mClickMeButton.setOnClickListener(this);
    }

    private String getTitleText() {
        return "First Activity";
    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(this, SecondActivity.class);
        startActivity(intent);
    }
}

My test file look like this:

package com.example.myapplication.test;

import android.graphics.Bitmap;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

import com.example.myapplication.BuildConfig;
import com.example.myapplication.FirstActivity;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class FirstActivityTest extends ActivityInstrumentationTestCase2<FirstActivity> {

    public FirstActivityTest() {
        super(FirstActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        getActivity();
    }

    @Test
    public void testListGoesOverTheFold() {
        onView(withText("First Activity")).check(matches(isDisplayed()));
    }
}

and the build.gradle like this:

apply plugin: 'com.android.application'
apply plugin: 'jacoco'
apply plugin: "sonar-runner"
apply plugin: 'spoon'

android {
    compileSdkVersion 21
    buildToolsVersion '22.0.1'

    packagingOptions {
        exclude 'LICENSE.txt'
    }

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"

        testApplicationId "com.example.myapplication.test"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        debug {
            testCoverageEnabled true
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    dependencies {
        testCompile 'org.easytesting:fest:1.0.16'
        testCompile 'junit:junit:4.12'
        testCompile 'org.robolectric:robolectric:2.4'
        testCompile 'com.squareup:fest-android:1.0.8'

        androidTestCompile 'com.squareup.spoon:spoon-client:1.1.9'
        androidTestCompile 'com.android.support.test:runner:0.2'
        androidTestCompile 'com.android.support.test:rules:0.2'
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.1') {
            exclude group: 'javax.inject'
        }
    }

    spoon {
        debug = true
        //devices = ['333236E9AE5800EC']
        if (project.hasProperty('spoonClassName')){
            className = project.spoonClassName
        }
    }
}

def coverageSourceDirs = [
        '../app/src/main/java', 'src/gen'
]


task jacocoTestReport(type: JacocoReport, dependsOn: "testDebug") {
    group = "Reporting"
    description = "Generate Jacoco coverage reports after running tests."
    reports {
        xml.enabled = true
        html.enabled = true
    }

    classDirectories = fileTree(
            dir: './build/intermediates/classes/debug',
            excludes: ['**/R.class',
                       '**/R$*.class'
            ])
    sourceDirectories = files(coverageSourceDirs)
    executionData = files('build/jacoco/testDebug.exec')
}
}

Every time I try to run it, I get:

Testing started at 16:57 ...
Target device: genymotion-google_nexus_5___5_0_0___api_21___1080x1920-192.168.56.101:5555
Uploading file
    local path: /Users/pernillauhlin/development/pingdom/android-robolectric-test/app/build/outputs/apk/app-debug.apk
    remote path: /data/local/tmp/com.example.myapplication
No apk changes detected. Skipping file upload, force stopping package instead.
DEVICE SHELL COMMAND: am force-stop com.example.myapplication
Uploading file
    local path: /Users/pernillauhlin/development/pingdom/android-robolectric-test/app/build/outputs/apk/app-debug-androidTest-unaligned.apk
    remote path: /data/local/tmp/com.example.myapplication.test
No apk changes detected. Skipping file upload, force stopping package instead.
DEVICE SHELL COMMAND: am force-stop com.example.myapplication.test
Running tests
Test running startedTest running failed: Unable to find instrumentation info for: ComponentInfo{com.example.myapplication.test/android.test.InstrumentationTestRunner}
Empty test suite.

My structure is:

Also, running spoon from command give me the same result. So, my question is:

  • What am I missing?
  • The annotation for tests; I've seen a lot of variations, above class, before test and so on. What is the correct way? Or can you specify @LargeTest before class and the @SmallTest before the actual test method?

EDIT:

My run configuration looks like this:

It looks like android.support.test.runner.AndroidJUnitRunner doesn't exist.

Build variants:

回答1:

I managed to reproduce your situation by setting the wrong android.test.InstrumentationTestRunner in the test configuration.

I would suggest checking if you have the correct one -android.support.test.runner.AndroidJUnitRunner- (or none) specified in the Run menu | Edit Configurations.

Also, your question's title is somewhat confusing, since from the build gradle dependencies, my understanding is that you're actually going for Espresso 2.1. If that is true, also note that:

TestCases like ActivityInstrumentationTestCase2 or ServiceTestCase are deprecated in favor of ActivityTestRule or ServiceTestRule.

As it can also be seen here or here, the annotations are to be used in the following way: (will adjust your deprecated test class just because I'm nice)

//annotate JUnit4 test classes with
@RunWith(AndroidJunit4.class)
@LargeTest
public class FirstActivityTest {

//use the following annotation and declare an ActivityTestRule for your activity under test
@Rule
public ActivityTestRule<FirstActivity> mActivityRule = new ActivityTestRule(FirstActivity.class);

//use @Before to setup your test fixture
@Before
public void setUp() { ... }

//annotate all test methods with
@Test
public void testHelloWorld() { ... }

//release resources by using
@After
public void tearDown() { ... }
}

More on Rules

Other great place to find out more about test size annotations



回答2:

Maybe this will help someone in the future: if you get a "no space left on device" error while installing the Android stuff, you have to re-install everything.

(If your disk was not full of almost full during installation, don't read it.)

I had a similar issue, the test were not run. The reason was that the announced memory requirements for the Android studio did not include the components required for testing. (And BTW you need not just 2G, but 2G in /tmp and 2G in your home directory.) Now, when the disk memory is exhausted, you get an installation that does not work. After you clear some additional space and re-run the installer, it still does not work. You have to remove everything, clear ~/.AndroidStudio1.5 (because after removal of the software it just wastes precious space), and re-install. (Most likely, they download .zip archives and do not check the result. Even if they considered md5 checking too complex, they still could check the file length! But they do not.)

To print memory usage in a directory under Linux, use du -h -d 1 (or du -h -d 2 for 2 directory levels, -h stands for human-readable).