Search code examples
javaandroidunit-testingjunitinstrumentation

How to run instrumentation @SmallTests from terminal?


I can't run my @SmallTests from terminal. I have created example of my setup and I would like you to point out what am I doing wrong.

  1. I am using my own default Runner class which looks like that:

    public class MyAppTestRunner extends AndroidJUnitRunner {
    
        @Override
        public Application newApplication(ClassLoader cl, String className, Context context) 
                throws InstantiationException, IllegalAccessException, ClassNotFoundException {
            return super.newApplication(cl, MyAppTestApplication.class.getName(), context);
        }
    }
    
  2. I have set this runner in my gradle:

    android {
        defaultConfig {
            testInstrumentationRunner "com.MyApp.instrumentation.config.MyAppTestRunner"
        }
        testBuildType 'integrationTest'
    }
    
  3. I am also using those dependencies:

    androidTestCompile com.android.support.test:runner:0.5
    androidTestCompile com.android.support.test:rules:0.5
    
  4. And then I have created simple class with one test case annotated with @SmallTest:

    import android.content.Intent;
    import android.support.test.filters.SmallTest;
    import android.support.test.rule.ActivityTestRule;
    import android.support.test.runner.AndroidJUnit4;
    
    import com.MyApp.a.ui.activity.WelcomeActivity;
    
    import org.junit.Before;
    import org.junit.Rule;
    import org.junit.runner.RunWith;
    
    
    @RunWith(AndroidJUnit4.class)
    public class ExampleTestPackage {
    
        @Rule
        public ActivityTestRule<WelcomeActivity> activityRule = new ActivityTestRule<>(
            WelcomeActivity.class, true, false
        );
    
        @Before
        public void before() {
            activityRule.launchActivity(new Intent());
        }
    
        @SmallTest
        public void exampleTest() {
            // some test code
        }
    }
    

So this is my setup. According to documentation of AndroidJUnitRunner which I am using, to run my tests with small annotation I should do something like this:

Running a specific test size i.e. annotated with SmallTest or MediumTest or LargeTest: adb shell am instrument -w -e size [small|medium|large] com.android.foo/android.support.test.runner.AndroidJUnitRunner

So what I do in terminal is:

adb shell am instrument -w -e size small com.MyApp.debug1.test/com.MyApp.instrumentation.config.MyAppTestRunner

But my @SmallTest is not found and the output is:

Time: 0.001

OK (0 tests)

Furthermore if I start my test class from Android Studio then I can see this error:

java.lang.Exception: No runnable methods
at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:191)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:128)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:416)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:84)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at android.support.test.internal.runner.junit4.AndroidJUnit4ClassRunner.<init>(AndroidJUnit4ClassRunner.java:37)
at android.support.test.runner.AndroidJUnit4.<init>(AndroidJUnit4.java:36)
at java.lang.reflect.Constructor.newInstance(Native Method)
at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.buildAndroidRunner(AndroidAnnotatedBuilder.java:83)
at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.runnerForClass(AndroidAnnotatedBuilder.java:62)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runner.Computer.getRunner(Computer.java:40)
at org.junit.runner.Computer$1.runnerForClass(Computer.java:31)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:101)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:87)
at org.junit.runners.Suite.<init>(Suite.java:81)
at org.junit.runner.Computer.getSuite(Computer.java:28)
at android.support.test.internal.runner.TestRequestBuilder.classes(TestRequestBuilder.java:789)
at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:753)
at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:354)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:260)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879)

Which of course can be fixed if I change my @SmallTest to @Test (import org.junit.Test;)

Am I using wrong classes there?


Solution

  • The annotations @SmallTest, @MediumTest, etc from android.support.test.filters do not replace the @Test annotation. The @Test annotation is required to signal JUnit that the corresponding method is a test case (http://junit.org/junit4/javadoc/latest/org/junit/Test.html).

    In your case, this will work:

    @SmallTest
    @Test
    public void exampleTest() {
        // some test code
    }