Search result for Question Taged unit-testing
There are some results of your Tag: unit-testing
    How to deal with deprecated gradle features were used in this build, making it incompatible with gradle 8.0

    1. FAILURE
    2. Sometime when you try to build the app you may encounter this FAILURE.
      ..."Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0."
      

    3. Most common Solution
    4. Run the Gradle build with a command line argument --warning-mode=all to see what exactly the deprecated features are.

      It will give you a detailed description of found issues with links to the Gradle docs for instructions how to fix your build.

      Adding --stacktrace to that, you will also be able to pinpoint where the warning comes from, if it's triggered by outdated code in one of the plugins and not your build script.

    5. Solution 2
    6. if the abouve Solution dont work Try this one

      cd android && ./gradlew clean && ./gradlew :app:bundleRelease
      

    7. Solution 3
    8. The process below worked in many case- First check Gradle Version:

      cd android
      ./gradlew -v
      

      In my case it was 6.5

      Go to https://developer.android.com/studio/releases/gradle-plugin and you'll get the plugin version for your gradle version. For gradle version 6.5, the plugin version is 4.1.0

      Then go to app/build.gradle and change classpath 'com.android.tools.build:gradle:<plugin_version>

    9. Solution 4
    10. if your project is incompatible with Gradle 8.0 .Here's what worked for you: First write this line of code in the Android Studio terminal:

      ./gradlew build --warning-mode all
      

      When you do that, you will be shown in the logcat what is found to be deprecated or an issue in your project, for me it was the jcenter() repository that needed to be removed in my settings.gradle file and also I needed to update classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21" to classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.30" in my build.gradle project file.

      Once I did these things, my project built perfectly and installed on my emulator

    Kyle Elkins 2022-08-09
    android - Unit testing coroutines runBlockingTest: This job has not completed yet

    Please find below a function using a coroutine to replace callback :

    override suspend fun signUp(authentication: Authentication): AuthenticationError {
        return suspendCancellableCoroutine {
            auth.createUserWithEmailAndPassword(authentication.email, authentication.password)
                .addOnCompleteListener(activityLifeCycleService.getActivity()) { task ->
                    if (task.isSuccessful) {
                        it.resume(AuthenticationError.SignUpSuccess)
                    } else {
                        Log.w(this.javaClass.name, "createUserWithEmail:failure", task.exception)
                        it.resume(AuthenticationError.SignUpFail)
                    }
                }
        }
    }
    

    Now I would like to unit testing this function. I am using Mockk :

      @Test
      fun `signup() must be delegated to createUserWithEmailAndPassword()`() = runBlockingTest {
    
          val listener = slot<OnCompleteListener<AuthResult>>()
          val authentication = mockk<Authentication> {
            every { email } returns "email"
            every { password } returns "pswd"
          }
          val task = mockk<Task<AuthResult>> {
            every { isSuccessful } returns true
          }
    
          every { auth.createUserWithEmailAndPassword("email", "pswd") } returns
              mockk {
                every { addOnCompleteListener(activity, capture(listener)) } returns mockk()
              }
    
        service.signUp(authentication)
    
          listener.captured.onComplete(task)
        }
    

    Unfortunately this test failed due to the following exception : java.lang.IllegalStateException: This job has not completed yet

    I tried to replace runBlockingTest with runBlocking but the test seems to wait in an infinite loop.

    Can someone help me with this UT please?

    Thanks in advance

    Elise Pankaj 2022-08-19
    unit testing - How can I create tests in Android Studio?

    Just downloaded Android Studio which is based off of the Intellij Idea.

    How would one create tests?

    I notice there is a option for create a Test Module but this doesn't seem to do anything, only create a new project with src

    I also tried pressing the hot key CTRL+AlT+T which allows to create unit tests on an existing class but it seems to want to place it in the current project. Of course this doesn't help with TDD

    Does anyone have any experience here ?

    Salvatrix Ngải 2022-08-16
    android - Can I use Cobertura on Unit Tests with PowerMock?

    Problem

    I am setting-up unit-test code coverage for an Android library which uses Robolectric to run the tests and PowerMock/Mockito for mock-testing.

    However, running unit-tests with Cobertura results in the following Exception...

    :example:testDebugUnitTest
    Exception in thread "Thread-5" java.lang.ExceptionInInitializerError
        at com.example.package.saas.Query$RemoveWordsType.__cobertura_init(Query.java)
        at com.example.package.saas.Query$RemoveWordsType.<clinit>(Query.java)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at net.sourceforge.cobertura.coveragedata.TouchCollector.applyTouchesToSingleClassOnProjectData(TouchCollector.java:123)
        at net.sourceforge.cobertura.coveragedata.TouchCollector.applyTouchesOnProjectData(TouchCollector.java:110)
        at net.sourceforge.cobertura.coveragedata.ProjectData.saveGlobalProjectData(ProjectData.java:272)
        at net.sourceforge.cobertura.coveragedata.SaveTimer.run(SaveTimer.java:33)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.IllegalStateException: Shutdown in progress
        at java.lang.ApplicationShutdownHooks.add(ApplicationShutdownHooks.java:66)
        at java.lang.Runtime.addShutdownHook(Runtime.java:211)
        at net.sourceforge.cobertura.coveragedata.ProjectData.initialize(ProjectData.java:239)
        at net.sourceforge.cobertura.coveragedata.ProjectData.getGlobalProjectData(ProjectData.java:209)
        at net.sourceforge.cobertura.coveragedata.TouchCollector.<clinit>(TouchCollector.java:45)
        ... 11 more
    

    ...and the generated Cobertura report shows no coverage at all. Cobertura report with PowerMock


    Running the same testcase without PowerMock*, the tests run fine and the coverage report is generated successfully: Cobertura report without PowerMock

    ​* i.e. commenting the tests using PowerMock, removing the PowerMockIgnore annotation, the PowerMockRule and the MockitoAnnotations.initMocks(this); invocation.


    Investigation

    • I see that some users fixed a similar issue by setting forkmode="once" in their testsuite.
      However, this is not the solution as I am using Gradle which defaults on Java projects to ForkMode.ONCE.
    • Other users reporting a similar issue fixed it by updating PowerMock to 1.5.4.
      I tried downgrading to this version, but the issue remains.
    • Finally, a similar issue was fixed by explicitly specifying a dependency to cobertura-runtime, but adding it didn't change anything either.

    Question

    Is it possible to use Cobertura in conjunction with PowerMock?

    • In that case, what am I missing?
    • Otherwise, how should I measure code coverage with such a setup (Android Library + Robolectric + PowerMock)?
    Meino Suvi 2022-08-17
    unit testing - Android RxJava 2 JUnit test - getMainLooper in android.os.Looper not mocked RuntimeException

    I am encountering a RuntimeException when attempting to run JUnit tests for a presenter that is using observeOn(AndroidSchedulers.mainThread()).

    Since they are pure JUnit tests and not Android instrumentation tests, they don't have access to Android dependencies, causing me to encounter the following error when executing the tests:

    java.lang.ExceptionInInitializerError
        at io.reactivex.android.schedulers.AndroidSchedulers$1.call(AndroidSchedulers.java:35)
        at io.reactivex.android.schedulers.AndroidSchedulers$1.call(AndroidSchedulers.java:33)
        at io.reactivex.android.plugins.RxAndroidPlugins.callRequireNonNull(RxAndroidPlugins.java:70)
        at io.reactivex.android.plugins.RxAndroidPlugins.initMainThreadScheduler(RxAndroidPlugins.java:40)
        at io.reactivex.android.schedulers.AndroidSchedulers.<clinit>(AndroidSchedulers.java:32)
        …
    Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
        at android.os.Looper.getMainLooper(Looper.java)
        at io.reactivex.android.schedulers.AndroidSchedulers$MainHolder.<clinit>(AndroidSchedulers.java:29)
        ...
    
    
    java.lang.NoClassDefFoundError: Could not initialize class io.reactivex.android.schedulers.AndroidSchedulers
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        …
    
    Passang Sisko 2022-08-18
    database - Android Unit Tests Requiring Context

    I am writing my first Android database backend and I'm struggling to unit test the creation of my database.

    Currently the problem I am encountering is obtaining a valid Context object to pass to my implementation of SQLiteOpenHelper. Is there a way to get a Context object in a class extending TestCase? The solution I have thought of is to instantiate an Activity in the setup method of my TestCase and then assigning the Context of that Activity to a field variable which my test methods can access...but it seems like there should be an easier way.

    Mandlenkosi Shantelle 2022-08-18
    What's the fastest way to run unit tests in Android

    There are two options available to run unit tests in Android Studio:

    1. Right click on the file with your unit tests (which is Gradle-Aware Make).
    2. testAppDebugUnitTest task is from the list of available Gradle tasks.

    The first one actually consists of two tasks: - :app:assembleAppDebug and :app:assembleAppDebugUnitTest

    The second one is just testAppDebugUnitTest itself.

    The first one is a recommended way by Google Tools Team, but it takes as twice as much time compared to the second one.

    There is no visible difference how to run unit tests except the duration. You might think your code won't be compiled without assembleAppDebug, but this is not true - changes you introduce to either class under a test or a test itself compiled and executed as expected.

    So, what's the difference and why is it the recommended way if it takes as twice as much time to prepare everything before actual unit tests run?

    Louella Eleonora 2022-09-04
    Run all unit tests in Android Studio

    I have this project in Android Studio :

    enter image description here

    I wish to run all unit tests in all project with one click.

    How i can do it ?

    Vitalija Dimas 2022-08-17
    Getting context in AndroidTestCase or InstrumentationTestCase in Android Studio's Unit Test feature

    I got some of my old tests running with Android Studio 1.1.0's new unit test support feature. When running gradlew testDebug the tests are run, but all of the tests that require a Context fail because getContext (AndroidTestCase) / getInstrumentation.getContext() (InstrumentationTestCase) both return null.

    How can I solve this?

    Here's two variants I've tried:

    import android.content.Context;
    import android.test.InstrumentationTestCase;
    
    public class TestTest extends InstrumentationTestCase {
    
        Context context;
    
        public void setUp() throws Exception {
            super.setUp();
    
            context = getInstrumentation().getContext();
    
            assertNotNull(context);
    
        }
    
        public void testSomething() {
    
            assertEquals(false, true);
        }  
    
    }
    

    and

    import android.content.Context;
    import android.test.AndroidTestCase;
    
    public class TestTest extends AndroidTestCase {
    
        Context context;
    
        public void setUp() throws Exception {
            super.setUp();
    
            context = getContext();
    
            assertNotNull(context);
    
        }
    
        public void testSomething() {
    
            assertEquals(false, true);
        }
    
    }
    

    This is my module's build.gradle:

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 22
        buildToolsVersion "22.0.0"
    
        testOptions {
            unitTests.returnDefaultValues = true
        }
    
        defaultConfig {
            applicationId "com.example.test.penistest"
            minSdkVersion 15
            targetSdkVersion 22
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:22.0.0'
        testCompile 'junit:junit:4.12'
    }
    

    and here the build.gradle for the project:

    // Top-level build file where you can add configuration options common to all sub-projects/modules.
    
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:1.1.3'
    
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    
    allprojects {
        repositories {
            jcenter()
        }
    }
    

    EDIT: My tests all worked before upgrading to AS 1.1.0 and ran on a device / emulator.

    EDIT:

    Heres 2 screenshots of failing InstrumentationTestCase and AndroidTestCase:

    enter image description here

    enter image description here

    Varinius Olwen 2022-08-30
    java - Android Unit Tests with Dagger 2

    I have an Android app that uses Dagger 2 for dependency injection. I am also using the latest gradle build tools that allow a build variant for unit testing and one for instrumentation tests. I am using java.util.Random in my app, and I want to mock this for testing. The classes I'm testing don't use any Android stuff, so they're just regular java classes.

    In my main code I define a Component in a class that extends the Application class, but in the unit tests I'm not using an Application. I tried defining a test Module and Component, but Dagger won't generate the Component. I have also tried using the Component that I defined in my application and swapping the Module when I build it, but the application's Component doesn't have inject methods for my test classes. How can I provide a mock implementation of Random for testing?

    Here's some sample code:

    Application:

    public class PipeGameApplication extends Application {
    
        private PipeGame pipeGame;
    
        @Singleton
        @Component(modules = PipeGameModule.class)
        public interface PipeGame {
            void inject(BoardFragment boardFragment);
            void inject(ConveyorFragment conveyorFragment);
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            pipeGame = DaggerPipeGameApplication_PipeGame.create();
        }
    
        public PipeGame component() {
            return pipeGame;
        }
    }
    

    Module:

    @Module
    public class PipeGameModule {
    
        @Provides
        @Singleton
        Random provideRandom() {
            return new Random();
        }
    }
    

    Base class for tests:

    public class BaseModelTest {
    
        PipeGameTest pipeGameTest;
    
        @Singleton
        @Component(modules = PipeGameTestModule.class)
        public interface PipeGameTest {
            void inject(BoardModelTest boardModelTest);
            void inject(ConveyorModelTest conveyorModelTest);
        }
    
        @Before
        public void setUp() {
            pipeGameTest = DaggerBaseModelTest_PipeGameTest.create(); // Doesn't work
        }
    
        public PipeGameTest component() {
            return pipeGameTest;
        }
    }
    

    or:

    public class BaseModelTest {
    
        PipeGameApplication.PipeGame pipeGameTest;
    
        // This works if I make the test module extend
        // the prod module, but it can't inject my test classes
        @Before
        public void setUp() {
            pipeGameTest = DaggerPipeGameApplication_PipeGame.builder().pipeGameModule(new PipeGameModuleTest()).build();
        }
    
        public PipeGameApplication.PipeGame component() {
            return pipeGameTest;
        }
    }
    

    Test Module:

    @Module
    public class PipeGameTestModule {
    
        @Provides
        @Singleton
        Random provideRandom() {
            return mock(Random.class);
        }
    }
    
    Eider Siors 2022-08-20
    android - Unit test Java class that loads native library

    I'm running unit tests in Android Studio. I have a Java class that loads a native library with the following code

     static
        {
           System.loadLibrary("mylibrary");
        }
    

    But when I test this class inside my src/test directory I get

    java.lang.UnsatisfiedLinkError: no mylibrary in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)
        at java.lang.Runtime.loadLibrary0(Runtime.java:870)
        at java.lang.System.loadLibrary(System.java:1122)
    

    How can I make it find the path of native .so libraries which is located at src/main/libs in order to unit test without errors?

    Note: inside src/main/libs directory I have 3 more subdirectories: armeabi, mips and x86. Each one of those contains the proper .so file. I'm using the Non experimental version for building NDK libs.

    I don't wanna use other 3rd party testing libraries as all my other "pure" java classes can be unit tested fine. But if that's not possible then I'm open to alternatives.

    Here is my test code which throws the error

       @Test
        public void testNativeClass() throws Exception
        {
            MyNativeJavaClass test = new MyNativeJavaClass("lalalal")
            List<String> results = test.getResultsFromNativeMethodAndPutThemInArrayList();
            assertEquals("There should be only three result", 3, results.size());
        }
    
    Karthikeyan Dimos 2022-08-18
    android - Accessing application context from TestSuite in Setup() before calling getActivity()

    I have an Activity that pulls an object from an Application extended class (application context) from within the OnCreate() method.

    When unit testing this activity, the object needed isn't there because it is populated from a previous Activity and stored in the above mentioned application context.

    Needless to say, when I call getActivity() from within my ActivityInstrumentationTestCase2 extended test case I get a null pointer exception.

    How can I populate the context before an activity is started and have it available to that Activity?

    Updated: After a bit of digging I found: this.getInstrumentation().getTargetContext() and then cast it to the type of my Application extended class. But I get a class cast exception and the trace points to this:

    04-04 21:02:27.036: INFO/TestRunner(431): started: testIt(edu.rockies.rockies.activity.courses.test.TopicTest)
    04-04 21:02:27.126: INFO/TestRunner(431): failed: testIt(edu.rockies.rockies.activity.courses.test.TopicTest)
    04-04 21:02:27.126: INFO/TestRunner(431): ----- begin exception -----
    04-04 21:02:27.136: INFO/TestRunner(431): java.lang.ClassCastException: android.app.ApplicationContext
    04-04 21:02:27.136: INFO/TestRunner(431):     at edu.rockies.rockies.activity.courses.test.TopicTest.setUp(TopicTest.java:27)
    04-04 21:02:27.136: INFO/TestRunner(431):     at junit.framework.TestCase.runBare(TestCase.java:125)
    04-04 21:02:27.136: INFO/TestRunner(431):     at junit.framework.TestResult$1.protect(TestResult.java:106)
    04-04 21:02:27.136: INFO/TestRunner(431):     at junit.framework.TestResult.runProtected(TestResult.java:124)
    04-04 21:02:27.136: INFO/TestRunner(431):     at junit.framework.TestResult.run(TestResult.java:109)
    04-04 21:02:27.136: INFO/TestRunner(431):     at junit.framework.TestCase.run(TestCase.java:118)
    04-04 21:02:27.136: INFO/TestRunner(431):     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
    04-04 21:02:27.136: INFO/TestRunner(431):     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
    04-04 21:02:27.136: INFO/TestRunner(431):     at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)
    04-04 21:02:27.136: INFO/TestRunner(431):     at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
    04-04 21:02:27.136: INFO/TestRunner(431): ----- end exception -----
    04-04 21:02:27.156: INFO/TestRunner(431): finished: testIt(edu.rockies.rockies.activity.courses.test.TopicTest)
    

    this.getInstrumentation().getTargetContext() is supposed to return an object of type context. But I get the android.app.ApplicationContext class cast exeption which doesn't make sense.

    Update 2:

    I did some more research and discovered this for android.app.Application

    java.lang.Object
        android.content.Context
            android.app.ApplicationContext
                android.app.Application
    

    But Google's own Android Javadoc refers to this:

    java.lang.Object
        android.content.Context
            android.content.ContextWrapper
                android.app.Application
    

    What's going on? Something's not right.

    Update 3:

    I have replaced the following line of code:

    this.getInstrumentation().getTargetContext();
    

    with this line of code.

    this.getInstrumentation().getTargetContext().getApplicationContext();
    

    Although the context resolves properly, it doesn't seem to be the same context as the activity's.

    Destinee Nedyalko 2022-08-23
    android - Unit testing Room and LiveData

    I'm currently developing an app using the newly Android Architecture Components. Specifically, I'm implementing a Room Database that returns a LiveData object on one of its queries. Insertion and querying work as expected, however I have an issue testing the query method using a unit test.

    Here is the DAO I'm trying to test:

    NotificationDao.kt

    @Dao
    interface NotificationDao {
    
        @Insert
        fun insertNotifications(vararg notifications: Notification): List<Long>
    
        @Query("SELECT * FROM notifications")
        fun getNotifications(): LiveData<List<Notification>>
    }
    

    As you can tell, the query function returns a LiveData object, if I change this to be just a List, Cursor, or basically whatever then I get the expected result, which is the data inserted in the Database.

    The issue is that the following test will always fail because the value of the LiveData object is always null:

    NotificationDaoTest.kt

    lateinit var db: SosafeDatabase
    lateinit var notificationDao: NotificationDao
    
    @Before
    fun setUp() {
        val context = InstrumentationRegistry.getTargetContext()
        db = Room.inMemoryDatabaseBuilder(context, SosafeDatabase::class.java).build()
        notificationDao = db.notificationDao()
    }
    
    @After
    @Throws(IOException::class)
    fun tearDown() {
        db.close()
    }
    
    @Test
    fun getNotifications_IfNotificationsInserted_ReturnsAListOfNotifications() {
        val NUMBER_OF_NOTIFICATIONS = 5
        val notifications = Array(NUMBER_OF_NOTIFICATIONS, { i -> createTestNotification(i) })
        notificationDao.insertNotifications(*notifications)
    
        val liveData = notificationDao.getNotifications()
        val queriedNotifications = liveData.value
        if (queriedNotifications != null) {
            assertEquals(queriedNotifications.size, NUMBER_OF_NOTIFICATIONS)
        } else {
            fail()
        }
    }
    
    private fun createTestNotification(id: Int): Notification {
        //method omitted for brevity 
    }
    

    So the question is: Does anyone knows of a better way to perform unit tests that involve LiveData objects?

    Salvatrix Ngải 2022-08-18
    android - How to unit test Retrofit api calls?

    I am trying to integrate Unit test cases for every chunk of code possible. But I am facing issues while adding test cases for api calls that are made through retrofit.

    The JUnit compiler never executes the code in the CallBack functions.

    There is another option of making all the api calls Synchronous for testing purpose, but that's not possible for every case in my app.

    How can I sort this out? I have to add test cases in the api calls by any means.

    Baptist Slaven 2022-08-18
    unit testing - Android Test Driven Development

    I have considerable experience in making Android applications. For my new project, we have decided to do Test Driven Development (TDD). I have been getting my hands wet on Robotium for User Scenario Testing, and it works fine and looks easy too.

    For unit testing, I tried to mock Context using (MockContext Android Class) but I am unable to do so. I went through this blog http://sites.google.com/site/androiddevtesting/ and through this http://sdudzin.blogspot.com/2011/01/easy-unit-testing-for-android.html , which suggests that mocking in Android apps is still very limited and hard, and have suggested to use PowerMock, jMockit, JeasyTest, or Roboelectric (in combination with Mockito and Maven) and even RoboGuice.

    I would like to get any suggestions from you guys on which unit testing framework in your opinion is the best for testing Android applications. (particularly testing Android classes, possibly giving mock Contexts and other mocking features so that I can make my test cases as independent as possible). Any suggestions or pointers would be helpful . Thanks

    Kyle Elkins 2022-08-22
    android - Unit testing a Kotlin coroutine with delay

    I'm trying to unit test a Kotlin coroutine that uses delay(). For the unit test I don't care about the delay(), it's just slowing the test down. I'd like to run the test in some way that doesn't actually delay when delay() is called.

    I tried running the coroutine using a custom context which delegates to CommonPool:

    class TestUiContext : CoroutineDispatcher(), Delay {
        suspend override fun delay(time: Long, unit: TimeUnit) {
            // I'd like it to call this
        }
    
        override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) {
            // but instead it calls this
        }
    
        override fun dispatch(context: CoroutineContext, block: Runnable) {
            CommonPool.dispatch(context, block)
        }
    }
    

    I was hoping I could just return from my context's delay() method, but instead it's calling my scheduleResumeAfterDelay() method, and I don't know how to delegate that to the default scheduler.

    Greta Iris 2022-08-23
    unit testing - Mocking library/framework that works best in Android?

    I'm developing Android application using third party libraries (Twitter4j). I want to be able mock those objects (also objects created by me) in JUnit and functional tests.

    Do you have any good experiences using some mocking libraries and you can recommend them?

    Seher Ernesto 2022-08-24
    android - Cannot resolve symbol InstantTaskExecutorRule

    I open example code BasicRxJavaSample (from this article Room+RxJava) The main thing is there:

    @Rule
    public InstantTaskExecutorRule instantTaskExecutorRule = 
        new InstantTaskExecutorRule();
    

    And BasicRxJavaSample is all ok. But I can not apply this in my test. That's what's going on:

    Cannot resolve symbol InstantTaskExecutorRule

    enter image description here

    And manual import does not work:

    enter image description here

    My autocompletion works like this enter image description here

    But should be so

    enter image description here

    My app build.gradle (full gradle here):

    // tests
    testImplementation 'junit:junit:4.12'
    androidTestCompile "com.android.support:support-annotations:$supportVersion"
    testImplementation "android.arch.core:core-testing:$archVersion"
    // Test helpers for Room
    testImplementation "android.arch.persistence.room:testing:1.0.0"
    // https://github.com/mockito/mockito
    testImplementation 'org.mockito:mockito-core:2.13.0'
    androidTestImplementation 'org.mockito:mockito-android:2.13.0'
    // AndroidJUnitRunner and JUnit Rules
    androidTestImplementation 'com.android.support.test:rules:1.0.1'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    // https://developer.android.com/topic/libraries/testing-support-library/packages.html
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-idling-resource:3.0.1'
    
    Edna Morgen 2022-08-18
    Android Studio unit testing: read data (input) file

    In a unit test, how can I read data from a json file on my (desktop) file system, without hardcoding the path?

    I would like to read test input (for my parsing methods) from a file instead of creating static Strings.

    The file is in the same location as my unit testing code, but I can also place it somewhere else in the project if needed. I am using Android Studio.

    Sisu Célio 2022-08-16
    java - Why is my JSONObject related unit test failing?

    I'm running my tests using gradle testFlavorType

    JSONObject jsonObject1 = new JSONObject();
    JSONObject jsonObject2 = new JSONObject();
    jsonObject1.put("test", "test");
    jsonObject2.put("test", "test");
    assertEquals(jsonObject1.get("test"), jsonObject2.get("test"));
    

    The above test succeeds.

    jsonObject = new SlackMessageRequest(channel, message).buildBody();
    String channelAssertion = jsonObject.getString(SlackMessageRequest.JSON_KEY_CHANNEL);
    String messageAssertion = jsonObject.getString(SlackMessageRequest.JSON_KEY_TEXT);
    assertEquals(channel, channelAssertion);
    assertEquals(message, messageAssertion);
    

    But the above two requests fail. The stack trace says that channelAssertion and messageAssertion are null, but not sure why. My question is: Why are the above two asserts failing?

    Below is the SlackMessageRequest.

    public class SlackMessageRequest
            extends BaseRequest {
        // region Variables
    
        public static final String JSON_KEY_TEXT = "text";
        public static final String JSON_KEY_CHANNEL = "channel";
    
        private String mChannel;
        private String mMessage;
    
        // endregion
    
        // region Constructors
    
        public SlackMessageRequest(String channel, String message) {
            mChannel = channel;
            mMessage = message;
        }
    
        // endregion
    
        // region Methods
    
        @Override
        public MethodType getMethodType() {
            return MethodType.POST;
        }    
    
        @Override
        public JSONObject buildBody() throws JSONException {
            JSONObject body = new JSONObject();
            body.put(JSON_KEY_TEXT, getMessage());
            body.put(JSON_KEY_CHANNEL, getChannel());
            return body;
        }
    
        @Override
        public String getUrl() {
            return "http://localhost:1337";
        }
    
        public String getMessage() {
            return mMessage;
        }
    
        public String getChannel() {
            return mChannel;
        }
    
    // endregion
    }
    

    Below is the stacktrace:

    junit.framework.ComparisonFailure: expected:<@tk> but was:<null>
        at junit.framework.Assert.assertEquals(Assert.java:100)
        at junit.framework.Assert.assertEquals(Assert.java:107)
        at junit.framework.TestCase.assertEquals(TestCase.java:269)
        at com.example.app.http.request.SlackMessageRequestTest.testBuildBody(SlackMessageRequestTest.java:30)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at junit.framework.TestCase.runTest(TestCase.java:176)
        at junit.framework.TestCase.runBare(TestCase.java:141)
        at junit.framework.TestResult$1.protect(TestResult.java:122)
        at junit.framework.TestResult.runProtected(TestResult.java:142)
        at junit.framework.TestResult.run(TestResult.java:125)
        at junit.framework.TestCase.run(TestCase.java:129)
        at junit.framework.TestSuite.runTest(TestSuite.java:252)
        at junit.framework.TestSuite.run(TestSuite.java:247)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
        at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
        at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
        at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
        at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
        at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
        at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
        at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
        at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
        at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
        at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
    

    EDIT 5:55PM EST

    I've figured out that I can log with System.out.println("") and then see the results by running gradle testFlavorType --debug and by trial and error I've discovered the following weird situation:

    @Override
    public JSONObject buildBody() throws JSONException {
        System.out.println("buildBody mChannel = " + mChannel);
        System.out.println("buildBody mMessage = " + mMessage);
        JSONObject body = new JSONObject();
        body.put(JSON_KEY_TEXT, getMessage());
        body.put(JSON_KEY_CHANNEL, getChannel());
    
        if (body.length() != 0) {
            Iterator<String> keys = body.keys();
    
            if (keys.hasNext()) {
                do {
                    String key = keys.next();
                    System.out.println("keys: " + key);
                } while (keys.hasNext());
            }
        } else {
            System.out.println("There are no keys????");
        }
    
        return body;
    }
    

    For some reason, "There are no keys????" is printing out?!?!?!?! Why?!

    EDIT 6:20PM EST

    I've figured out how to debug unit tests. According to the debugger, the assigned JSONObject is returning "null". I have no clue what this means (see below). Since I think this is relevant, my gradle file includes the following:

    testOptions {
        unitTests.returnDefaultValues = true
    }
    

    It's especially strange because if I construct a JSONObject inside the test, then everything works fine. But if it is part of the original application's code, then it doesn't work and does the above.

    enter image description here

    Gaynor Valerianus 2022-08-20
    unit testing - Robolectric tests running in Android Studio but not on the command line

    I'm trying to run unit tests using Robolectric; they run fine under Android Studio, but the exact same tests fail when running in the command line - which is a big deal, I need to be able to run them from my continuous integration platform, not just from an IDE.

    I suspect that I'm missing some command-line argument (say, a classpath or something similar) or calling the wrong task - otherwise the test wouldn't run at all from Android Studio. Some relevant details; the test looks like this:

    @RunWith(RobolectricTestRunner.class)
    @Config(manifest = "app/src/main/AndroidManifest.xml", resourceDir = "res", emulateSdk = 19)
    public class SplashActivityTest {
    
        @Test
        public void testActivity() {
            SplashActivity splashActivity = new SplashActivity();
            String appName = splashActivity.getString(R.string.app_name); // HERE, line 20
            assertEquals(appName, "App");
        }
    
    }
    

    As mentioned above, it runs fine in Android Studio (by right-clicking the test file and selecting Run 'SplashActivityTest') but when running it from the command line it fails in the line marked with HERE, with the following stack trace:

    android.content.res.Resources$NotFoundException: unknown resource 2131492893
      at org.robolectric.shadows.ShadowAssetManager.getAndResolve(ShadowAssetManager.java:309)
      at org.robolectric.shadows.ShadowAssetManager.getResourceText(ShadowAssetManager.java:69)
      at android.content.res.AssetManager.getResourceText(AssetManager.java)
      at android.content.res.Resources.getText(Resources.java:240)
      at org.robolectric.shadows.ShadowResources.getText(ShadowResources.java:361)
      at android.content.res.Resources.getText(Resources.java)
      at android.content.res.Resources.getString(Resources.java:330)
      at org.robolectric.shadows.ShadowContext.getString(ShadowContext.java:39)
      at org.robolectric.shadows.ShadowContextWrapper.getString(ShadowContextWrapper.java:69)
      at android.content.Context.getString(Context.java)
      at path.to.myApp.activities.SplashActivityTest.testActivity(SplashActivityTest.java:20)
      // ... and so on ...
    

    I'm using this to run from the command line (notice that in here and in Android Studio I'm using the Gradle wrapper):

    project-root$ ./gradlew test --continue
    

    Also: I'm using Android Studio 1.1.0, Gradle version is 2.3, Robolectric's version is 3.0-SNAPSHOT and Robolectric's Gradle plugin version is 1.0.1

    Rupa Luned 2022-09-16
    c++ - Googletest for Android NDK

    I checked a previous answer about unit test for Android, where it is suggested Googletest as a good option. However, I got a look into the Google C++ Testing Framework - Googletest. About platforms, I don't see anything mentioning support to Android. Could someone tell anything, if there is some way of using it with Android devices - e.g. steps to build a toolchain, etc?

    Manu Signý 2022-09-02
    Android Unit Testing: Bundle/Parcelable

    How do you unit test Parcelable? I created a Parcelable class, and wrote this unit test

    TestClass test = new TestClass();
    Bundle bundle = new Bundle();
    bundle.putParcelable("test", test);
    
    TestClass testAfter = bundle.getParcelable("test");
    assertEquals(testAfter.getStuff(), event1.getStuff());
    

    I purposely try to fail the test by returning null in the createFromParcel(), but it seems to succeed. It looks like it doesn't get parceled until it's needed. How do I force the Bundle to..bundle?

    Iorwerth Endrit 2022-08-22
    unit testing - Is it possible to find out if an Android application runs as part of an instrumentation test

    Is there a runtime check for an application to find out if it runs as part of an instrumentation test?

    Background: Our application performs a database sync when starting. But that should happen only when started regularly. It especially interferes with the instrumentation tests testing the db sync. Not surprisingly.

    And with all the other tests it's just a waste of CPU cycles.

    Winnie Zubin 2022-09-07
    How to read a test-only file in Android unit test

    For my Android app I'm writing unit tests that require reading some files. Since those are test-only files I don't want them in my res folders as I don't want them to end up in my final .apk file.

    I want to do something similar to this question but using the newly added (in Gradle 1.1) unit test support (as opposed to instrumentation test).

    My project structure is as follows:

    /app
       /src
          /main
             /java/my.module/myClass.java
             /res/production_resources_go_here
          /test
             /java/my.module/myClassTest.java
             /resources/testFile.txt
    

    what should my myClassTest test look like to be able to successfully read the testFile.txt?

    Séafra Orvar 2022-08-25
    unit testing - android tests often stall at 'instantiating tests'

    When I click the run test button, Android Studio builds and attempts to run the test.

    70% of the time, it says "Instantiating tests..." and never goes anywhere from there. If I kill the adb-server, unplug adevice, or kill an emulator, the test suite magically runs fine.

    I even saw a bizarre behavior the other night. I unplugged the device while it said Instantiating Tests. Android Studio picked up that it disappeared. I pulled my phone out of my pocket a few hours later, unlocked it, and out of nowhere, it started running the test suite.

    Any idea what can cause this behavior? The closest I've found is Android Test stopping in instantiating tests, but that is referring to a different issue.

    Grażyna Jalil 2022-08-23
    JUnit testing for Android app with fragments

    My Android App was built on Single Activity, multiple fragments based model. I need to do unit testing for the app. I could write unit testcases for app which contains all activities using ActivityInstrumentationTestCase2 JUnit but not for app which contains fragments. Please suggest the way to write JUnit testcases for fragments.

    Thank you

    Furqan Terzo 2022-09-18
    java - Cannot mock final Kotlin class using Mockito 2

    I am unable to mock a Kotlin final class using Mockito 2. I am using Robolectric in addition.

    This is my test code:

    @RunWith(RobolectricTestRunner.class)
    @Config(constants = BuildConfig.class, sdk = 21)
    public class Test {
    
        // more mocks
    
        @Mock
        MyKotlinLoader kotlinLoader;
    
        @Before
        public void setUp() {
            MockitoAnnotations.initMocks(this);
        }
    }
    

    The test fails when we try to initialise the mocks in the setUp() method.

    In addition, I am using the following gradle dependencies in my code:

    testCompile 'org.robolectric:robolectric:3.3.2'
    testCompile 'org.robolectric:shadows-multidex:3.3.2'
    testCompile 'org.robolectric:shadows-support-v4:3.3.2'
    testCompile("org.powermock:powermock-api-mockito2:1.7.0") {
        exclude module: 'hamcrest-core'
        exclude module: 'objenesis'
    }
    testCompile 'junit:junit:4.12'
    testCompile 'org.mockito:mockito-inline:2.8.9'
    

    All other unit tests pass using this configuration but as soon as I try to mock the Kotlin class it throws the following error:

    Mockito cannot mock/spy because : - final class

    Please note I am using Mockito version 2 and I am using the inline dependency which automatically enables the ability to mock final classes.

    Laxmi Queenie 2022-08-29
    android - Cannot run gradle test tasks because of java.lang.NoClassDefFoundError: jdk/internal/reflect/GeneratedSerializationConstructorAccessor1

    I have an android project where I cannot run anymore all the test gradle tasks locally (I have 3 different flavors in this project). I have this error message 50 times before the tasks fail. I have no issue running these tasks remotely with Gitlab CI/CD, and I have another project locally where I don't have this issue neither.

    java.lang.NoClassDefFoundError: jdk/internal/reflect/GeneratedSerializationConstructorAccessor1
        at jdk.internal.reflect.GeneratedSerializationConstructorAccessor1.newInstance(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.io.ObjectStreamClass.newInstance(ObjectStreamClass.java:1092)
        at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2150)
        at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1668)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:482)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:440)
        at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.deserializeWorker(SystemApplicationClassLoaderWorker.java:153)
        at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:121)
        at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
        at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
        at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
    
    Grażyna Jalil 2022-08-24
    android - 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?

    Wangchuk Balduíno 2022-08-18
    unit testing - How do I get a jacoco coverage report using Android gradle plugin 0.10.0 or higher?

    I'm trying to get a test coverage report using Gradle Android plugin 0.10.2. But I still can't get a coverage report after running some tests. (connectedAndroidTest).

    my main module's build.gradle is :

    apply plugin: 'android'
    
    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.3"
    
        defaultConfig {
            minSdkVersion 8
            targetSdkVersion 19
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            debug {
                testCoverageEnabled true
            }
    
            release {
                runProguard false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:19.+'
    }
    

    and the buildscript section of project's build gradle is :

    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:0.10.+'
        }
    }
    

    Once I run a gradlew connectedAndroidTest from terminal, I can find coverage-instrumented-classes and code-coverage folder inside the build folder. But I can't find coverage folder in the reports folder. (Only I can see is androidTests folder)

    Is there anything missing for getting a jacoco coverage report?

    Orion Waman 2022-08-22