Bibliothèque de tests 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 vérifier qu'elle répond correctement
les cas rares, qui sont
difficiles à tester manuellement.
Elle vous permet de créer des tests unitaires locaux, qui vérifient généralement le comportement des classes de votre application qui interagissent avec Santé Connect client.
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
à utiliser dans les tests pour remplacer HealthConnectClient
. FakeHealthConnectClient
présente les caractéristiques suivantes:
- Une représentation en mémoire des enregistrements, de sorte que vous pouvez insérer, supprimer, supprimer et 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 compatibles avec les bouchons
- Autorise toutes les fonctions à générer des exceptions
- Un élément
FakePermissionController
qui peut être utilisé pour émuler des vérifications d'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 contrefaçons, consultez Utiliser des doubles de test sous Android
Par exemple, si la classe qui interagit avec le client est appelée
HealthConnectManager
et utilise un HealthConnectClient
comme dépendance, il
ressemblerait à ceci:
class HealthConnectManager(
private val healthConnectClient: HealthConnectClient,
...
) { }
Lors des tests, vous pouvez transmettre un objet fictif à votre classe testée à la place:
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 fetchReport
fictive 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 pour insertRecords
mentionne ces exceptions:
@throws android.os.RemoteException
pour les échecs de transport IPC.@throws SecurityException
pour les requêtes avec accès non autorisé.@throws java.io.IOException
pour tout problème d'E/S de disque.
Ces exceptions s'appliquent en cas de mauvaise connexion ou de manque d'espace sur le appareil. Votre application doit réagir correctement à ces problèmes d'exécution, car ils peuvent à 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. À la place, les appels d'agrégation
utiliser des bouchons que vous pouvez programmer
pour qu’ils se comportent d’une certaine manière. Vous pouvez accéder
bouchons 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 la classe testée, HealthConnectManager
, dans ce
a traité correctement 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
.
Le sujet testé peut utiliser PermissionController—through
le
Propriété permissionController
de l'interface HealthConnectClient
, pour vérifier
pour les autorisations. 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 en utilisant
le 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 de bugs très courante. FakeHealthConnectClient
fournit des mécanismes permettant de vérifier que votre implémentation de pagination pour
les enregistrements et les modifications
se comportent correctement.
Votre objet testé, HealthConnectManager
dans notre exemple, peut spécifier le
taille de 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 la taille de la page sur une valeur faible (2, par exemple) vous permet de tester facilement
la pagination. Par exemple, vous pouvez insérer 5 enregistrements pour que readRecords
renvoie 3
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 des données fictives, mais vous pouvez utiliser la données et générateurs utilisés par la bibliothèque dans Android Code Search.
Souches
La propriété overrides
de FakeHealthConnectClient
vous permet de programmer
bouchon) l'une de ses fonctions, de sorte 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 prendre en charge la mise en file d'attente
plusieurs réponses. Pour en savoir plus, consultez Stub
et MutableStub
.
Récapitulatif 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 que vous doit vérifier.
- Vérifiez que chaque appel que vous effectuez au client est précédé de la chaîne vérification des autorisations.
- Vérifiez l'implémentation de la pagination.
- Vérifiez ce qui se passe lorsque vous extrayez plusieurs pages, mais que l'une d'elles a expiré à partir d'un jeton d'accès.