Library Pengujian Health Connect (androidx.health.connect:connect-testing
)
menyederhanakan pembuatan pengujian otomatis. Anda dapat menggunakan library ini untuk memverifikasi
perilaku aplikasi dan memvalidasi bahwa aplikasi merespons dengan benar
kasus yang tidak umum, yang sulit diuji secara manual.
Anda dapat menggunakan library untuk membuat pengujian unit lokal, yang biasanya memverifikasi perilaku class di aplikasi Anda yang berinteraksi dengan klien Health Connect.
Untuk mulai menggunakan library, tambahkan sebagai dependensi pengujian:
testImplementation("androidx.health.connect:connect-testing:1.0.0-alpha01")
Titik entri ke library adalah class FakeHealthConnectClient
, yang Anda
gunakan dalam pengujian untuk menggantikan HealthConnectClient
. FakeHealthConnectClient
memiliki fitur berikut:
- Representasi data dalam memori, sehingga Anda dapat menyisipkan, menghapus, dan membaca data
- Pembuatan token perubahan dan pelacakan perubahan
- Penomoran halaman untuk catatan dan perubahan
- Respons agregasi didukung dengan stub
- Mengizinkan fungsi apa pun untuk memunculkan pengecualian
FakePermissionController
yang dapat digunakan untuk meniru pemeriksaan izin
Untuk mempelajari lebih lanjut cara mengganti dependensi dalam pengujian, baca Injeksi Dependensi di Android. Untuk mengetahui lebih lanjut tentang tiruan, baca Menggunakan duplikat pengujian di Android.
Misalnya, jika class yang berinteraksi dengan klien disebut
HealthConnectManager
dan mengambil HealthConnectClient
sebagai dependensi, maka akan terlihat seperti:
class HealthConnectManager(
private val healthConnectClient: HealthConnectClient,
...
) { }
Dalam pengujian, Anda dapat meneruskan tiruan ke class yang sedang diuji:
import androidx.health.connect.client.testing.ExperimentalTestingApi
import androidx.health.connect.client.testing.FakeHealthConnectClient
import kotlinx.coroutines.test.runTest
@OptIn(ExperimentalTestingApi::class)
class HealthConnectManagerTest {
@Test
fun readRecords_filterByActivity() = runTest {
// Create a Fake with 2 running records.
val fake = FakeHealthConnectClient()
fake.insertRecords(listOf(fakeRunRecord1, fakeBikeRecord1))
// Create a manager that depends on the fake.
val manager = HealthConnectManager(fake)
// Read running records only.
val runningRecords = manager.fetchReport(activity = Running)
// Verify that the records were filtered correctly.
assertTrue(runningRecords.size == 1)
}
}
Pengujian ini memverifikasi bahwa fungsi fetchReport
fiktif di
HealthConnectManager
memfilter data dengan benar menurut aktivitas.
Memverifikasi pengecualian
Hampir setiap panggilan ke HealthConnectClient
dapat memunculkan pengecualian. Misalnya,
dokumentasi untuk insertRecords
menyebutkan pengecualian berikut:
@throws android.os.RemoteException
untuk setiap kegagalan pengiriman IPC.@throws SecurityException
untuk permintaan dengan akses yang tidak diizinkan.@throws java.io.IOException
untuk masalah I/O disk.
Pengecualian ini mencakup kasus seperti koneksi yang buruk atau tidak ada ruang yang tersisa di perangkat. Aplikasi Anda harus bereaksi dengan benar terhadap masalah runtime ini, karena dapat terjadi kapan saja.
import androidx.health.connect.client.testing.stubs.stub
@Test
fun addRecords_throwsRemoteException_errorIsExposed() {
// Create Fake that throws a RemoteException
// when insertRecords is called.
val fake = FakeHealthConnectClient()
fake.overrides.insertRecords = stub { throw RemoteException() }
// Create a manager that depends on the fake.
val manager = HealthConnectManager(fake)
// Insert a record.
manager.addRecords(fakeRunRecord1)
// Verify that the manager is exposing an error.
assertTrue(manager.errors.size == 1)
}
Agregasi
Panggilan agregasi tidak memiliki implementasi palsu. Sebagai gantinya, panggilan agregasi
menggunakan stub yang dapat Anda program untuk berperilaku dengan cara tertentu. Anda dapat mengakses
stub melalui properti overrides
dari FakeHealthConnectClient
.
Misalnya, Anda dapat memprogram fungsi gabungan untuk menampilkan hasil tertentu:
import androidx.health.connect.client.testing.AggregationResult
import androidx.health.connect.client.records.HeartRateRecord
import androidx.health.connect.client.records.ExerciseSessionRecord
import java.time.Duration
@Test
fun aggregate() {
// Create a fake result.
val result =
AggregationResult(metrics =
buildMap {
put(HeartRateRecord.BPM_AVG, 74.0)
put(
ExerciseSessionRecord.EXERCISE_DURATION_TOTAL,
Duration.ofMinutes(30)
)
}
)
// Create a fake that always returns the fake
// result when aggregate() is called.
val fake = FakeHealthConnectClient()
fake.overrides.aggregate = stub(result)
Kemudian, Anda dapat memverifikasi bahwa class yang sedang diuji, HealthConnectManager
dalam kasus ini, memproses hasil dengan benar:
// Create a manager that depends on the fake.
val manager = HealthConnectManager(fake)
// Call the function that in turn calls aggregate on the client.
val report = manager.getHeartRateReport()
// Verify that the manager is exposing an error.
assertThat(report.bpmAverage).isEqualTo(74.0)
Izin
Library pengujian menyertakan FakePermissionController
, yang dapat diteruskan
sebagai dependensi ke FakeHealthConnectClient
.
Subjek yang sedang diuji dapat menggunakan PermissionController—through
properti
permissionController
dari antarmuka HealthConnectClient
—untuk memeriksa
izin. Hal ini biasanya dilakukan sebelum setiap panggilan ke klien.
Untuk menguji fungsi ini, Anda dapat menetapkan izin yang tersedia menggunakan
FakePermissionController
:
import androidx.health.connect.client.testing.FakePermissionController
@Test
fun newRecords_noPermissions_errorIsExposed() {
// Create a permission controller with no permissions.
val permissionController = FakePermissionController(grantAll = false)
// Create a fake client with the permission controller.
val fake = FakeHealthConnectClient(permissionController = permissionController)
// Create a manager that depends on the fake.
val manager = HealthConnectManager(fake)
// Call addRecords so that the permission check is made.
manager.addRecords(fakeRunRecord1)
// Verify that the manager is exposing an error.
assertThat(manager.errors).hasSize(1)
}
Penomoran halaman
Penomoran halaman adalah sumber bug yang sangat umum, jadi FakeHealthConnectClient
menyediakan mekanisme untuk membantu Anda memverifikasi bahwa penerapan penomoran halaman untuk
rekaman dan perubahan berperilaku dengan benar.
Subjek yang sedang diuji, HealthConnectManager
dalam contoh ini, dapat menentukan
ukuran halaman dalam ReadRecordsRequest
:
fun fetchRecordsReport(pageSize: Int = 1000) }
val pagedRequest =
ReadRecordsRequest(
timeRangeFilter = ...,
recordType = ...,
pageToken = page1.pageToken,
pageSize = pageSize,
)
val page = client.readRecords(pagedRequest)
...
Menetapkan ukuran halaman ke nilai kecil, seperti 2, memungkinkan Anda menguji penomoran halaman. Misalnya, Anda dapat menyisipkan 5 data sehingga readRecords
menampilkan
3 halaman yang berbeda:
@Test
fun readRecords_multiplePages() = runTest {
// Create a Fake with 2 running records.
val fake = FakeHealthConnectClient()
fake.insertRecords(generateRunningRecords(5))
// Create a manager that depends on the fake.
val manager = HealthConnectManager(fake)
// Read records with a page size of 2.
val report = manager.generateReport(pageSize = 2)
// Verify that all the pages were processed correctly.
assertTrue(report.records.size == 5)
}
Data pengujian
Library ini belum menyertakan API untuk membuat data palsu, tetapi Anda dapat menggunakan data dan generator yang digunakan oleh library di Penelusuran Kode Android.
Untuk meniru nilai metadata dalam pengujian, Anda dapat menggunakan
MetadataTestHelper
. Hal ini menyediakan fungsi ekstensi
populatedWithTestValues()
, yang menyimulasikan Health Connect
mengisi nilai metadata selama penyisipan data.
Stub
Properti overrides
dari FakeHealthConnectClient
memungkinkan Anda memprogram (atau
mengganti) fungsi apa pun sehingga fungsi tersebut akan menampilkan pengecualian saat dipanggil.
Panggilan agregasi juga dapat menampilkan data arbitrer, dan mendukung antrean
beberapa respons. Lihat Stub
dan MutableStub
untuk mengetahui informasi selengkapnya.
Ringkasan kasus ekstrem
- Verifikasi bahwa aplikasi Anda berperilaku seperti yang diharapkan saat klien menampilkan pengecualian. Periksa dokumentasi setiap fungsi untuk mengetahui pengecualian yang harus Anda periksa.
- Pastikan setiap panggilan yang Anda lakukan ke klien didahului dengan pemeriksaan izin yang tepat.
- Verifikasi penerapan penomoran halaman Anda.
- Verifikasi apa yang terjadi saat Anda mengambil beberapa halaman, tetapi salah satunya memiliki token yang sudah tidak berlaku.