Android sharing generated code between test and androidTest - android

I'm trying to share some code between my unit tests and my instrumentation tests. I've implemented something like the following in my build.gradle:
sourceSets {
String sharedTestDir = 'src/sharedTest/java'
test {
java.srcDir sharedTestDir
}
androidTest {
java.srcDir sharedTestDir
}
}
This seems to work just fine for normal code. However, code that is generated from an annotation seems to produce problems in Android Studio only. (The code runs fine, but it produces red squiggles in Android Studio) Basically, Android Studio can't seem to find the generated classes for code that lives in src/sharedTest - even though the actual build is fine.
In case it's helpful, the generated classes are coming from Dagger (as I share a component/module between the two types of tests). I've got a custom Application object that lives in sharedTest which is where I notice the Android Studio error:
createApplicationComponent() {
return DaggerMockApplicationComponent.create();
}
I've also added the apt command to both test and androidTest:
dependencies {
testApt 'com.google.dagger:dagger-compiler:2.7'
androidTestApt 'com.google.dagger:dagger-compiler:2.7'
}
I'm clearly missing something in my understanding around source sets here. Is there a cleaner way to share the code between test and androidTest? Is there a way to get Android Studio to see this generated code? Or, worst case, can I make Android Studio at least ignore this error more easily?

Related

Android: Sharing test code across modules

I'm having issues sharing code across different modules for testing my app.
I have a couple of classes (TestCoroutineContextProvider and CoroutinesTestRule) which I have placed in my presentation fragment.
In order to share the code between unit tests and UI tests, I have in my presentation build.gradle the following:
sourceSets {
test {
java.srcDirs += "$projectDir/src/testShared"
}
androidTest {
java.srcDirs += "$projectDir/src/testShared"
}
}
This way I think I can have access to those two files in both my ViewModel and Fragment tests.
Nevertheless, although the files are imported correctly and there's no IDE error, when trying to run the tests I get the following:
e: /features/account/src/test/java/me/myapp/account/AccountViewModelTest.kt: (35, 30): Unresolved reference: CoroutinesTestRule
and the same thing for the other file.
Am I doing something wrong?
Thanks a lot in advance!
You need to do the following to share the code across unit tests and instrumented tests:
In your app level build.gradle file, add the following:
sourceSets {
// Share test utils between unit and instrumented tests
test.java.srcDirs += 'src/sharedTest/kotlin'
androidTest.java.srcDirs += 'src/sharedTest/kotlin'
}
where sharedTest is the directory / module name where the shared utilities will go in
Go to your module in which the build.gradle is located then navigate to src and create a directory named sharedTest and inside it create kotlin
Mark the kotlin directory as "Test Sources Root" by right clicking -> Mark As -> Test Sources Root so the IDE shows it as a test directory
Put your test utils in there
Do gradle sync
Enjoy!
Note: Even after this sometimes IDE shows errors / warnings when you try to use those shared utilities but if you run those tests, they will pass also when executing via gradle. Usually I have seen this problem to disappear after doing a gradle sync or re-launching Android Studio

androidTest not compiling, showing cannot resolve symbol

I'm trying to add instrumented test using Espresso in my android project.
I've added all necessary libs, besides adding AndroidJUnitRunner as the testInstrumentationRunner:
But for some reason, the imports are not working in instrumented test file:
But the local test file is getting the imports properly:
I've also added junit as androidTestImplementation, but makes no difference:
androidTestImplementation 'junit:junit:4.12'
This is why I cannot run the test file.
If I run the file anyway, I get this error:
Process finished with exit code 1
Class not found: "com.mcp.shippax.MainActivityEspressoTest"Empty test suite.
I cannot understand why this is happening (numerous grade syncs/invalidate caches/restarts), when the setup is so straight and simple.
I don't remember making any project changes other than converting most of my source files to Kotlin, including the test files. But later I reverted the test files back to java again.
I had the same issue. I've had various build types for dev and prod environments and what helped me, was to specify testBuildType like in this answer https://stackoverflow.com/a/34778780/9736105.
So something like this:
android {
...
testBuildType "<my-build-type>"
buildTypes {
<my-build-type> {
...
}
....
}
}
After I did that and set my build variant to that build type, I was able to resolve all dependecies.

