I am writing an Android Library Project basing on Android Bitmap class (call it AndroindLib) which contains only utility class (no activity). I tried to test it using Android JUnit, but it keeps complaining that can't find the AnroidLib.apk
What's the right way to Unit test Android Library Project?
Quoting the documentation:
"There are two recommended ways of setting up testing on code and resources in a library project:
You can set up a test project that instruments an application project that depends on the library project. You can then add tests to the project for library-specific features.
You can set up a standard application project that depends on the library and put the instrumentation in that project. This lets you create a self-contained project that contains both the tests/instrumentations and the code to test."
In your test project simply change the package name so that it's the same as your library's package.
For example, you have a library whose package is "com.example.lib". Create a test project targeting your library. In the manifest file you'll see package="com.example.lib.test", and targetPackage="com.example.lib". Just change the package from "com.example.lib.test" to "com.example.lib" (targetPackage leave as is).
Also, make sure that the library is referenced to your test project NOT in Java build path, but as a usual Android library : in Eclipse it must be shown as library in Project->Properties->Android tab, but not in Project->Properties->Java Build Path tab.
Then run you tests.
Per the documentation:
Testing a library module is the same as testing an app.
The main difference is that the library and its dependencies are automatically included as dependencies of the test APK. This means that the test APK includes not only its own code, but also the library's AAR and all its dependencies. Because there is no separate "app under test," the androidTest task installs (and uninstalls) only the test APK.
When merging multiple manifest files, Gradle follows the default priority order and merges the library's manifest into the test APK's main manifest.
NOTE: This solution is based on using Eclipse Indigo (3.8.2) and might have to be implemented slightly differently for another IDE although the basic principles will be the same.
I had similar issues and I found that do the following always works:
(NOTE: These instructions are for building a new project group from scratch. If you have already built parts of the project group, then you may have to modify your projects so that they connect in the same way.)
Create a new Android Library project by checking the "Is Library" checkbox during creation. (for example an Android project named "RemingtonAndroidTools").
Build the Android Library project and verify that it created a jar file in the bin folder. (for example a jar file named "RemingtonAndroidTools.jar".)
Create an empty Android Project for testing the Android app that will serve as an Android Test App. (For example an Android project named "RemingtonAndroidToolsTestApp"). You will not need to modify the source code or resources of the Android Test App project unless you have something that must be added for testing. Many things can be tested without any modifications to the Android Test App Project. The Android Test App project is a bridge between your Android Library project and the Android Junit project that makes testing of the Android Library project via Android Junit possible.
Go the Library tab of Java Build Path for the Android Test App project ("RemingtonAndroidToolsTestApp" in this example).
Add the jar file ("RemingtonAndroidTools.jar" in this example) of the Android Library Project ("RemingtonAndroidTools" in this example) via the "Add Jars..." button.
Create a new Android Test project (for example "RemingtonAndroidToolsTester") that will serve as an Android Library Tester and select the Android Test App project ("RemingtonAndroidToolsTestApp" in this example) as the target.
Go the Library tab of Java Build Path for the Android Library Tester project ("RemingtonAndroidToolsTester" in this example).
Add the jar file ("RemingtonAndroidTools.jar" in this example) of the Android Library Project ("RemingtonAndroidTools" in this example) via the "Add Jars..." button.
Find the last folder of your Android package in the Android Library Tester project ("danny.remington.remington_android_tools_test_app.test" for example) and add a test class ("MainActivityTest" for example) that inherits from ActivityInstrumentationTestCase2.
Edit the test class ("TestActivityTest" in this example) to use the activity (for example "TestActivity") of the Android Test App ("RemingtonAndroidToolsTestApp" in this example) as the parameter for ActivityInstrumentationTestCase2.
Edit the test class ("TestActivityTest" in this example) and create a default constructor that makes a call to super(Class) and passing in the class of the Android Test App ("TestActivity.class" for example).
You should end up with three projects (Android Library, Android Test App, Android Library Tester) that look similar to this:
You should end up with a class for testing your Android Library that looks similar to this:
package danny.remington.remington_android_tools_test_app.test;
import android.test.ActivityInstrumentationTestCase2;
import danny.remington.remington_android_tools_test_app.TestActivity;
/**
*
*/
public class TestActivityTest extends
ActivityInstrumentationTestCase2<TestActivity> {
public TestActivityTest() {
super(TestActivity.class);
}
}
You can then add any test that you want. You will not need to reference the Android Test App ("RemingtonAndroidToolsTestApp" in this example) further to run your tests unless they require access to an Android specific component (like the Assets folder, for example). If you need to access any Android specific components you can do so by modifying the Android Test App ("RemingtonAndroidToolsTestApp" in this example) and then referencing it via the instrumentation provided by the standard Android Junit API. (You can read more about that here: http://developer.android.com/tools/testing/testing_android.html)
If your ulitiy classes do not depend on any android specific code, you can just use standard JUnit unit tests. No need to use the Android versions.
Related
I want to make a separate module so I can share it between projects. The module is going to have android components. So upon creating a new module the options are Phone & Tablet module and Android Library. I wanted to know what's the difference between the two. thanks
What is Module? From the Add a Module for a New Device documentation:
Modules provide a container for your app's source code, resource
files, and app level settings, such as the module-level build file and
Android manifest file. Each module can be independently built, tested,
and debugged.
What is Android Library? From Create an Android Library documentation:
An Android library is structurally the same as an Android app module.
It can include everything needed to build an app, including source
code, resource files, and an Android manifest. However, instead of
compiling into an APK that runs on a device, an Android library
compiles into an Android Archive (AAR) file that you can use as a
dependency for an Android app module. Unlike JAR files, AAR files can
contain Android resources and a manifest file, which allows you to
bundle in shared resources like layouts and drawables in addition to
Java classes and methods.
You can't access the components from one module to another module.
So, if you need to share components between projects, you need to create Android library. But please remember, you can't run the library. You only can access and use it from the module. Furthermore, you can use Gradle Android Maven plugin to install your library locally.
Check the official doc
Resume:
Modules provide a container for your app's source code, resource files, and app level settings, such as the module-level build file and Android manifest file. Each module can be independently built, tested, and debugged.
Android Studio uses modules to make it easy to add new devices to your project. By following a few simple steps in Android Studio, you can create a module to contain code that's specific to a device type, such as Android Wear or Android TV. Android Studio automatically creates module directories, such as source and resource directories, and a default build.gradle file appropriate for the device type. Also, Android Studio creates device modules with recommended build configurations, such as using the Leanback library for Android TV modules.
Currently I am working on creating test cases for my Android project which used Another Android project as Android Library project. In my Android project I didn't do any business logic I have done all logics in my Android Library project,So I just extends my activity into Android library Project Activity. I have written separate Test classes for each Activity in Android Library.If I run each test class It will pass in test.How can I test the whole Android Library Project? and also Android application project?. If I accessed any Android Library project's test class(AndroidLibraryProject/src/androidTest/java/packageName/testCase.java) in my Android Application Project it showed does not exist error message while run the class.How can I test whole project both Android application project and Library project
When you run unit-test on project (module ":app") which use another projects as library, it automatically run test on module project/library project.
So write tests for both, try letting tests for library projects at
AndroidApplicationProject/src/androidTest/java/packageName/
(not AndroidLibraryProject/src/androidTest/java/packageName/)
My desired end result is to have a Project that can output different productflavors of Mobile, Tv, and Wear apps, that share the same code-base. So I would like the codebase to be a dependency for all three app-types, where each app module would only contain activities and interaction with the codebase.
My first idea was to add a "Android Library Module" to my newly created project, but I noticed that this is really just a new app module with its own resources and everything. I would like the codebase to function more like a "Java Library", but it needs access to packages like "android.graphics.Color".
So in short, is the correct way of achieving this result to use a java library that has a reference to an android sdk or am i just going about this the wrong way?
Continuation of this question at:Does an Android Library need a manifest ,app_name,Icon?
There's no in-between. If you want access to Android APIs, then the library needs to be an Android library so that the build system can properly link it in to dependent projects. It's true that Android Libraries have resources and other things you may not need, but you can ignore those bits and treat it essentially as a plain Java library if you wish. Even if you're not using resources, you may find useful the ability to specify AndroidManifest.xml attributes to be merged into the dependent app.
The Android Library project doesn't build a fully-fledged APK as its output; it generates an AAR, which is conceptually similar to a JAR archive, but has resources and meta-information useful to Android projects.
Supplemental answer defining terms
The Android Studio documentation defines a module as follows:
A module is a collection of source files and build settings that allow
you to divide your project into discrete units of functionality. Your
project can have one or many modules and one module may use another
module as a dependency. Each module can be independently built,
tested, and debugged.
So basically a module is a subproject in your bigger project.
Types of modules
Android app module - The app module is usually what you are working with in a normal project. When you compile it you get an APK file that will run on a device. Here are the different types of app modules that exist:
Phone & Tablet Module
Android Wear Module
Android TV Module
Glass Module
Library module - The purpose of a library is to share code. For example, you could have a project with a couple different app modules. The common code that they both use could be located in the library.
Android Library - In addition to Java code, this allows you to also include Android resource files and a manifest. If you are making an Android project and are wondering what kind of library to use, then choose the Android Library. When compiled it creates an AAR (Android Archive) file.
Java Library - This only allows you to include Java code files, no Android resource files. This is useful for cross-platform code sharing. When compiled it creates a JAR (Java Archive) file.
Google Cloud module - This type of module is the Google Cloud backend for communication with your client side app.
One additional point that I've not seen well documented: An android library module can have a dependency on another android library module or java library module, but a java library module cannot have a dependency on an android library module.
In the Android LunarLander sample project, the unit tests are included right in the project, in a (non-source) folder called 'tests'. This is in line with the SDK testing guide which recommends this layout as opposed to creating tests in a separate project. However, I have no idea how I can actually run these tests.
I can't create an Android Junit Test run configuration:
if I try to 'run all test in project or package' it complains that manifest file doesn't contain instrumentation info - clearly it's using the top-level manifest file instead of the tests manifest file.
if I try to 'run a single test', I can't find any because tests isn't a source folder, and if I set it as a source folder, errors pop up, since it assumes the test class should be in a package starting with 'tests.src'.
It's starting to seem to me that this sample is broken... I hope I am wrong, since I'd rather embed tests into my project and be able to run them easily (instead of creating a separate test project that links to project for application under test). Does anybody know how I can run these tests? Thanks...
Google recommend a single all-in-one directory because it makes your files easy maintainable in many situation, for instance when dealing with source control.
It doesn't matter where the test project is located int the file system, however, you must import it into your Eclipse's workspace, same as what you did for the LunarLander project:
If everything goes well, your Package Explorer should look something like this:
In my Android 4.2 samples, things are not going well, it seems that the source code of LunarLander test project is not up-to-date:
it doesn't come with project.properties file.
it uses same package name as LunarLander project, resulting Eclipse to be fooled when importing package/class from the referenced LunarLander project.
it doesn't automatically add the LunarLander project to test project's classpath, resulting imported package/class from the referenced LunarLander project is invisible.
Once you resolve all issues, you should able to run/debug Android JUnit Test from test project.
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.