ספריית הבדיקות של Health Connect (androidx.health.connect:connect-testing
)
מפשטת את יצירת הבדיקות האוטומטיות. אפשר להשתמש בספרייה הזו כדי לאמת את ההתנהגות של האפליקציה ולוודא שהיא מגיבה בצורה נכונה למקרים לא שכיחים, שקשה לבדוק באופן ידני.
אפשר להשתמש בספרייה כדי ליצור בדיקות יחידה מקומיות, שבדרך כלל מאמתות את ההתנהגות של המחלקות באפליקציה שמתקשרות עם לקוח Health Connect.
כדי להתחיל להשתמש בספרייה, מוסיפים אותה כתלות לבדיקה:
testImplementation("androidx.health.connect:connect-testing:1.0.0-alpha01")
נקודת הכניסה לספרייה היא המחלקה FakeHealthConnectClient
, שבה משתמשים בבדיקות כדי להחליף את HealthConnectClient
. FakeHealthConnectClient
כולל את התכונות הבאות:
- ייצוג בזיכרון של רשומות, כך שאפשר להוסיף, להסיר, למחוק ולקרוא אותן
- יצירה של טוקנים לשינויים ומעקב אחר שינויים
- חלוקה לעמודים של רשומות ושינויים
- תשובות של צבירה נתמכות באמצעות placeholder
- מאפשר לכל פונקציה להציג חריגים
FakePermissionController
שאפשר להשתמש בו כדי לבצע בדיקות הרשאות
מידע נוסף על החלפת יחסי תלות בבדיקות זמין במאמר בנושא הזרקת תלות ב-Android. במאמר שימוש ב-test doubles ב-Android אפשר לקרוא מידע נוסף על זיופים.
לדוגמה, אם המחלקה שמבצעת אינטראקציה עם הלקוח נקראת HealthConnectManager
והיא מקבלת את HealthConnectClient
כתלות, היא תיראה כך:
class HealthConnectManager(
private val healthConnectClient: HealthConnectClient,
...
) { }
בבדיקות, אפשר להעביר fake למחלקה שנבדקת במקום זאת:
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)
}
}
הבדיקה הזו מוודאת שהפונקציה הדמיונית fetchReport
ב-HealthConnectManager
מסננת רשומות לפי פעילות בצורה תקינה.
אימות חריגים
כמעט כל קריאה ל-HealthConnectClient
יכולה להחזיר חריגים. לדוגמה,
בתיעוד של insertRecords
מוזכרים החריגים הבאים:
@throws android.os.RemoteException
לכל כשל בהעברת נתונים בין תהליכים.@throws SecurityException
לבקשות עם גישה לא מורשית.@throws java.io.IOException
לבעיות קלט/פלט בדיסק.
החריגים האלה כוללים מקרים כמו חיבור גרוע או חוסר מקום במכשיר. האפליקציה צריכה להגיב בצורה נכונה לבעיות האלה בזמן הריצה, כי הן יכולות לקרות בכל שלב.
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)
}
צבירה
אין הטמעות מזויפות של קריאות מצטברות. במקום זאת, קריאות מצטברות משתמשות ב-stubs שאפשר לתכנת כך שיתנהגו בצורה מסוימת. אפשר לגשת ל-stub דרך המאפיין overrides
של FakeHealthConnectClient
.
לדוגמה, אפשר לתכנת את הפונקציה המצטברת כך שתחזיר תוצאה ספציפית:
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)
לאחר מכן, תוכלו לוודא שהכיתה שנבדקת, HealthConnectManager
במקרה הזה, עיבדה את התוצאה בצורה נכונה:
// 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)
הרשאות
ספריית הבדיקה כוללת את FakePermissionController
, שאפשר להעביר אותו כתלות אל FakeHealthConnectClient
.
הנבדקים יכולים להשתמש במאפיין PermissionController—through
the
permissionController
של ממשק HealthConnectClient
כדי לבדוק הרשאות. הפעולה הזו מתבצעת בדרך כלל לפני כל שיחה ללקוח.
כדי לבדוק את הפונקציונליות הזו, אפשר להגדיר אילו הרשאות יהיו זמינות באמצעות 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)
}
עימוד
החלוקה לדפים היא מקור נפוץ מאוד לבאגים, ולכן FakeHealthConnectClient
מספקת מנגנונים שיעזרו לכם לוודא שההטמעה של החלוקה לדפים עבור
רשומות ושינויים מתבצעת בצורה תקינה.
הנושא שנבדק, HealthConnectManager
בדוגמה שלנו, יכול לציין את גודל הדף ב-ReadRecordsRequest
:
fun fetchRecordsReport(pageSize: Int = 1000) }
val pagedRequest =
ReadRecordsRequest(
timeRangeFilter = ...,
recordType = ...,
pageToken = page1.pageToken,
pageSize = pageSize,
)
val page = client.readRecords(pagedRequest)
...
הגדרת גודל הדף לערך קטן, כמו 2, מאפשרת לכם לבדוק את המספור של הדפים. לדוגמה, אפשר להוסיף 5 רשומות כך שהפונקציה readRecords
תחזיר 3 דפים שונים:
@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)
}
נתונים לבדיקה
הספרייה עדיין לא כוללת ממשקי API ליצירת נתונים מזויפים, אבל אפשר להשתמש בנתונים ובגנרטורים שבה בחיפוש קוד ב-Android.
כדי ליצור ערכי מטא-נתונים מדומים בבדיקות, אפשר להשתמש ב-MetadataTestHelper
. הפונקציה הזו מספקת את פונקציית ההרחבה populatedWithTestValues()
, שמדמה את האכלוס של ערכי המטא-נתונים על ידי Health Connect במהלך הוספת הרשומה.
כרטיסים
המאפיין overrides
של FakeHealthConnectClient
מאפשר לתכנת (או לסמן כ-stub) כל אחת מהפונקציות שלו כך שהן יחזירו חריגים כשהן מופעלות.
קריאות לצירוף יכולות להחזיר גם נתונים שרירותיים, והן תומכות בהוספה לתור של כמה תגובות. מידע נוסף זמין במאמרים בנושא Stub
וMutableStub
.
סיכום של מקרי קצה
- מוודאים שהאפליקציה מתנהגת כצפוי כשהלקוח שולח חריגות. כדאי לעיין בתיעוד של כל פונקציה כדי להבין אילו חריגים צריך לבדוק.
- מוודאים שלפני כל קריאה ללקוח מתבצעת בדיקת ההרשאות המתאימה.
- בודקים את ההטמעה של המספור.
- בודקים מה קורה כשמאחזרים כמה דפים אבל לאחד מהם יש טוקן שתוקפו פג.