33

I created a default empty project on Android Studio 2.1.2 with API 24. In the sample project, Google offers a depreciated class ApplicationTestCase:

This class was deprecated in API level 24. Use ActivityTestRule instead. New tests should be written using the Android Testing Support Library.

Sample:

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

My Question: Why Android Test Case is now deprecated? How to replace ApplicationTestCase by ActivityTestRule?


EDIT:

I try with Expresso, but on API 24 (compileSdkVersion 24) I have this error:

Error:Conflict with dependency 'com.android.support:appcompat-v7'. Resolved versions for app (24.0.0) and test app (23.1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
Error:Conflict with dependency 'com.android.support:design'. Resolved versions for app (24.0.0) and test app (23.1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
Error:Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (24.0.0) and test app (23.1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
Error:Conflict with dependency 'com.android.support:recyclerview-v7'. Resolved versions for app (24.0.0) and test app (23.1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.

When I try to add this lib in my build.gradle:

// Android JUnit Runner
androidTestCompile 'com.android.support.test:runner:0.5'
// JUnit4 Rules
androidTestCompile 'com.android.support.test:rules:0.5'
// Espresso core
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
// Espresso-contrib for DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2'
// Espresso-web for WebView support
androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2'
// Espresso-idling-resource for synchronization with background jobs
androidTestCompile 'com.android.support.test.espresso:espresso-idling-resource:2.2.2'

My conclusion is that for the moment neither Android Test Case nor Expresso works on Android API 24. Is this right?


EDIT: 2016-08-05

I fix previous error on Expresso like that:

def espressoVersion = '2.2.2'
def testRunnerVersion = '0.5'
androidTestCompile "com.android.support.test:rules:${testRunnerVersion}"
androidTestCompile "com.android.support.test.espresso:espresso-core:${espressoVersion}"
configurations.androidTestCompile.dependencies.each { androidTestCompileDependency ->
    androidTestCompileDependency.exclude group: 'com.android.support'
}
lopez.mikhael
  • 9,943
  • 19
  • 67
  • 110

3 Answers3

25

The new androidTest example that the beta version of Android Studio 2.2 generates, look like this:

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("org.mypackage", appContext.getPackageName());
    }
}

Just like the deprecation warning suggests, the new instrumentation tests should use InstrumentationRegistry instead of extending from AndroidTestCase. Run them with AndroidJUnit4.

The relevant dependencies section in build.gradle looks like this:

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
})
friederbluemle
  • 33,549
  • 14
  • 108
  • 109
  • 3
    Ok, but how do you replace `ApplicationTestCase`? It handles app setup and teardown between each test case. – TWiStErRob Sep 08 '16 at 14:04
  • @TWiStErRob Simply add a methods to your test case and annotate them with `@Before` and `@After` from JUnit, and perform your setup/teardown actions there. – friederbluemle Sep 15 '16 at 11:04
  • 3
    I know that, my question was more targeted towards: what's the contents of those methods to **properly** create a new `Application` instance each time without leaking, conflicting and having the instance created in that test available through `context.getApplicationContext()` where needed inside the app? – TWiStErRob Sep 15 '16 at 11:07
  • If I am understanding it correctly, your Application class needs to handle that resource leaks regardless whether it is called from the Test class or not. Please see my answer below on how to use it instead of ApplicationTestCase. – MG Developer Sep 08 '18 at 17:50
1

As indicated in the API documentation the API has been deprecated and instead use of the InstrumentationRegistry.getTargetContext() will in turn call onCreate method of your Application class.

The getTargetContext will call the ApplicationStartupService class defined in Android Manifest as below.

    <?xml version="1.0" encoding="utf-8"?>
     <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       <application
           android:name=".service.ApplicationStartupService"

 public class ApplicationStartupService extends Application
 {

       /**
         * Method initializes the application configuration
       */
       @Override
       public void onCreate(){

          super.onCreate();

          this.initResources()
       }

      private void initResource(){
          //do your application init work here.
      }
}

Test Class

  @RunWith(AndroidJUnit4.class)      
  public class ApplicationStartupServiceTest {

  @Test
  public void testResourcesAreInitializedd() throws Exception {
   //do your assertions here.
  }

https://developer.android.com/reference/android/test/ApplicationTestCase

MG Developer
  • 859
  • 11
  • 17
0

With what can I replace

public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}