While migrating our build tool to Buck, we stumbled upon the following issues for the unit tests in Android:
Our tests for the view model need to access R.java for asserting the right resources are referenced.
We used the java_test rule but it seems R.java is not found. There is a robolectric_test which builds the .apk but we just want the R.java file in the classpath for the unit tests.
Is there a reason there is no android_test rule.
Any plans of doing so?
We explored the code and looked that we need to see the AndroidLibraryGraphEnhancer and build the Android resources.
Any recommendations?
No plans for adding such rule because it's not clear what it supposed to do and why robolectric_test is not enough.
Buck doesn't build an apk for Robolectric tests.
You really don't want to use java_test to test Android code because Android SDK and Java SDK are different. You have to test Android code with robolectric_test because it uses Android SDK.
Related
I have several tests in common module for multi platform Kotlin project. When I execute those tests using gradle, e.g. ./gradlew :android:test, they all go through and the tests run.
I have now encountered a more complicated problem where I would like to debug an actual test in IntelliJ. Unfortunately, upon selecting the debug option in IntelliJ, I get an No JDK specified error.
I am using the following dependencies for testing:
testImplementation "org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlin_version"
testImplementation "org.jetbrains.kotlin:kotlin-test-common:$kotlin_version"
with $kotlin_version being 1.2.41.
The common module settings looks like this:
SDKs section also correctly recognises JDKs:
I have tried changing the Module SDK from Kotlin SDK to java, however IntelliJ then wants me to require jUnit for test execution, which I would prefer not to, if possible.
Is there a way how to make the debugger run in IntelliJ for the Kotlin code?
Found the solution.
Just like it does not make sense to execute tests using Gradle in the common module alone, e.g. ./gradlew :common:test and the tests need to be executed for a specific platform ./gradlew :android:test, because the common module might contain expected declarations which are supposed to be implemented per platform using the actual keyword, it also does not make sense to debug in the common module directly.
Instead, for such purposes, the test to be debugged must be placed in a specific platform module, for my purpose I have chosen the Android module, and then it can be executed and debugged.
As I have mentioned, this approach is necessary because in the Android module the expected structures are actually replaced by the actual implementations.
I have multiple feature modules in my instant app project structure. All of my resources which are being used in the multiple features are residing in my core module.
Assume my core module package name is com.andorid.myapp.core.
And I have a feature1 module with package name com.android.myapp.feature1.
Now If I am using any resources from core module into the feature1 module, I am referencing it with simply R.string.something_from_core and studio doesn't complain anything even I have imported com.andorid.myapp.feature1.R not com.android.myapp.core.R it just works fine. But when I run ./gradlew assemble, It doesn't build successfully and throws an error which says the R.string.something_from_core doesn't exist.
Now my 100s of my project files are using resources from core and I am not able to find which resources are coming from core and which are from feature1 because studio is not complaining anything while writing code it just works. And also the build is only breaking when it tries to run build variants like assmbleFlavourFeature, rest everything is working fine.
So confused with no solution, would be great if someone can help.
Seems there is a problem with cache.
Try my answer here :
My answer
Hope this helps.
I recently updated my original Android project and moved some files into new packages for better organisation.
Prior to updating my project packages, I had created an Android JUnit Test Project which I had linked to some intern packages representing my applications Model. All of my Test Cases were passing.
Upon moving some of my classes into new sub-Packages, my tests are now failing with a NoClassDefFoundError, which is appear because the simple relocation of my classes into new packages.
I reworked my TestCase classes to update the modified include statements, removing all reference errors that emerge upon re-packaging.
I then deleted the tests Run Configurations in hope that when I re-ran the tests this would resolve any build paths errors, but it has not resolved the issue.
I am fairly new to JUnit Testing and I'm sure that there is some simple fix, but I can't figure it out.
I've looked at some other questions, but the ones that seem semi-related are using libs and jars, not simple internal package changes.
My packages changed from:
app.model
To
app.model.app
NOTE: When I run the Android Project, the app works fine (the repackaging hasn't effect the application). It is as though the test project is pointing to the old .apk and not the new .apk
An explanation of how to resolve this issue would be appreciated. I am interested in growing my understanding of Android JUnit Testing.
Thanks!
I'm a long time Java developer with many years of Java EE, Ant, Maven, unit testing, mocks, etc. I'm currently using gradle to build android apps and am looking at unit testing them. And it's got me tearing my hair out!
My reading indicates that to test an app, I have to create another app inside it in a test directory. But I'm not sure how this embedded app can see the main apps classes. I presume that google came up with this because of something to do with the manifests which are different. I'm not sure why.
Without doing this embedded app system, I've been able to get unit tests to run by including the test classes with the main classes in the APK, adding the instrumentation declarations to the manifest, deploying it and running the test runners. But I don't want to be compiling test classes with app classes and including all the dependencies so that's not really an option and I'm not really sure of the effects of the changes to the manifest as I cannot find any documentation about the effects.
None of this is understood by gradle which follows the maven system of building. Also note that the android way seems to be that the embedded sub-project (test) is dependant on the main parent project, something that is totally contray to gradle and maven.
Another option seems to be separate the test project so that it's completely outside the app project. But really, I'd like to use a similar convention to maven and simply have tests in a separate directory, along with the manifest in test resources.
Has anyone managed to get testing on the emulators running unit tests following a more maven like directory structure?
You can try Robotium. It provides lots of features for a better testcase. You can have a look at it here.
Do you have to run the unit tests in the emulator? Isn't that too slow? I've been using robolectric ( http://pivotal.github.com/robolectric/ ) which creates shadow objects that work similar to mocks. I use progaurd ( http://proguard.sourceforge.net/ ) to strip out the tests for the release build.
According to this SDK guide, unit-testing a Library project can be achieved by creating a standard application project, reference the Library project and then instrument the application for unit testing.
However, when I do this and launch the test application I get the message
No tests found with test runner 'JUnit 3'.
I'm using Eclipse and the Android ADT plugin, all latest versions.
Note: the projects compile just fine. The test project also installs fine to the emulator. But in the console I can see that it looks for <library>.apk, which of course doesn't exist since I'm compiling this as a library into the test project.
Anyone got this to work? And if so, what is the trickery here?
Update: after discovering and fixing a problem, which was actually including the test classes (!), the test runner now can find all tests. But, all the tests fail with the following exceptions:
java.lang.NoClassDefFoundError: <nameOfClassInLibraryProject>
nameOfClassInLibraryProject are classes defined in the library project. These classes should be compiled into the test project, and indeed, everything compiles just fine. But when running the test project, the runtime doesn't seem to find the library classes.
After much fiddling and wasted time in Eclipse I have managed to get Android Library projects to work.
According to the Working with Library Projects article:
Instead, you must compile the library indirectly, by referencing the library from a dependent application's build path, then building that application.
The problem was that I interpreted this to mean that the library project should be added to the Projects tab in Java Build Path. Doing this makes the test project compile since the library code is obviously available to the compiler. But since the library is not compiled into a .jar or .apk in itself, the library classes are never deployed to the device.
The solution is to not add the library project to Projects, rather on the Source tab, add the library /src folder using the Link Source... button. And yes, it is the library src folder, not the library project root, that must be linked into the test project.