How to unit test a cordova plugin using Junit? - android

I've done some Cordova plugins and I would like to write unit tests on it. The idea is that, after I run cordova build android, for example, the test files would be moved to the correct folder on Android and I could run tests with Java. Is that possible?
I've seen some plugins to make possible to test a Cordova plugin, like cordova plugin test framework. The problem here is that it only tests the call and the callback. It's not possible to mock objects, for example. For instance, I have a plugin to track GPS and I would like to test it.
I also would like to test the iOS side as well.

You were right in your research that the current tests for the Cordova Core plugins are all using cordova-plugin-test-framework to implement tests that are run on the device with e.g. cordova-paramedic or cordova-mobile-spec (see the CI configuration in the GitHub repositories on how to trigger a build with cordova-paramedic for example).
The only Cordova projects where "normal" unit tests, written in Java for Android and Obj-C for iOS, are used are the platforms. For Android for example this folder exists: https://github.com/apache/cordova-android/tree/master/test These tests can be run via run_java_unit_tests.js, which is also available via npm as npm run java-unit-tests.
I am pretty sure the same concept could be applied to plugin tests.
(Please let me know if you try and this actually works!)

Related

React Native Android to iOS migration

I have an Android app built from scratch using React Native. Can I migrate the same app to iOS? If so, how tough will it be?
The Android app is already built and working fine.
If the app is done in React Native, you could build it using Xcode, of course you need a Mac, https://facebook.github.io/react-native/docs/getting-started#xcode.
You can also try from command line
react-native run-ios
Remember that you still need to install Xcode and the tools needed to build on the simulator or your device.
Also remember that you might have to do some changes in your code, not always the code for android works in iOS, moreover if you are using native modules done by you or from a library.
A project written in react-native should, by default, work on iOS.
Normally tho, every package you have used, some styles still differs from each other from platform, some things are avaiable to do on Android and not on iOS, some things are avaiable on iOS and not on Android.
Some packages needs linking. Some needs additional steps to run on iOS changing some datas/informations using xcode. (like deep linking).
On react-native 0.60 you need to install the pods manually as it's not done by the autolinking, there are a lot things to check and it may not be automatic for the majority of the cases

Testing android implementation of cordova plugin

I have created a cordova plugin which has an android implementation. This Java code has calls into an SDK that interfaces with specific hardware that the mobile device is connected to. I would like to write unit tests for my Java code and mock all the calls into the SDK so that I can run the tests during CI.
When looking into this, I found the cordova-plugin-test-framework, but from what I can tell, this is for tests that you would write against the javascript code, not the actual platform implementations. I'm sure I could use it and write some tests, but it would require the mobile device to be connected to the hardware, and I don't want to have actual calls into the SDK. In other words, I don't have a way of mocking the SDK calls using this.
I thought maybe I could just run JUnit from the command line with my Java code, but then I was getting errors because it couldn't find org.apache.cordova.CallbackContext. I tried faking my own object, but as I continued, I found more dependencies that my code in isolation just doesn't know about.
Next I figured it would be best to test it within the android project under /platforms in my ionic mobile app, since all the dependencies would be visible at that point. I'm able to run ./gradlew test (https://developer.android.com/studio/test/command-line.html) from here, but I can't figure out how to implement the test cases so that this call will pick them up. Is there some kind of config I can add so it knows where to look for tests? I'd be fine if there was just a certain place I had to put them.
I'm open to any options with this. I just want to be able to run JUnit test as part of our CI process.

Porting JUnit tests to Android Testing Framework

