Intro
This article is the first of a series of posts on writing automated unit tests for mobile apps over Ethereum using testrpc and Truffle.
- Part I: Introduction (This post)
- Part II: iOS
- Part III: Android
While working on Kin mobile SDKs we have stumbled upon a challenge regarding our CI flow: There are multiple developers working on the mobile SDKs across multiple teams — iOS, Android, and backend. In order to add new features multiple times a day without stepping on each other’s toes we require automated unit tests. This will help verify that important features such as checking balances or sending transactions don’t break on every new change added to the repositories. Our iOS and Android mobile SDKs have recently been open sourced, and these concerns are even more valid in an open source environment; when changes from contributors around the world are proposed, we need to have a fast way to ensure nothing breaks. Additionally, if there was a bug in the code before, adding new test cases helps to identify a problem and guarantee that it won’t happen again.
Since the initial version of the SDK will be on Ethereum, we need a way to write unit tests that work with an Ethereum node. Preferably the node should be isolated — so that it could run ad-hoc on a CI service like Travis CI when a developer implements a new feature, which happens multiple times a day. It also means that syncing the entire blockchain for every test execution is not an option since it’s slow and would be inefficient for the test cases. Furthermore, transactions over Testnet require test ETH, and takes time to be processed and mined. If you think about it — we only need specific components from an Ethereum node: mainly the JSON RPC protocol component for receiving transactions, and the EVM for smart contract support (since Kin is currently an ERC20 smart contract). We can, for example, skip the PoW consensus and mining layers — since these can greatly slow down development time, and we won’t be connecting to Mainnet for unit tests.
Fortunately enough we have an application just for that: testrpc, recently named Ganache. It’s an Ethereum mock node, which simulates the exact parts one usually needs when testing Ethereum apps — be it desktop, browser, or mobile apps as in our case. It was recently added to the Truffle testing framework. Truffle is a library and CLI which makes testing, developing and deploying Ethereum apps much easier. Using Truffle we can easily deploy contracts and assign tokens for test accounts. It also allows writing unit tests in Javascript, but in the case of mobile development we’ll write our own in Swift.
It’s true that we could use a full Ethereum node like Geth and “disable” mining and other components. However, testrpc provides a solution with sane defaults that allows you to start writing unit tests without messing with unnecessary node configuration. For more information about testrpc features please see the following StackExchange post.
Testing Requirements — What Do We Test?
There are two main domains our SDK acts on, therefore testing is also focused on them:
- Account Creation and Management: all these operations happen only on the device and don’t depend on the blockchain, so testing them is simple. Whenever tests are run, we ensure accounts can be:
- Created
- Stored securely
- Deleted
- Exported
- Imported
2. Blockchain Interactions: the account generated should be able to:
- Check the current balance
- Check the pending balance
- Send transactions
Tests preferably should run against a newly deployed token contract with accounts loaded with both ETH and Kin tokens, and not depend on previous block history.
Setting up testrpc with Truffle Framework
The following explains how to install and setup testrpc, deploy an ERC20 token contract on it, create multiple test accounts and assign ETH and tokens to them. This code will also be viewable in our kinfoundation/kin-sdk-core-ios repository.
Installation
Testrpc and Truffle are written in Node.js and can be installed using npm
:
$ npm install --save truffle ethereumjs-testrpc
Directory Tree
You should use the following directory tree. Truffle can also set this up automatically using the truffle init
command:
Contracts/
This directory should include smart contracts that you want to test against. In our case, we used the ERC20 contract we used for deploying the Kin token.
Migrations/
Migrations are Javascript files that Truffle uses for deploying contracts on a target node (testrpc in our case). You can also use this for initializing accounts for testing and assigning ETH and tokens to them.
truffle.js
This file defines necessary configuration for Truffle to run properly e.g. testrpc node address (localhost:8545
in our case), transaction gas cost, and loading some additional libraries.
scripts/ and Makefile
The following scripts initialize testrpc, Truffle, accounts and the ERC20 token contract. We wrapped calling them using GNU Make, practically turning it to a CLI. You don’t have to use this Makefile and can just call the scripts manually or some other solution, but we find it convenient.
testrpc-accounts.sh
This file defines ten wallet accounts used for testing, along with their private keys.
testrpc-run.sh
This file 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.
Note: This script communicates with Xcode via a .plist
file, which will be discussed later on.
testrpc-kill.sh
This script is used for kill testrpc before restarting it for re-executing tests. It uses the pid file created in testrpc-run.sh
.
truffle.sh
This script executes Truffle, which does the following:
- Deploys the token contract on the testrpc nodes using the migration script mentioned above.
- Assigns tokens to some of the accounts defines 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 iOS / Xcode unit tests could test against it.
prepare-tests.sh
This script is executed by Xcode prior to running the tests. It prints the accounts private keys and token contract address into a .plist
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).
.travis.yml
We’re using Travis CI for automated tests. We’re testing Objective-C and Swift code which also depends on Node.js apps — testrpc and Truffle. Thus, we need to set them both up in the automated build:
Conclusion
This sums up the directory layout and infrastructure we’re using for unit tests. In the following posts we will explain how we integrate all of the above into Xcode (for iOS unit tests) and Android Studio.
I hope this article provided a good explanation on how to use automation for fast iteration development over Ethereum. If you have any questions or need any help — Please feel free to ask questions in the responses box down below.