I'm trying to get Robolectric up and running by following thecodepath tutorial on github. However, when running the test, eclipse tries to download org/robolectric/android-all/4.3_r2-robolectric-0/android-all-4.3_r2-robolectric-0.jar. What exactly is this 30+ mb .jar file for? Is it supposed to replace the android.jar file from the tutorial?
Let me first ask а question: Why do we need Robolectric for unit testing Android?
And the answer is that android.jar is shipped with contracts of classes and utilities methods only. That means every method, every function and constructor in this jar just have one line of code:
throw new RuntimeException("Stub!");
You can only compile your code against this jar and never run on a desktop JVM. If you try to run then you will get an exception thrown as soon as you try to instantiate an android class or call any android utility method.
Robolectric tries to solve this problem. From the beginning it customises ClassLoader and every call to the android code is replaced with a Robolectric implementation. That gave us possibility to test our code on desktop JVM. But that is quite hard to re-implement whole android as well you trap in situation when you test against something different that is present on devices.
So the strategy was changed from Robolectric version 2. It tries to use as much as possible android source code which is open sourced from the beginning. That is why the first run of your tests Robolectric downloads and caches own android.jar which is compiled from android sources. It is done to make sure that our tests environment behaviour is close to behaviour that we have on the devices.
I would recommend you to read more about Robolectric on their blog, google group. As well you can find plenty of presentations on slideshare and youtube about it. And I encourage you to contribute to Robolectric project on github as soon as you are confident with it and want to give back your gratitude to the community.
I had the same problem when I was trying to set up Robolectric for the first time. The reason for my problem was, my project src files were in the package:
com.example
But my test files were not inside a package. When I moved my test files to:
com.example
The problem got resolved. I hope this might help.
Related
Trying to develop android LPA system app for eSIM with the new Pie API.
The doc says to extend the abstract EuiccService class. But this class is not in the official SDK, and the link in the docs just leads to corresponding file in the android source repo.
I tried using this file/class as a dependency, but it references other internal android classes/annotations and causes build/IDE errors.
Does anyone have an idea how to use this?
Do I really have to pull android src code and somehow reference required class from it?
EDIT: I think I've solved it, found couple of potential solutions, but they were a bit cumbersome. Used the android.jar from here: https://github.com/anggrayudi/android-hidden-api (contains modified android.jar with hidden APIs and internal resources). It didn't work when i replaced the whole file and resulted strange build errors, but i manually transferred the android\service\euicc\ folder to original android.jar of android-28 sdk and it works perfectly (class is available and apk builds without issues). And no need to waste time pulling and building AOSP.
EDIT #2: apparently not fully fixable atm. There's issue with android gradle plugins (at least 3.2.x-3.3.x) where during full sync some build task generates mock classes from android.jar and process fails if it's modified (discussion is here: https://github.com/anggrayudi/android-hidden-api/issues/46). Error looks like this:
Failed to transform file 'android.jar' to match attributes {artifactType=android-mockable-jar, returnDefaultValues=false} using transform MockableJarTransform
There's a workaround for that, though inconvenient:
when you need a full sync for the project, replace the android.jar with original, run sync, restore modified android.jar, the IDE now will run indexing and classes will be available again with build working until next full sync.
Will update this post if/when it's fixed or new solution is found.
EDIT#3: here's probably a final solution for EuiccService case (turned out pretty obvious):
Instead of adding 'android/service/euicc' folder to android.jar, just put it in a separate library and add it as a compileOnly dependency. Since the classes were not in the SDK, the lib should not cause conflict (would be the case if you need to use modified framework or access hidden APIs in already existing classes).
If you are going to create a System APP, you will do it in several ways:
You could call a part of the SystemAPI (a method for example) by reference.
You could make the aplication as a part of the AOSP Project (Downloading the AOSP code, and introducing your app as part of packages/apps/)
You will be able to access system APIs on a rooted device or if you have system permissions (this happens when you flash your app into the device as part of the system image).
However, if you want to be able to call the EuiccService class from Android Studio (for coding purposes), you'll need to add the Android framework jar to your project.
The steps are provided below:
First, you will have to download and build AOSP and generate a framework jar for your target Android version. Check the documentation here to get an idea of how to download and build AOSP.
After a successful build all framework classes are compiled into a jar called classes.jar which can be found at the location out/target/common/obj/JAVA_LIBRARIES/framework_intermediates.
Get this classes.jar and add it to your Android project as a jar file.
Gradle sync the project and start coding.
Please beware that you WILL NOT BE ABLE TO run this app on an Adnroid device where you do not have system permission for this app.
I have been using android studio for some time.(still learning) and till date i haven't used the java files in the test folders. i.e the one's marked here :-
Is it necessary for a project or can we just delete those files?
If it is necessary, what is its use and how can we use it ? (any reference would be great).
If anyone could rephrase the question in a better way,it would be better.
Those are for tests. The androidTest is for instrumented tests while the test folder is for unit tests. You could delete them if you do not plan on using it, but it also does not harm your project.
See here Test Your App
I do have a project with an app and a library module that contains JNI code. I added a test class to the 'androidTest' folder in order to test all this in a device environment.
At the time doing, Android Studio 2.2.2 was able to identify the code as test (adding all the nice icons to run the whole class test and so on).
Now (a large number of commits and git rebasing later) I want to do some more work, but Android Studio refuses to accept the code as test code, although gradle itself (invoked with :libname:connectedAndroidTest) does perform the tests and writes timing info into some XML in the ./build/outputs/androidTest-results/connected of the library module folder.
The AS editor marks all unit testing related imports in red. When I try to resolve the "problem" AS suggests to "Add library 'runner-0.5' to classpath" although build.gradle already contains that reference.
AFAIR I was also able to select the library module in the "Module" setting in the General tab of the Android Test run configuration. But that doesn't work anymore.
What puzzles me is, that I some had this all working from within the IDE and now it doesn't work anymore. Although the gradle call will still run the test cases that the compiler doesn't complain about anything...
Any ideas anybody?
PS:
I do know that I can move the "androidTest" code into a differen module. However I do already have 10+ modules in my project. And since gradle is able to run the test, why is Android Studio not anymore?
I've been working on getting unit testing to work with a custom Android library. I've followed the first suggestion from this Android developer guide and created an Android app project that depends on the library (via Properties->Android->Library->Add...) as liaison to the actual testing project.
All seemed to work fine, but then I encountered my first run-time-exception in one of my test cases. When I wanted to fix the code in my library, I found, that double-clicking any item in the JUnit test panel would open a .class file, instead of the corresponding .java file. So editing the code is not possible, until I've crawled though the package hierarchy and grabbed the .java file manually.
Also, the debugger/test-runner is happily ignoring any breakpoints in the library. Is there a way to make the test project realize, that the code for the library is right there in the workspace? Not having the abilities to debug using breakpoints and jumping from a stack trace into the code are big productivity bummers.
Addendum: After leaving Eclipse and starting another session, now breakpoints seem to be respected. However, the debug-perspective will open the .class files instead of the corresponding .java files.
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.