Automated Unit Tests — Kin Mobile SDK on Ethereum Part III: Android
This post is a follow up for: testrpc with Xcode, as a tutorial on how to write automated instrumentation tests for an Android mobile app with testrpc and Truffle on Ethereum. I will show only the files that were changed.
While trying to run unit tests on Android, We had to run them as instrumentation tests, with an emulator to simulate a smartphone. This is due to the use of Geth (go-ethereum), a Go library we are using to interact with Ethereum.
Requirements:
- Clone our repo:
git clone https://github.com/kinfoundation/kin-sdk-core-android.git
- Node install:
brew install node
- Truffle install:
cd kin-sdk-core/truffle && npm install
- Submodule:
git submodule init && git submodule update
- Run An Emulator API 16 and above
- Run tests:
make test
from root directory
How it works
The following scripts initialize testrpc, Truffle, accounts and the ERC20 token contract. We decided calling them using GNU Make and Gradle tasks.
testrpc-accounts.sh
Defines ten wallet accounts used for testing, along with their private keys.
testrpc-run.sh
Starts up testrpc, loads the accounts mentioned above, and outputs a log and a file with its pid (Process ID). The log can be used for development and transaction tracing, while the pid is used for restarting testrpc when re-executing the tests.
This script also prints the accounts’ private keys into a testConfig.json
file, which will be discussed later on.
truffle.sh
Executes Truffle, which does the following:
- Deploys the token contract on the testrpc nodes using the migration script mentioned in the previous post.
- Assigns tokens to the accounts defined in
testrpc-accounts.sh
. - Outputs the results of the above actions to a
truffle.log
file. - Outputs the newly deployed token contract to a
token-contract-address
file, so that android tests could test against it.
prepate-tests.sh
Executed by gradle task prepareRPC
prior to running the tests. It prints the token contract address into a testConfig.json
file.
Makefile
The following targets call the scripts above, so an automated build on Travis CI could just call make test
, keeping all logic out of the CI configuration (.travis.yml
in our case). We created 2 gradle tasks that communicate with this Makefile, in order to be able to run tests also from Android Studio. I’ll elaborate on gradle section.
travis.yml
Configuration file to our continuous integration service Travis. Our travis.yml has been updated since we first open-sourced our SDK, and we were able to improve the build time. We’re now caching node_modules, we removed all of the unnecessary components e.g: Writing — tools
twice, before and after — platform-tools
which makes travis download the latest android sdk tool, but we are using specific android sdk tools (26.0.2) so we don’t actually need it. We changed EMULATOR_API_LEVEL
from 19 to 16, which boots up faster than all other API levels.
As you can see, we now install node dependencies in kin-sdk-core/truffle
. This is due to a problem we had with Jitpack: Before that, we installed node dependencies just like iOS does: cd truffle && npm install
, meaning inside the project folder beside our kin-sdk-core module and the sample app module. But Jitpack was failing to build because of the existence of truffle
folder that is not a regular android module. We found that moving truffle
folder into the existing kin-sdk-core module fixes the problem.
build.gradle (Module: kin-sdk-core)
We added two gradle tasks: prepareRPC
and clearRPC
. The preBuild
task is the first task that runs on android build and depends on prepareRPC
. The last task connectedDebugAndroidTest
is finalized by the cleanRPC
task. Task prepareRPC
will call to Make target prepare-tests
, that handles running testrpc. Note the running machine’s IP address while running the tests on Android Studio emulator is: 10.0.2.2 and on Genymotion is 10.0.3.2. Each instance of the emulator runs behind a virtual router/firewall service that isolates it from your development machine network interfaces and settings and from the internet. You can read more about it here. After the task has completed, you’ll have a testrpc node up and running, and testConfig.json
will be generated in androidTest/asset
folder, containing ten accounts and a token contract address. The first account will have 100 ETH and 1000 Tokens, all the other nine accounts will have 100 ETH. The contract address is the one we need to communicate with, in order to create transactions, get balance and pending balance related to the accounts.
Import testrpc output into android tests
On BaseTest.java we read testConfig.json
and create Config.java
object where we can access the generated accounts’ private keys and the token contract address. We set the token contract address as a system property and got it in EthClientWrapper.java based on ServiceProvider.networkId
. If the networkId equals the NETWORK_ID_TRUFFLE it will retrieve the contract address from the system property — TOKEN_CONTRACT_ADDRESS
.
While running tests from Android Studio, you will have to cleanup testrpc by running the command make clean
, it will shut it down and remove remaining log files. If you run tests from the command line by make test
, gradle will execute clearRPC
task and will shutdown testrpc on its own.
To run all the tests from your terminal — which is also what Travis executes.
make test
It took about a week to make it all work together as expected and in an easy way to test. We had a great opportunity to make testing a little bit different than the regular way: connecting testrpc, Truffle, Travis-CI, GNU Make and Gradle. We hope it will make the contribution to our Kin SDK safer and easier. If you have any comments or questions, feel free to comment here, or ping me on LinkedIn OrenZakay.