- Notifications
You must be signed in to change notification settings - Fork10
Google Test for native (NDK/C++) Android Apps
License
harshvs/android-gtest-driver
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Google Test for NDK based Android Apps
Here we have a sample NDK based Android project and a python script toshow the integration of theGoogleTests to run native (C++)instrumented unit tests.
The Unit testing of the shared native (C++) modules typically requiresa large overhead of extracting/maintaining/running the modules outsideof their real context so they could run under tests on thedevelopment/test machines. This usually requires rebuilding thebinaries for the target machine with mocking and simulating thingsaround it.
In practice, real systems are complex with myriadinter-dependencies. Testing a component by mocking its actualdependencies and, that too, outside of its actual run-time context isa complex, costly and tedious task. It is also hard to guarantee thatthe module under test will behave in exactly the same way in bothtest(dev box) and production environment. Also, it becomesincreasingly hard to maintain the pure unit testing with mockeverything strategy in presence of pressing deadlines and influx ofnew features. Often the ball gets dropped in the middle of the projectand thereafter abandoned - as the cost (engineering debt) to revive itthen gets prohibitively expensive.
The instrumented unit tests which run on actual device/emulatorprovide a better alternative. It gets us higher ROI as the effort torun and maintain it is lower, and it gives greater confidence inresutls (as entities get tested under real conditions). The downsideof it could be slowness and flakiness of the test runs. But thoseconcerns can be mitigated by avoiding delay causing steps like UIinteractions and by providing controlled network conditions (say bytesting against services available in the local network).
Using instrumented unit tests helps to reduce the effort to write andmaintain mock code. We are free to use a mocking framework, if wechoose, to simulate any dependency (say a flaky external service orfaking UI interaction).
A unit in this context can be as small or big as we choose or seefit. The same test strategy, therefore covers a wide spectrum oftesting (Unit/Component/Integration). This reasonable approach canpotentially give us a far greater ROI and control overwriting/maintaining test cases.
The tooling support for writing/maintaining instrumented C++ unit testsseems absent for Android. Here we may choose to hand-craftinstrumentation tests but that effort won't scale in comparison tousing an industry standard testing framework like Google Test.
Google Test is a popular open sourced xUnit based C++ testingframework from Google. It is put to use for testing large scale andcritical projects like Chromium, LLVM, Protocol Buffer and the AndroidNDK etc. It is a command line based system, though its integration inIDEs (VS, CLion) is supported. There are some open source UIfront-ends are available too. Google Test is light-weight, robust andhaving good eco-system/community - but it lacks support when it comesto its integration in Android projects. Android Studio does notprovide any tooling support for it either.
android-gtest-driver tries to fill that gap.
Google Test invokes the tests for the system under test by parsing thesupplied command line parameters and puts the result into its STDOUTchannel.
The idea is to introduce a proxy program which runs on the commandshell (on dev machine) which mimics the command line behavior of theGoogle Tests running inside the App. The driver program behaves as ifit is the system under test, but the actual test initialization andthe test runs happen on the device/emulator in the context of the appprocess.
This proxy way of interaction is achieved using ADB channel and byredirection of the app process's STDOUT channel to Android logs. Thedriver program keeps track of test results by scanning adb logs.
The input from console to Google Test runtime inside the app ishandled by the following steps:
- Test driver (gtest.py) takes the test command line params.
- A broadcast intent (GTEST_CMD) with those parameters as intent extra is sent via ADB to the device
- The broadcast is received by the app's GTest Driver receiver.
- The test parameters are extracted from the intent.
- The native Google test run (a JNI call) is initiated by initializing gtest for the supplied parameters.
The output (result) from the Google Test is delivered to console bythe following steps:
- The Google test runtime generates results on the app process's STDOUT channel.
- The STDOUT of the process is funneled via a PIPE to a new FILE handle.
- The input stream from the PIPE is put into Android logs (by a worker thread, AppStdoutPump).
- The ADB gets the logs from the device to the test driver (gtest.py).
- The driver monitors the start and the end of Google Test specific logs.
- The driver outputs the results to its own STDOUT channel.
About
Google Test for native (NDK/C++) Android Apps
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.


