Best Practices in Testing Mobile Applications Designing And Developing Bulletproof Android Applications

Developing applications for mobile is not that different from traditional desktop development. However, developers might find developing mobile applications more restrictive, especially resource constrained. Again, let’s start with some best practices or “rules” for mobile application development:

  • Test assumptions regarding feasibility early and often on the target devices.
  • Keep application size as small and efficient as possible.
  • Choose efficient data structures and algorithms appropriate to mobile.
  • Exercise prudent memory management.
  • Assume that devices are running primarily on battery power.

Designing a Development Process That Works for Mobile Development

A successful project’s backbone is a good software process. It ensures standards, good communication, and reduces risks. We talked about the overall mobile development process in the previouschapter. Again, here are a few general tips of successful cmobile development processes:

  • Use an iterative development process.
  • Use a regular, reproducible build process with adequate versioning.
  • Communicate scope changes to all parties—changes often affect testing most of all.

Testing the Feasibility of Your Application Early and Often

It cannot be said enough: You must test developer assumptions on real devices. There is nothing worse than designing and developing an application for a few months only to find that it needs serious redesign to work on an actual device. Just because your application works on the emulator does not, in any way, guarantee that it will run properly on the device. Some functional areas to examine carefully for feasibility include

  • Functionality that interacts with peripherals and device hardware
  • Network speed and latency
  • Memory footprint and usage
  • Algorithm efficiency
  • User interface suitability for different screen sizes and resolutions
  • Device input method assumptions
  • File size and storage usage

We know; we sound like a broken record but, truly, we’ve seen this mistake happen over and over again. Projects are especially vulnerable to this when target devices aren’t yet available. What happens is that engineers are forced closer to the waterfall method of software development with a big, bad surprise after weeks or months of development on some vanilla-style emulator.

We don’t need to explain again why waterfall approaches are dangerous, do we? You can never be too cautious about this stuff. Think of this as the preflight safety speech of mobile software development.

Using Coding Standards, Reviews, and Unit Tests to Improve Code Quality

Developers who spend the time and effort necessary to develop efficient mobile application are rewarded by their users. The following is a representative list of some of the efforts that you can take:

  • Centralizing core features in shared Java packages (or, if you have shared C or C++ libraries, consider using the Android NDK)
  • Developing for compatible versions of the Android SDK (know your target devices)
  • Using built-in controls and widgets appropriate to the application, customizing only where needed

You can use system services to determine important device characteristics (screen type, language, date, time, input methods, available hardware, and so on). If you make any changes to system settings from within your application, be sure to change the settings back when your application exits or pauses, if appropriate.

Defining Coding Standards

Developing a set of well-communicated coding standards for the development team can help drive home some of the important requirements of mobile applications. Some standards might include

  • Implementing robust error handling and handle exceptions gracefully.
  • Moving lengthy, process-intensive, or blocking operations off the main UI thread.
  • Releasing objects and resources you aren’t actively using.
  • Practicing prudent memory management. Memory leaks can render your application useless.
  • Using resources appropriately for future localization. Don’t hardcode strings and other assets in code or layout files.
  • Avoiding obfuscation in the code itself; comments are worthwhile. However, you should consider obfuscation later in the development process to protect against software piracy. Ideally, use obfuscation settings that preserve filename and line number details, so that you can easily track down application defects.
  • Considering using standard document generation tools, such as Javadoc.
  • Instituting and enforce naming conventions—in code and in database schema design.

Performing Code Reviews

Performing code inspections can improve the quality of project code, help enforce coding standards, and identify problems before QA gets their hands on a build and spends time and resources testing it.

It can also be helpful to pair developers with the QA tester who tests their specific functional areas to build a closer relationship between the teams. If testers understand how the application and Android operating system functions, they can test the application more thoroughly and successfully. This might or might not be done as part of a formal code review process. For example, a tester can identify defects related to type-safety just by noting the type of input expected (but not validated) on a form field of a layout or by reviewing Submit or Save button handling function with the developer.

Developing Code Diagnostics

