Automated unit testing for Android / Ant - android

I have an Android project and JUnit tests in my code.
I wanted to know if there is an ant task to run some tests.
In fact, I have several classic tests which are run using JUnit to test several methods, and some tests that need an android emulator or at least need to be run on an android device.
As I didn't find any documentation, I wanted to know if it's possible to do that kind of thing.
Like
junit-android dir="."...
Thanks a lot for your help and time.
Just to be clear because I've search on the web and didn't find many things, so hope you can help.
I have an Android project that contains NO activities.
Actual build.xml file:
I compile java source code
It generates me a .jar file.
I need to run some tests defined in my project/tests/ folder, using
the previous generated library. Thoses tests need to be runned on an
emulator device using ANT build file, whithout being dependent of
Eclipse.
Project:
src (java source code)
gen
bin
res
tests (Android test project)
AndroidManifest.xml
build.xml
...
The test project generated is containing a build.xml that has been automatically generated using android update command. Sadly, there is no task "run-tests". And how do I specify that I would like to use my library for those tests?

Everything you need to create and run android test projects from the command line, provided by Google itself ;-)
http://developer.android.com/tools/testing/testing_otheride.html
The command line you need is something like:
adb shell am instrument -w <test_package_name>/<runner_class>
To call that from Ant, use the <run-tests/> task, described here.

Create a target in your build.xml like this
<target name="run-tests">
<test-junit includedTests="pathToPackageContainingTests}/*.class" />
</target>
Then you can simply do this
ant clean release run-tests

Related

Using google Test with Android NDK

gradle-ndk-gtest-sample
Android NDK with
README.NDK
I have been trying to configure my Android NDK project for use with Google Test. I started with native-activity sample as the base project and began following the guides above. I inserted the code from the first link into my root build.gradle. I am really not having any success. It looks like i was able to generate the test library:
./libs/googleTest/1.7.0/lib/osx/libgtest.a
./libs/googleTest/1.7.0/lib/linux/libgtest.a
./app/.externalNativeBuild/cmake/debug/x86_64/libnative_app_glue.a
./app/.externalNativeBuild/cmake/debug/x86_64/libFOO.a
./app/.externalNativeBuild/cmake/debug/x86_64/libgtest.a
./app/.externalNativeBuild/cmake/debug/arm64-v8a/libnative_app_glue.a
./app/.externalNativeBuild/cmake/debug/arm64-v8a/libFOO.a
./app/.externalNativeBuild/cmake/debug/arm64-v8a/libgtest.a
But I don't know where to go from here. How do I actually run the tests and see if they passed?
Try something like https://github.com/DanAlbert/GTestJNI. It's an alternative test runner for JUnit and GTest that exposes GTests as if they were JUnit, so you can just run your normal androidTests and they'll run your GTests for you.
Some day I want to get this either added to the NDK or at least made trivial to add to a project as a git submodule or something, but for now you can merge the pieces of that into your project.

How can I build an Android apk without Gradle on the command line?

I wrote an Android app that uses no dependencies or modules, has a single activity, and has a single layout file.
How can I build an apk file of my app on the command line without using Gradle (or other "build systems" or "dependency management" software)?
Use the following steps to build your apk manually, if you don't want use ant/gralde to build. But you must have Android SDK installed at least.
create R.java from aapt
use javac to compile all java source to *.class
use dx to convert all *.class to dex file, e.g output is classes.dex
create initial version of APK from assets, resources and AndroidManfiest.mk, e.g output is MyApplication.apk.unaligned
use aapt to add classes.dex generated in step 3 to MyApplication.apk.unaligned
use jarsigner to sign MyApplication.apk.unaligned with debug or release key
use zipalign to align the final APK, e.g output is MyApplication-debug.apk or MyApplication-release.apk if signing with release key
Done
I have created a sample script to do all the stuffs above, see here
Actually, Some articles have discussed this topic, see the following links.
https://www.apriorit.com/dev-blog/233-how-to-build-apk-file-from-command-line
https://spin.atomicobject.com/2011/08/22/building-android-application-bundles-apks-by-hand/
Try this for building apps with support libraries from command line. https://github.com/HemanthJabalpuri/AndroidExplorer
alijandro gave a perfect answer. I managed to write simple ANT script that builds production APK with AdMob and without gradle usage. A couple useful comments:
If you want to obfuscate classes you have to jar the compiled classes (between javac and dx steps) and run proguard on it
For AdMob you have to extract the following jars from zip archives (like
C:\Users\<User>\AppData\Local\Android\sdk\extras\google\m2repository\com\google\android\gms\play-services-ads\10.2.6\play-services-ads-10.2.6.aar):
play-services-ads-10.2.6.jar
play-services-ads-lite-10.2.6.jar
play-services-base-10.2.6.jar
play-services-basement-10.2.6.jar
play-services-clearcut-10.2.6.jar
play-services-gass-10.2.6.jar
play-services-tasks-10.2.6.jar
These archives should be passed in javac and dx
For AdMob there are several additional simple config steps as well
Gradle does a lot of mess with android projects, so own script looks like a singular solution for projects that are going to go into production
A while back I stumbled across this thread after getting frustrated with both Android Studio and Gradle. Inspired by the answer from alijandro and this template from authmane512, I wrote a series of scripts to compile an Android app (including with dependencies/packages) in Java or Kotlin without any external build system.
Link: https://github.com/jbendtsen/tiny-android-template
There is a little bit of DIY involved here, but given that it's the sort of stuff that something like Gradle would do for you, I would argue that it's useful to know. Besides, it's like wayyyy less slow, and you have a lot more control how your app gets assembled.