Android Studio can't see dagger 2 test component

I` am trying to create some extra Dagger 2 modules for android instrumental tests. And Dagger 2 files are generated successfully, but my Android Studio IDE can't see it. I tried to use android-apt plug-in, gradle-apt-plagin and native android annotation processor. Nevertheless, nothing worked. However gradle 2 file for debug or prod application working fine.
For test module and component I use some custom sours folder:
def commonTestDir = 'src/commonTest/java'
test {
java.srcDir commonTestDir
}
androidTest {
java.srcDir commonTestDir
}
I use all of compile/apt, testCompile/testApt, androidTestCompile/androidTestApt for daggger 2 declaration in build.gradle file.
p.s. I`am sorry for my bad english...

Configure test folder for unit testing in Android studio

I have added a folder for unit testing in my android studio project. The default folder is andoidTest but I have added a new folder and name in test instead. (like robolectric sample tests)
When I add test Dependency in my build.gradle under module such as
testCompile("junit:junit:${junitVersion}")
testCompile ("org.robolectric:robolectric:${robolectricVersion}")
They do not get added to external libraries under project, but when I use the default configuration and use androidTestCompile, it can added external libraries.
Then I thought that maybe I should setRoot for tests in gradle, so I used following in android tag in build.gradle:
sourceSets {
androidTest.setRoot('src/test')
}
But still problem remained. I can run tests using gradlew, but imports in classes in test folder do not apply as well as no external library for test purpose is visible.
Anyone have any solution for this issue?
I was searching and didn't find answer that I thought already covered this. So decided to create new one for the future.
Answer
Android Studio is not picking up unit tests automatically right now. I know it is planned for 1.3 version.
So you have to change test artifact value from Android Instrumental Tests to Unit Tests in Build Variants tool window:
Almost fine your Gradle script but try do that:
sourceSets {
androidTest.setRoot('src/test')
androidTest {
java.srcDirs = ['src/test/java']
}
}

How to add a new source directory to an Android Studio project?

So ultimately I'm trying to separate my integration tests from the unit tests in an Android Studio project. I've found a few resources on the subject:
http://selimober.com/blog/2014/01/24/separate-unit-and-integration-tests-using-gradle/
https://blog.safaribooksonline.com/2013/08/22/gradle-test-organization/
Separating integration tests from unit tests in Android Studio
All these seem to indicate that the way to go is to create a new sourceSet for the integration tests, and then to create a new test task which builds and runs the tests in that source set. I can't get past the first step of creating a source set which is recognized by Android Studio.
Here's what I have within app/build.gradle, which builds without errors, but does not result in an integrationTest source root I can add classes to:
android{
...
sourceSets{
integrationTest {
java.srcDir('src/integrationTest/java')
}
}
}
My questions are:
Where precisely do I have to add the sourceSets block? In build.gradle? in app/build.gradle? In app/build.gradle inside the android block?
Once I've added my source set in he right place using the correct syntax, is this sufficient for Android Studio to detect and present it in the UI along side the main and test sources, or are there additional steps?
edit:
I've attempted to follow the instructions in marius' answer, but integrationTest isn't showing up in my build variants. Here's what I'm seeing:
This is enough:
android{
...
productFlavors{
integrationTest {
}
}
}
Regarding your 1st question: The productFlavors block should be in your app/build.gradle, inside android block.
Regarding your 2nd question: Once you add this to your build.gradle file, you also need to create your folders /src/integrationTest and /src/integrationTest/java . Once that is done, sync your gradle files and choose your new Build Variant from the Build Variant window, in order for the IDE to detect it as the active source folder.

Categories

Resources