I'm planning to port my JUnit tests to Android Testing framework.
Some of the tests only involve the JVM but not the Android system, is it still necessary to port them? Android is using Dalvik and will replace it with ART(Android Runtime) in Lollipop, both of which are different from the JVM (Please correct if I'm wrong.). In this sense, it seems necessary to port all the JUnit tests to the Android Testing framework.
However, some tutorial argues that
"If possible, you should prefer to run your unit tests directly on the
JVM as the test execution is much faster compared to the time required
to deploy and run the test on an Android device."
http://www.vogella.com/tutorials/AndroidTesting/article.html#androidtesting
I'm not an expert on JVM, Dalvik nor ART. Can someone clarify this issue? Is it necessary to port the tests that only involve JVM to Android Testing Framework?
Thanks!
This depends on what you would like to test and the environment in which you run your tests in.
In theory, pure non-Android-specific Java code (aka. POJOs) you write will work on whatever virtual machine you run it on--JVM, Dalvik, or ART.
If you agree with that theory, then if you are already running your tests on a JVM, there is no need to run it on Dalvik or ART, especially if you consider the speed at which JVM will execute the tests. (Running it on Dalvik involves building the apk, and installing it, and running an adb shell command which can take some time...)
Of course, if you feel that the behavior of your Java code may change depending on the runtime, then you should probably port those tests over to your Android tests.
Recently, I checked out Android Testing Support provided in Android SDK.
As far as I know, you can write Unit Tests, which can be executed directly on JVM in your computer or CI Server (e.g. Jenkins) without Android device or emulator. The only requirement is the fact that these tests and code, which is tested have to be written in pure Java without any dependencies to Android SDK and Android Context. These tests have to be located at src/test/java directory. You can switch test artifact in Build Variants in Android Studio to "Unit Tests" and run your tests with IDE. you can also run them via Gradle wrapper with the command: ./gradlew test
If your tests or code, which is going to be tested depend on Android SDK and Android Context, you should use Android Instrumentation tests, which have to be located in src/androidTest/java directory. These tests have to be executed on Android device or emulator. You can switch test artifact in Android Studio to "Android Instrumentation Tests" and run your tests with IDE or use Gradle wrapper command ./gradlew connectedCheck
You can check official article about Unit Testing at: http://tools.android.com/tech-docs/unit-testing-support . It's worth reading. It's a bit outdated, because now you can use build tools: 1.1.0 instead of 1.1.0-rc1, but rest of the information is up to date. After reading this article, you should understand this topic better.

development workflow for managing cordova plugins in your phonegap project

I'm trying to compile a phonegap based app using different development machines - think multiple developers with their own machines and/or different machines to build different platforms.
The application was first compiled on PC for android which works ok, but when I try compile on Mac for ios, some of the app functionality is missing. I can confirm that other applications are able to be built on the same Mac for ios, so it's not an xcode related issue.
My .gitignore includes things like node_modules/, www/, platforms/, app/lib and plugins/ and when I run npm install node_modules gets populated, and when I run bower install app/lib/ gets populated and so on.
As per this post I then proceed with manually creating directories www/, platforms/ and plugins/ which then allows me to run grunt platform:add:ios. I can then emulate and/or deploy successfully, but when testing, functionality in the app is missing.
The problem seems to be that the plugins/ folder doesn't get populated. I can manually run cordova plugin add <plugin> for each cordova plugin and when building and deploying the missing functionality shows up but the process seems a bit inefficient and prone to error if someone forgets to add a plugin.
Various guides have suggested running cordova prepare ios but this doesn't seem to do much.
This blog post by Josh Bavari suggests some hacking around to automate the process, and this post talks about something similar but they're half a year old now.
Am I missing something obvious here, or is the manual cordova plugin add process a normal part of dev workflow? Cheers.

Continuous Integration for Android via TeamCity. Preferred tools?

Our team is new to both Android and Java development (originally, we came from C++), therefore our knowledge about build tools for java is pretty shallow.
There are few build tools which can be used for build automation, and the most interesting I found were ant and maven. And although there are many articles on build automation, I didn't find any comprehensive tutorial on automating Integration process for android apps.
I would be very greatful if you could state your preferable build tool for Android and explain or give any links explaining the process of continuous integration for android apps (which cover not only building application package, but running tests under the emulator).
Thank you very much for your time and assistance.
P.S.: We are using Team City as the Continuous Integration server.
We are building our continuous integration platform for Android using the following:
Maven - for managing the build/unit-test/integration-test/deploy cycle
Hudson - for continuous integration
Team City will also run Maven projects - it is fairly simple to configure a TeamCity agent to run a specific Maven goal e.g. mvn integration-test - the agent could be running on a PC with an Android emulator or a real Android device plugged in.
In the past I've had a whole bank of TeamCity agents testing against different hardware. For example if you have 5 Android devices plugged into an agent you can configure the TeamCity build pipeline to run the integration tests (controlled easily via Maven) on ALL 5 devices and only declare a PASS when they pass on all 5.
Ant (http://ant.apache.org/) is pretty much the de facto standard for building java projects. It features a very easy to learn scripting language and can even be used to deploy your application to multiple targets.
For automated testing, most java developers use jUnit (http://www.junit.org/). While not quite as seamless as the Ruby on Rails testing framework, jUnit tests do allow for test-driven development.
Maven (http://maven.apache.org/what-is-maven.html) is more of a meta-program that can use ant scripts and run your jUnit tests. True, ant can also be used to run jUnit tests, but Maven does a good job of pulling all of that together as well as providing extra functionality (example: the ability to automatically find external dependencies and download them).
While I am not familiar with TeamCity, I would be surprised if it did not have a way to integrate with ant/maven/junit.
Best of luck!

Categories

Resources