Simple non-API Android JUnit test in Eclipse with android-maven-plugin?

I run non-Android JUnit tests from within Eclipse every day. Today I wanted to test some of my Android library classes. Oh, the pain.
I have an Android library project using android-maven-plugin. I have source files in src/main/java and my (new) unit test in src/test/java. My POM has the appropriate JUnit dependencies and android-maven-plugin references.
Sometimes I create an Android Uri instance from a File. Sometimes I have an existing Java URI instance that I've created from a File which I then convert to a Uri. Since I trust neither Java nor Android with files and URIs (don't get me started on how Java mangles UNC paths in URIs, or how Java breaks the equals() contract in URIs), I wanted to create a simple unit test to create a temp file, create Uris from two different approaches, and make sure they come out equal.
So I make a little JUnit unit test like I'm used to, and try to run it in Eclipse using Ctrl+F11. Eclipse asks me if this is an "Android JUnit Test" or a "JUnit Test". Well, Android, obviously. So I choose the first option and get:
[2013-03-23 21:37:10 - mylib] ------------------------------
[2013-03-23 21:37:10 - mylib] Android Launch!
[2013-03-23 21:37:10 - mylib] adb is running normally.
[2013-03-23 21:37:10 - mylib] Could not find mylib.apk!
Hmmm... that wasn't very successful. So I delete the run configuration and try just "JUnit Test". Now I get a different dialog, asking me to select my preferred launcher, either "Android JUnit Test Launcher" or "Eclipse JUnit Test Launcher". It doesn't matter which I choose; I get:
Class not found com.example.MyUnitTest
java.lang.ClassNotFoundException: com.example.MyUnitTest
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClass(RemoteTestRunner.java:693)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClasses(RemoteTestRunner.java:429)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
I've read that with the android-maven-plugin I can run unit tests locally in Eclipse if they just use classes in the Android jar but don't make any API calls, which is what I'm doing here. So how do I pull that off?
A workaround is to click the "Run As..." button in the toolbar and then select "Run Configurations...". If you select the JUnit launcher you created and go to its "Classpath" tab you can add the bin/classes folder to the JUnit launcher classpath. This should now run.
Do not use Run As - Android JUnit Test as it is for running Android Test Project only.
When use Run As - JUnit Test, the ClassNotFoundException is due to inconsistence between ADT and Eclipse built-in JUnit Test Runner regards to the project output folder. ADT generates all .class files under bin/classes, whereas built-in JUnit Test Runner looking for .class files under target/classes. Your Android project in Eclipse never use target/classes so it remains empty, this is the reason why you get ClassNotFoundException exception.
AFAIK there is no way to alter Eclipse built-in JUnit Test Runner to use a different folder than the default target/classes. Check out Ricardo's answer to see how to add bin/classes to built-in JUnit Test Runner's classpath. Also note that you cannot alter your Android project's default output folder to something else than ../bin/classes either, as it will break ADT build process.
The dirty workaround (for solving ClassNotFoundException) is manual copy everything under bin\classes to target\classes, note that you need do this every time you change the source code.
This is not a problem when running mvn test from command line or via Eclipse, as Maven use target\classes and know how to fill it properly. note that by using this approach, you will not able to use the JUnit window with nice red/green error bar inside Eclipse.
An android junit test should be located in a separate module as setup in the Android Maven Plugin samples projects (e.g. the morseflash example). This is due to the overloaded path setting and the need to build the apk and deploy it on the device/emulator to run the test. Android junit tests are NOT unit tests at all, but rather integration test (or in this case called instrumentation tests).

Android unit testing - how to run tests in same project as application?

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.

Documentation of available Ant tasks for Android?

I just accidentally discovered the ant task for test coverage reports with emma.
I'm now looking for a target that only invokes the unit test and generates unit testing output.
Is there a list with the available ant targets somewhere, or is it possible to look them up somewhere inside the code of the SDK?
Is there a list with the available ant targets somewhere, ...
You can get a list of all ant targets with -projecthelp and -verbose. While in the root directory of the project:
$ ant -projecthelp -verbose
The private ones show under the heading "Other targets:", but the targets with a leading dash are impossible to invoke from the command line. You can add a "wrapper" target to your build.xml and simply make it depend on the target you want.
I use ones like this for exposing the main targets to the IntelliJ IDEA platform:
<!-- Wrapper targets for setting up IntelliJ IDEA with Ant Build -->
<target name="Android clean" depends="clean" />
But you could also do something like:
<target name="Generate Resource Source" depends="-resource-src" />
Is there a list with the available ant
targets somewhere
Not that I am aware of. I can't even see how to get Ant to dump a list. :-(
is it possible to look them up
somewhere inside the code of the SDK?
They're on your development machine in $ANDROID_HOME/platforms/$API/templates, where $ANDROID_HOME is where you installed the SDK and $API is some Android version (e.g., android-2.1).
ant help would display all the available targets with detailed description.
Help target is at the end of ${SDK.HOME}/tools/ant/build.xml

Categories

Resources