顯示具有 Ondrej 標籤的文章。 顯示所有文章
顯示具有 Ondrej 標籤的文章。 顯示所有文章

2009年4月1日 星期三

Testing Android Applications - part 1

Adroid 應用程式的測試方法 - I

圖片引用自 tucowsinc.com

Unit tests and testing are parts of each developer's life and they are important parts of development. Developers usually concentrate on unit tests which help them ensure that future changes will not break the system and let other people do tests and stress tests of applications to reveal bugs, which we as developers simply cannot see.

About This Series of Articles

This is the first article about testing Android applications. We will look at some testing background, discuss basic elements available for you in the SDK and show how to prepare testing environment to run tests. In following articles we will concentrate on describing testing methods in detail.

Short History of Android Testing

Prior to Android SDK 1.0 there was a huge gap in testing of android applications which inspired 3rd-party testing frameworks such as Positron and Electron. With Android SDK 1.0 Google filled the gap with its own testing framework and Positron and Electron frameworks are not needed any more. Filled the gap in testing and filled it well. Let's have a look at what is available there for us. We will concentrate on unit and functional test which are supported with new part of Android SDK.

Unit Testing

There are basically three levels of tests/unit-test you can use in your application:

  1. Unit testing of logic which does not depend on android at all. This is similar to every usual unit testing. Running tests directly from Eclipse requires some configuration changes which we will cover later.
  2. Unit testing of business logic which depends on Android but does not depend on Android application elements and ui. These logic does not require activity to be running with complete context and it can be tested in isolation from ui. These tests usually require something from context (e.g. resources, configuration, logger, some native classes)
  3. Unit/funcional testing of Android application elements. These tests are fully instantiated activities, services, content providers and applications. Via instrumentation it is possible to send keyboard and touch events to the activities and check response in ui. It is possible to test lifecycle of a service and to test databases changes made by content provider.

To be able to test layers of the application in isolation using and fully use prevoius three levels. It is useful to follow these guidelines during design and development phases of your Android application:

  1. Separate business logic from ui logic as much as possible.
  2. Create presenter for complicated activities which models state on the screen and binds to the views according to MVP pattern.
  3. Make clear non expansive contracts between ui layer and business logic.
  4. Return error codes from business logic and let present logic transform them to error messages.
  5. Pass configuraton stored in preferences or in resources in parameters and do not load it in business logic

How to Prepare Testing Environment for Unit Tests

Good starting point for preparing environment for tests which do not depend on Android can be found here. Android runtime in android.jar contains some subset of junit which can not be used out of android environment. If you try to run unit test directly from Eclipse, you get exception like this:

... Internal Error (classFileParser.cpp:2924), pid=11018, tid=3084700560 # Error: ShouldNotReachHere() ...

To be able to run tests from Eclipse you have to replace android.jar by junit.jar

  1. go to "Run Configurations"
  2. search for configuration running your unit test
  3. go to "Classpath" tab
  4. remove "Android Library" from "Bootstrap Entries"
  5. then go to project build path configuration
  6. and add Junit library to your project
  7. you should be able to run junit unit tests

Image on the left shows "Run Configuration" dialog with Android library not deleted and image on the right shows configuration of build path. It is sometimes even possible to unit test classes which depends on classes from android.jar by deleting junit classes in the jar file. But once tested classes requires something from android runtime, you get exceptions.

Setup for Tests Depending on Android

Good starting point is here which shows how to set separate application and test environment but does not show that is possible to have everything working together in one project. You have to setup instrumentation for your project which allows your tests to hook into your application and take control over application ui and pass various events.

  • Add <uses-library android:name="android.test.runner" /> to alement in your manifest file
  • Add test runner definition to your manifest file

where:

  • android:name is name of the test runner class - use android.test.InstrumentationTestRunner as default
  • android:targetPackage is application package you want to instrument
  • android:label is name of the test which appears under Instrumentation in Dev Tools application

How to Run Tests Depending on Android in Eclipse and Emulator

To run tests directly from emulator go to DevTools application in the emulator, select Instrumentation and click on the name of the tests you want to run. Results and lot of debugging output can be found in Logcat console.

How to Run Tests Depending on Android with adb

To run tests from command line enter

adb shell am instrument -w PACKAGE/android.test.InstrumentationTestRunner

where PACKAGE is full name of application package which should be instrumented.

Monkey

