Chương 1 CƠ SỞ LÝ THUYẾT
1.2. Khái niệm về kiểm thử trên điện thoại thông minh
1.2.4. Nền tảng kiểm thử Android
Nền tảng kiểm thử của Android cung cấp rất tiện dụng được mở rộng từ nền tảng kiểm thử của JUnit chuẩn với nhiều tính năng phù hợp với các chiến lược kiểm thử [4].
Những tính năng này bao gồm:
Bổ sung các class Android mở rộng từ JUnit cho phép truy cập vào các đối tượng hệ thống trong Android.
Instrumentation framework cho phép kiểm soát và kiểm tra ứng dụng.
Các đối tượng giả lập (Mock) được sử dụng phổ biến trong hệ thống Android để kiểm tra khả năng chịu tải của các ứng dụng.
Các công cụ cho phép thực hiện kiểm thử riêng lẻ hay chạy cả một dãy các lệnh kiểm thử mà có thể không cần đến Instrumentation framework (IF).
Hỗ trợ quản lí kiểm thử trong ADT plugin của Eclipse và cả chế độ dòng lệnh của hệ điều hành.
1.2.4.1. Instrument framework (IF)
Instrumentation framework là một phần cơ bản của nền tảng kiểm thử trong Android. IF điều khiển ứng dụng kiểm thử và cho phép gắn các đối tượng thay thế giả lập (Mock object) vào ứng dụng để chạy. Ví dụ ta có thể tạo một đối tượng giả lập Context trước khi ứng dụng bắt đầu và cho phép ứng dụng sử dụng nó. Tất cả mọi tương tác giữa ứng dụng và môi trường xung quanh có thể sử dụng phương pháp tiếp cận này. Ta cũng có thể tách riêng ứng dụng của chúng ta trong một môi trường giới hạn để lấy về kết quả, hoặc các dữ liệu được lưu trữ và không thay đổi như Content Provider, cơ sở dữ liệu hay thậm chí là hệ thống các tệp tin [7].
Một dự án Android thường có một dự án kiểm thử tương ứng với tên kết thúc bằng “Test”. Bên trong một dự án kiểm thử file AndroidManifest.xml khai báo thẻ cho biết IF là <instrumentation></ instrumentation>.
Ví dụ: giả sử dự án Android có file manifest có dạng sau:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.at"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity
android:name=".TooDo"
android:screenOrientation="landscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".WorkEnter">
</activity>
<receiver android:name=".AlarmReceiver"> </receiver>
</application>
<uses-sdk android:minSdkVersion="3" />
<uses-permission android:name="android.permission.VIBRATE"/>
</manifest>
Hình 1.3. Định dạng tệp manifest trong kiểm thử đơn vị Android.
Nhìn ví dụ này có thể thấy ngay rằng trong thẻ khai báo IF là với thuộc tính name là trình chạy kiểm thử test runner, class mặc định của Android testing API (android.test.runner), ta cũng có thể tùy biến class này bằng cách kế thừa từ class InstrumentationTestRunner, thuộc tính targetPackage chỉ ra package của ứng dụng mà ta muốn kiểm thử (trong ví dụ là AddressContacts).
1.2.4.2. Kiến trúc kiểm thử ứng dụng trên Android
Hình 1.4. Kiến trúc kiểm thử ứng dụng trên Android [7].
Gói chương trình
InstrumentationRunner
Gói kiểm thử
Các lớp kiểm thử Android Instrumentation Kiểm thử đơn vị
Đối tượng MOCK Công cụ kiểm thử
Kiểm thử tự động
Trong kiến trúc này InstrumentationTestRunner làm nhiệm vụ trung gian trong việc chạy các các ca kiểm thử. Các thành phần chính trong kiến trúc này:
- Application package: chứa toàn bộ ứng dụng để kiểm thử.
- Test projects: chứa các mã nguồn, file manifest và những file khác dùng để kiểm thử ứng dụng. Ta có thể sử dụng Eclipse để tạo ra dự án kiểm thử này.
- Testing API: Nơi chứa các ca kiểm thử đã được cài đặt.
- JUnit: có thể sử dụng các ca kiểm thử của các lớp JUnit để kiểm thử.
- Instrumentation: Android Instrumentation là một tập các phương thức điều khiển trong hệ thống Andoird. Các điều khiển này độc lập với vòng đời của ứng dụng và chúng cũng kiểm soát cách Android tải ứng dụng để chạy. Thông thường Android framework không cung cấp cách để gọi trực tiếp các hàm callback trong vòng đời của một ứng dụng như onCreate(), onResume(),... nhưng với instrumentation ta có thể gọi các hàm này thông qua các phương thức như getActivity(), activity.finish().
- Test case classes: Android cung cấp một vài class kế thừa từ lớp TestCase và Assert của JUnit framework như Application TestCase,
Instrumentation TestCase.
- Mock Object: để chống sự phụ thuộc (dependency injection) trong kiểm thử, Android cung cấp các class để tạo các đối tượng hệ thống giả lập như MockContext, MockContentProvider.
- MonkeyRunner: những API để thực thi trong môi trường với ngôn ngữ là Python.
- Monkey: một công cụ dòng lệnh để kiểm thử khả năng chịu tải của ứng dụng thông qua công cụ adb của hệ điều hành Android.
1.2.4.3. Các mục tiêu kiểm thử
Trong suốt quá trình phát triển phần mềm, các ca kiểm thử sẽ hướng đến các thiết bị khác nhau. Từ đơn giản, phức tạp và tốc độ kiểm thử trên máy ảo đến trên một thiết bị thật cụ thể nào đó. Ngoài ra có một vài trường hợp trung gian như chạy kiểm tra trên một máy ảo cục bộ JVM hay DVM, phụ thuộc vào từng trường hợp.
Mỗi trường hợp đều có ưu và nhược điểm riêng. Máy ảo có lẽ là thiết bị phù hợp nhất mà ta có thể thay đổi gần như tất cả các tham số cấu hình để mô phỏng các điều kiện khác nhau cho các ca kiểm thử. Thiết bị thật dùng để kiểm thử hiệu năng vì trên máy ảo sẽ không thể tính ra được các thông số trên thiết bị thật sẽ như thế nào. Rendering, filling, và các trường hợp khác phải được kiểm tra trước khi ứng dụng được chuyển giao cho người dùng cuối. Tóm lại ứng dụng nên được kiểm tra ở mọi trường hợp, đây là cách tốt nhất để phát hiện những lỗi trước hơn khi là lỗi được phát hiện bởi khách hàng khi sử dụng.