The Android SDK provides a number of packages related to code diagnostics. Building a framework for logging, unit testing, and exercising your application to gather important diagnostic information, such as the frequency of method calls and performance of algorithms, can help you develop a solid, efficient, and effective mobile application. It should be noted that diagnostic hooks are almost always removed prior to application publication because they impose significant performance reductions and greatly reduce responsiveness.

Using Application Logging

In Chapter “Writing Your First Android Application,” we discuss how to leverage the built-in logging class android.util.Log to implement diagnostic logging, which can be monitored via a number of Android tools, such as the LogCat utility (available within DDMS, ADB, and Android Development Plug-in for Eclipse).

Developing Unit Tests

Unit testing can help developers move one step closer to the elusive 100 percent of code coverage testing. The Android SDK includes extensions to the JUnit framework for testing Android applications. Automated testing is accomplished by creating test cases, in Java code, that verify that the application works the way you designed it. You can do this automated testing for both unit testing and functional testing, including user interface testing.

Basic JUnit support is provided through the junit.framework and junit.runner packages. Here you find the familiar framework for running basic unit tests with helper classes for individual test cases. You can combine these test cases into test suites. There are utility classes for your standard assertions and test result logic.

The Android-specific unit testing classes are part of the android.test package, which includes an extensive array of testing tools designed specifically for Android applications. This package builds upon the JUnit framework and adds many interesting features, such as the following:

  • Simplified Hooking of Test Instrumentation (android.app.Instrumentation) with android.test.InstrumentationTestRunner, which you can run via ADB shell commands
  • Performance Testing (android.test.PerformanceTestCase)
  • Single Activity (or Context) Testing (android.test.ActivityUnitTestCase)
  • Full Application Testing (android.test.ApplicationTestCase)
  • Services Testing (android.test.ServiceTestCase)
  • Utilities for generating events such as Touch events (android.test.TouchUtils)
  • Many more specialized assertions (android.test.MoreAsserts) View validation (android.test.ViewAsserts)

If you are interested in designing and implementing a unit test framework for your Android application, we suggest working through our tutorial called “Android SDK: Unit Testing with the JUnit Testing Framework.”You can find this tutorial online.

Handling Defects Occurring on a Single Device

Occasionally, you have a situation in which you need to provide code for a specific device. Google and the Android team tell you that when this happens, it’s a bug, so you should tell them about it. By all means, do so. However, this won’t help you in the short term. Handling bugs that occur only on a single device can be tricky. You don’t want to branch code unnecessarily, so here are some of your choices:

  • If possible, keep the client generic, and use the server to serve up device-specific items.
  • If the conditions can be determined programmatically on the client, try to craft a generic solution that enables developers to continue to develop under one source code tree, without branching.
  • If the device is not a high-priority target, consider dropping it from your requirements if the cost-benefit ratio suggests that a workaround is not cost effective.
  • If required, branch the code to implement the fix. Make sure to set your Android manifest file settings such that the branched application version is installed only on the appropriate devices.
  • If all else fails, document the problem only and wait for the underlying “bug” to be addressed. Keep your users in the loop.

Leveraging Android Tools for Development

The Android SDK comes with a number of usefull tools and resources for application development. The development community adds even more useful utilities to the mix. You might want to leverage the following tools during this phase of your development project:

  • The Eclipse development environment with the ADT plug-in
  • The Android emulator and physical devices for testing
  • The Android Dalvik Debug Monitor Service (DDMS) tool for debugging and interaction with the emulator or device
  • The Android Debug Bridge (ADB) tool for logging, debugging, and shell access tools
  • The sqlite3 command-line tool for application database access (available via the ADB shell)
  • The Hierarchy Viewer for user interface debugging of views

There are also numerous other tools available as part of the Android SDK. See the Android documentation for more details.

Avoiding Silly Mistakes in Android Application Development

Here are some of the frustrating and silly mistakes Android developers should try to avoid:

  • Forgetting to add new application activities and necessary permissions to the AndroidManifest.xml file
  • Forgetting to display Toast messages using the show() method
  • Hard-coding information such as network information, test user information, and other data into the application
  • Forgetting to disable diagnostic logging before release
  • Distributing live applications with debug mode enabled