Self-contained test library project cannot find the library classes - android

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.

Related

Running AndroidTest on Library project not working anymore

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?

How to resolve java.lang.NoClassDefFoundError

I am using:
org.apache.commons.lang.builder.EqualsBuilder
in a in an Android library project (A) that in turn is used in another library project (B).
This works fine in the Android app that consumes library project B.
However, I have built an Android Test project to unit test the Android app - in particular the library project B classes. When doing so I encounter the following exception:
java.lang.NoClassDefFoundError: org.apache.commons.lang.builder.EqualsBuilder
I have included
commons-lang-2.6.jar
which contains the
org.apache.commons.lang.builder.EqualsBuilder
namespace in library project A build path for export.
I have searched SO for this issue and found a number of posts on the NoClassDefFoundError, but none that have a situation with unit testing.
I found the answer. After reviewing this article, I realized that I needed both the jar from project A and the commons-lang-2.6.jar in the test project. Adding BOTH jars to the build path and export resolved the issue.

How to test an android library?

I am writing an android library project and trying to test it. I found testing a library project
more difficult than it has to be using my current method.
Right now, I am exporting the library project into jar file. Then I put it into the libs folder of the test project and the test target project. Then I add it to build path of both projects and run the test.
Every time I make a change to the library I have to do this again. Is there easier way to do this?
There is some reference to this in the google docs. Check out http://developer.android.com/tools/projects/index.html#testing
Basically, the easiest way is to write an application that uses the library project and then add unittests to that application.
When creating the tests via eclipse, you can choose to test modules from within your library project. This way, changes to the library project are automatically applied.

Does slicing a large Android project into Android libraries improve build time?

I have a rather large Android project, and it takes considerable amounts of time for the sdk to do the resource-parsing / dexing / etc. I'd like to improve this somehow.
I've read that Android library projects can contain resources now too. So we can also put Activities, Fragments, etc. in them.
Does this mean, that if I export parts of my large project into library projects which I reference from the main project, then I don't have to rebuild the already built (and not modified) libraries again, when I rebuild the main project? So I only have to do the resource-parsing / dexing / etc. for the modified libraries and possibly the main project, decreasing the overall build time in most cases.
Does this mean, that if I export parts of my large project into library projects which I reference from the main project, then I don't have to rebuild the already built (and not modified) libraries again, when I rebuild the main project?
Partially no, Android Library Project is not built directly, it is always built along with the dependent Main Project, when SDK compile/build the Main Project, SDK tools compile the Library Project into a temporary JAR file and uses it in the main project. whenever you re-build your Main Project, the referenced Library Project is re-built as a part of main project build life cycle, even though nothing changed in Library Project. Check out timestamp of the temporary JAR generated under your app-lib/bin folder for evidence, it always get changed every time yo build Main Project.
Quoting from official dev guide:
However, a library project differs from an standard Android application project in that you cannot compile it directly to its own .apk and run it on an Android device. Similarly, you cannot export the library project to a self-contained JAR file, as you would do for a true library. Instead, you must compile the library indirectly, by referencing the library in the dependent application and building that application.
When you build an application that depends on a library project, the SDK tools compile the library into a temporary JAR file and uses it in the main project, then uses the result to generate the .apk. In cases where a resource ID is defined in both the application and the library, the tools ensure that the resource declared in the application gets priority and that the resource in the library project is not compiled into the application .apk. This gives your application the flexibility to either use or redefine any resource behaviors or values that are defined in any library.
Android Library Project is different from regular java library project. where you can compile and build everything into and jar library once, and start import/use the class from reference jar dependencies in main project. Currently Android Library Project is designed on source-based mechanism, not compiled-code based library mechanism, as mentioned in this Android blog, although self-contained jar distribution is promised in future release (unfortunately not in neither r15, r16, r17 nor r18 yet).
Yes... The build system rebuilds what needs to be built unless you build Clean.
I wouldn't expect huge time savings here.
In my experience, the slowest step of compilation is actually the dexing of the output files, which can not be performed incrementally, so moving your code into libraries will not speed things up. Similarly, incremental compilation (when it works — it often doesn't with the Android toolchain) will work equally well with unchanged files spread over a bunch of projects as will unchanged files in a single project.
Of course, the best way to find the answer for your actual use case is to experiment on your actual code base. And there may also be code maintainability benefits to splitting your project up into independent modules.

Android Test Project with external libraries in ADT17

I've a main project that depends on other Library projects that use external JARS (that are also used in the main project).
Now with ADT17 I have removed from the main project the external libraries that are also used in library projects, because they are automatically inherited from new AD17 Android dependencies (from library projects).
Until here all works correctly. The problem is when I want to create a Test project for the main project. What I do is mark all externals jars and android dependencies as exportable to be inherited in the test project.
But the problem is that Android dependencies although they are market as exportable aren't inherited from the test project and when I run it I get some Link of class X not found... make sure it's in the apk.
I attach an image to make it more clear:
(It's an snapshot from main project libraries. Blue marked ones are correctly inherited and red ones not).
It seems that it was a bug in ADT17 with test projects that depend on external libraries.
Today I've updated to ADT18 and it works correctly without having any lib defined in test project.

Categories

Resources