La bibliothèque de test Santé Connect (androidx.health.connect:connect-testing
) simplifie la création de tests automatisés. Vous pouvez utiliser cette bibliothèque pour vérifier le comportement de votre application et valider qu'elle répond correctement aux cas inhabituels, qui sont difficiles à tester manuellement.
Vous pouvez utiliser la bibliothèque pour créer des tests unitaires locaux, qui vérifient généralement le comportement des classes de votre application qui interagissent avec le client Health Connect.
Pour commencer à utiliser la bibliothèque, ajoutez-la en tant que dépendance de test :
testImplementation("androidx.health.connect:connect-testing:1.0.0-alpha01")
Le point d'entrée de la bibliothèque est la classe FakeHealthConnectClient
, que vous utilisez dans les tests pour remplacer HealthConnectClient
. FakeHealthConnectClient
présente les caractéristiques suivantes :
- Représentation en mémoire des enregistrements, qui vous permet de les insérer, de les supprimer et de les lire
- Génération de jetons de modification et suivi des modifications
- Pagination pour les enregistrements et les modifications
- Les réponses d'agrégation sont acceptées avec les stubs.
- Autorise toute fonction à générer des exceptions
- Un
FakePermissionController
pouvant être utilisé pour émuler les vérifications des autorisations
Pour en savoir plus sur le remplacement des dépendances dans les tests, consultez Injection de dépendances dans Android. Pour en savoir plus sur les faux, consultez Utiliser des doubles de test sur Android.
Par exemple, si la classe qui interagit avec le client est appelée HealthConnectManager
et qu'elle prend un HealthConnectClient
comme dépendance, elle ressemblerait à ceci :
class HealthConnectManager(
private val healthConnectClient: HealthConnectClient,
...
) { }
Dans les tests, vous pouvez transmettre un faux à votre classe en cours de test :
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)
}
}
Ce test vérifie que la fonction fictive fetchReport
dans HealthConnectManager
filtre correctement les enregistrements par activité.
Vérifier les exceptions
Presque tous les appels à HealthConnectClient
peuvent générer des exceptions. Par exemple, la documentation de insertRecords
mentionne les exceptions suivantes :
@throws android.os.RemoteException
pour tout échec de transport IPC.@throws SecurityException
pour les demandes avec accès non autorisé.@throws java.io.IOException
pour tout problème d'E/S de disque.
Ces exceptions couvrent des cas tels qu'une mauvaise connexion ou un espace de stockage insuffisant sur l'appareil. Votre application doit réagir correctement à ces problèmes d'exécution, car ils peuvent survenir à tout moment.
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)
}
Agrégation
Les appels d'agrégation n'ont pas d'implémentations fictives. Au lieu de cela, les appels d'agrégation utilisent des stubs que vous pouvez programmer pour qu'ils se comportent d'une certaine manière. Vous pouvez accéder aux stubs via la propriété overrides
de FakeHealthConnectClient
.
Par exemple, vous pouvez programmer la fonction d'agrégation pour qu'elle renvoie un résultat spécifique :
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)
Vous pouvez ensuite vérifier que votre classe testée, HealthConnectManager
dans ce cas, a correctement traité le résultat :
// 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)
Autorisations
La bibliothèque de test inclut un FakePermissionController
, qui peut être transmis en tant que dépendance à FakeHealthConnectClient
.
Votre sujet de test peut utiliser la propriété permissionController
de l'interface HealthConnectClient
pour vérifier les autorisations.PermissionController—through
Cette opération est généralement effectuée avant chaque appel au client.
Pour tester cette fonctionnalité, vous pouvez définir les autorisations disponibles à l'aide de 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)
}
Pagination
La pagination est une source très courante de bugs. FakeHealthConnectClient
fournit donc des mécanismes pour vous aider à vérifier que votre implémentation de la pagination pour les enregistrements et les modifications se comporte correctement.
Votre sujet de test, HealthConnectManager
dans notre exemple, peut spécifier la taille de la page dans ReadRecordsRequest
:
fun fetchRecordsReport(pageSize: Int = 1000) }
val pagedRequest =
ReadRecordsRequest(
timeRangeFilter = ...,
recordType = ...,
pageToken = page1.pageToken,
pageSize = pageSize,
)
val page = client.readRecords(pagedRequest)
...
Définir une petite taille de page, par exemple 2, vous permet de tester la pagination. Par exemple, vous pouvez insérer cinq enregistrements pour que readRecords
renvoie trois pages différentes :
@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)
}
Données de test
La bibliothèque n'inclut pas encore d'API permettant de générer de fausses données, mais vous pouvez utiliser les données et les générateurs utilisés par la bibliothèque dans Android Code Search.
Pour simuler des valeurs de métadonnées dans les tests, vous pouvez utiliser MetadataTestHelper
. Cela fournit la fonction d'extension populatedWithTestValues()
, qui simule Health Connect en remplissant les valeurs de métadonnées lors de l'insertion d'enregistrements.
Stubs
La propriété overrides
de FakeHealthConnectClient
vous permet de programmer (ou de créer des stubs) n'importe laquelle de ses fonctions afin qu'elles génèrent des exceptions lorsqu'elles sont appelées.
Les appels d'agrégation peuvent également renvoyer des données arbitraires et permettent de mettre en file d'attente plusieurs réponses. Pour en savoir plus, consultez Stub
et MutableStub
.
Résumé des cas limites
- Vérifiez que votre application se comporte comme prévu lorsque le client génère des exceptions. Consultez la documentation de chaque fonction pour déterminer les exceptions à vérifier.
- Vérifiez que chaque appel que vous effectuez au client est précédé de la vérification des autorisations appropriée.
- Vérifiez l'implémentation de la pagination.
- Vérifiez ce qui se passe lorsque vous récupérez plusieurs pages, mais que l'une d'elles possède un jeton expiré.