Does everything seem to be too complicated for you? Do you wonder if there is simple way how to test Android application? The answer is UI/Application Exerciser Monkey tool available in Android SDK. Monkey is quite fast way for testing of ui. Just be warned that monkey does not like real devices yet. There is bug which causes that monkey is killed by Android whenever it tries to send a notification key to the real T-Mobile G1 device. Now our clever monkey likes to work without bugs with the emulator only.

Next Article...

So far we know what we can test on Android application and we know how to setup and run various kinds of tests. Next time we will look at some tips and hints how to actually write unit and functional tests.

Stay tuned...

註:

這是 Ondrej 的第一篇文章,原先是想幫他在文中譯註關鍵部份。不過我讀了一下,發覺他的用語都還簡單易懂,加上又是技術文章,大家應該有能力,理解他所要傳遞的知識。如果硬在原文中,加上中文譯註,反倒破壞了閱讀者的流暢性。

最後決定,我會在文章的最後,加上關鍵部份的註解。不會逐字翻譯,多是將重點或精神點出。如果你有任何的問題,歡迎在這裡提問,中文發問也可以的。

單元測試 (Unit Testing)

以測試的角度來看,基本上一 個應用程式可分成三層:

  • Logic: 純粹程式邏輯的部份,也就是和 Android 系統以及 UI 無關的部份。
  • Business logic: 和 Android 系統邏輯相關,但和 UI (例如 Activity, View, Dialog, Context, Resources, Logger 都是 UI 相關部份) 無關的部份。
  • UI logic: 當然就是和 UI 息息相關的部份。

要讓你的程式達到 "可測試" 的程度,你必須在寫程式注意一些事情,及遵守下列原則:

  • 程式中要盡量將上面提到的三層,清楚分開
  • 可以利用 MVP (Model, View, Presenter) 設計範式幫你分開,尤其是與 UI 相關及無關的部份,一定要切乾淨。
  • 在 UI 層與 Business logic 層之間的溝通傳遞協定,要盡量簡單清楚。
  • 不要在 Business logic 這層中,直接顯示錯誤訊息。應該要傳回錯誤碼,由 UI 層來顯示。
  • 也不要在 Business logic 層中,直接使用 Android 的 API 去讀取 preferences 設定,或是從 resources 中讀字串值。只有 UI 層,才能使用 Android 的 APIs,讀取到值後,再傳給 Business logic 那一層的。

繼續閱讀全文...

2009年3月17日 星期二

恩德雷 joined Sam's blog

Welcome Ondrej to join us!

不久前,才透過 email 認識 Ondrej。這位來自捷克,目前定居在台北的 Android Developer。

和 Ondrej 聊了一下午,知道他在 J2EE 上有多年的經驗,而其加入的 Inmite 初創公司,有參加過 ADC,也曾受邀在 布拉格 Google Developer Days 上介紹 Android。他說他很願意分享他在 Android 上的經驗,聽到這,我當然就毫不猶豫地邀請他一起共筆。希望他的加入,能提供給大家更多的收穫。

不用驚訝,Ondrej (恩德雷是他的中文名字) 真的能說、也看得懂一些中文。請大家不要吝嗇地,多多給他些鼓勵、支持、意見、還有發問,不管是用英文或是中文都可以。底下是關於他自己的介紹:

Hello,
I am Ondrej Zahradnik 恩德雷 - Android developer living in Taipei for already almost half a year. I work for startup company Inmite based in Prague, Czech Republic which focuses on developing Android Applications.

I joined Sam's blog because I would like to share my knowledge about developing Android Applications with guys from Taiwanese Android community and help us to push Android from devoted developers to the public.

Although I have some background in studying Mandarin in Xiamen University, unfortunately I am not yet good enough to read and write articles about Android in Mandarin, so Sam suggested that he will translate most important parts of my articles written in English to Mandarin for you. But feel free to write comments and questions in Mandarin I will understand and will try to reply in characters. It will also help me to improve my Mandarin from street use to some technical

If you have any questions related to Android or me, drop me a message by email to ondra at inmite.eu

Wandering why I am here so far from the business in the Czech Republic? The answer is quite simple. My girlfriend got a scholarship from Taiwanese government to study her PhD. degree here and I have decided to accompany her and we have not decided how long we stay here yet. It can from another half a year to few years.

Looking forward to seeing you reading our new posts and to meet on some coming Android sessions here in Taipei.


繼續閱讀全文...