Les fonctions de sélection d’une adresse de livraison, de vérification de la zone desservie par un magasin ou d’alerte par géorepérage passent souvent sans difficulté après quelques manipulations sur une machine de développement, puis commencent à échouer de manière intermittente dans un pipeline sans intervention humaine. Le problème vient généralement non pas de l’algorithme de localisation, mais du simulateur, qui a conservé les coordonnées ou les autorisations de la tâche précédente, voire un trajet toujours en cours. Pour rendre les tests de localisation reproductibles sur un Mac cloud, il faut traiter la « position » comme une donnée de test à créer et à détruire explicitement, et non comme un simple élément de l’environnement du simulateur.
Séparer les objectifs de validation en trois niveaux
Un même test d’interface ne doit pas prendre en charge à la fois le calcul des coordonnées, l’intégration avec le service de localisation du système et les assertions sur l’interface. Une organisation en trois niveaux est plus robuste :
- Utiliser des tests unitaires ordinaires pour vérifier les distances, les zones et les transitions d’état en leur transmettant directement des coordonnées construites pour le test.
- Utiliser un nombre limité de tests sur simulateur pour confirmer que les données de localisation du système arrivent bien dans l’application et déclenchent l’écran attendu.
- Valider sur des appareils réels le réveil en arrière-plan, la dérive du signal, la consommation d’énergie et les comportements liés aux capteurs.
Commencez par définir une interface d’entrée très étroite pour la couche métier. Le service de localisation peut, par exemple, ne fournir que les coordonnées, l’heure et l’état de l’autorisation. La logique de géorepérage ne doit pas être dispersée directement dans les contrôleurs de vue. Ainsi, la grande majorité des cas limites peut être testée sans lancer de simulateur ; seule l’intégration avec le système dépend de simctl location.
Des coordonnées simulées permettent de vérifier comment l’application traite une position donnée, mais elles ne prouvent pas que l’environnement radio réel fournira les événements de localisation au même rythme.
Préparer un simulateur indépendant pour chaque tâche
Commencez par fixer le chemin de Xcode, puis répertoriez les types d’appareils et les runtimes réellement installés sur la machine. Ne conservez pas définitivement en dur l’identifiant de runtime utilisé dans l’exemple, car il peut changer après une mise à niveau de Xcode.
sudo xcode-select -s /Applications/Xcode.app
xcrun simctl list devicetypes
xcrun simctl list runtimes
Le pipeline doit créer un ensemble d’appareils CoreSimulator indépendant et enregistrer l’UDID généré pour la tâche en cours. Dans l’exemple suivant, remplacez le type d’appareil et l’identifiant du runtime par les valeurs réellement renvoyées par les commandes précédentes.
set -euo pipefail
DEVICE_SET="$PWD/.simulator-location-tests"
DEVICE_TYPE="com.apple.CoreSimulator.SimDeviceType.iPhone-16"
RUNTIME="com.apple.CoreSimulator.SimRuntime.iOS-18-0"
rm -rf "$DEVICE_SET"
UDID="$(xcrun simctl --set "$DEVICE_SET" create GeoTest "$DEVICE_TYPE" "$RUNTIME")"
xcrun simctl --set "$DEVICE_SET" boot "$UDID"
xcrun simctl --set "$DEVICE_SET" bootstatus "$UDID" -b
Un ensemble d’appareils indépendant facilite davantage le diagnostic que l’effacement répété d’un simulateur partagé. Le répertoire d’appareils d’une tâche en échec peut être conservé temporairement, tandis que celui d’une tâche réussie peut être supprimé immédiatement. Les tâches parallèles ne se disputent pas non plus le même appareil déjà démarré.
Injecter des coordonnées fixes et les autorisations
Les coordonnées fixes conviennent aux conditions déterministes telles que « à l’intérieur de la zone », « franchissement de la limite » ou « loin du point cible ». Il faut d’abord installer l’application, préconfigurer les autorisations et définir les coordonnées, puis lancer la cible de test. Si les autorisations sont modifiées après le démarrage de l’application, le premier écran peut déjà avoir enregistré l’état non autorisé.
BUNDLE_ID="com.example.LocationDemo"
xcrun simctl --set "$DEVICE_SET" privacy "$UDID" grant location "$BUNDLE_ID"
xcrun simctl --set "$DEVICE_SET" location "$UDID" set 1.290270,103.851959
xcodebuild test \
-workspace LocationDemo.xcworkspace \
-scheme LocationDemo \
-destination "platform=iOS Simulator,id=$UDID" \
-resultBundlePath "$PWD/TestResults/LocationTests.xcresult"
Un test de limite ne doit pas reposer sur un seul point. Prévoyez au minimum trois groupes de coordonnées : à l’intérieur de la zone, à proximité de la limite et à l’extérieur. Les données de test doivent aussi indiquer clairement le résultat attendu, au lieu de le masquer derrière des noms comme case1 ou case2.
| Scénario | Conception de l’entrée | Assertion recommandée |
|---|---|---|
| Dans la zone | Distance au centre nettement inférieure au seuil | L’état reste stable à l’intérieur de la zone |
| Près de la limite | Un point de chaque côté du seuil | Les règles de comparaison et d’arrondi sont cohérentes |
| Hors de la zone | Distance au centre nettement supérieure au seuil | Aucune action réservée à la zone intérieure n’est déclenchée |
| Autorisation désactivée | Révocation de l’autorisation de localisation | Affichage d’un état d’accompagnement permettant de rétablir l’accès |
Si l’application met en cache la dernière position, effacez ses données avant chaque cas de test ou désactivez le cache persistant à l’aide d’un argument de lancement de test. Dans le cas contraire, l’ancienne valeur risque de remplacer les nouvelles coordonnées.
Vérifier l’ordre des déplacements avec un fichier GPX
Les déplacements continus doivent être décrits dans des fichiers GPX courts et lisibles. Ne conservez que les points de passage nécessaires pour déclencher les transitions d’état essentielles, sans reproduire tout un trajet réel. Le fichier suivant décrit un déplacement de l’extérieur vers l’intérieur de la zone :
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="location-ci">
<wpt lat="1.320000" lon="103.820000">
<name>outside</name>
</wpt>
<wpt lat="1.290270" lon="103.851959">
<name>inside</name>
</wpt>
</gpx>
Lors de l’exécution du trajet, les assertions doivent porter sur l’ordre des événements plutôt que dépendre de délais d’attente précis à la seconde près.
xcrun simctl --set "$DEVICE_SET" location "$UDID" start "$PWD/Fixtures/enter-region.gpx"
xcodebuild test \
-workspace LocationDemo.xcworkspace \
-scheme LocationRouteTests \
-destination "platform=iOS Simulator,id=$UDID"
xcrun simctl --set "$DEVICE_SET" location "$UDID" stop
L’application peut enregistrer une séquence d’états expurgée des données sensibles, par exemple outside → approaching → inside, et associer à chaque changement un temps croissant de façon monotone. N’inscrivez pas les coordonnées complètes dans les journaux conservés à long terme. Pour documenter un échec, le nom du cas de test, la zone attendue, l’état réel et un nombre limité de décimales suffisent.
Nettoyer l’état et conserver les éléments de diagnostic
Le nettoyage ne doit pas être exécuté uniquement en cas de réussite. Enregistrez un gestionnaire de sortie dès le début du script afin d’arrêter le trajet, d’effacer la localisation et d’éteindre l’appareil. La suppression de l’ensemble d’appareils dépend ensuite du résultat des tests.
cleanup() {
xcrun simctl --set "$DEVICE_SET" location "$UDID" stop 2>/dev/null || true
xcrun simctl --set "$DEVICE_SET" location "$UDID" clear 2>/dev/null || true
xcrun simctl --set "$DEVICE_SET" shutdown "$UDID" 2>/dev/null || true
}
trap cleanup EXIT
En cas d’échec, archivez le fichier xcresult, les journaux de l’application, le fichier GPX utilisé, les identifiants de l’appareil et du runtime, ainsi que l’état des autorisations avant le début du test. Les captures d’écran peuvent faciliter le diagnostic, mais elles ne remplacent pas des assertions structurées. Si le test échoue plusieurs fois avec les mêmes coordonnées, vérifiez d’abord que l’ensemble d’appareils est réellement isolé, que le Bundle ID est correct et que l’autorisation a été accordée avant le lancement. Examinez ensuite les calculs métier.
Un pipeline de tests de localisation stable doit finalement garantir des entrées lisibles, un état de simulateur à usage unique, l’arrêt systématique des trajets et la possibilité de tester unitairement la logique métier sans dépendre du service de localisation du système. Lorsqu’un échec survient, l’équipe dispose alors d’un écart d’état explicite, plutôt que d’un simple constat impossible à reproduire selon lequel « la localisation est parfois imprécise ».
Questions fréquentes
L’injection de position avec simctl remplace-t-elle les essais sur appareil réel ?
Non. Elle valide efficacement les règles métier et l’interface, mais le réveil en arrière-plan, les variations du signal, la consommation et les capteurs doivent encore être testés sur appareil réel.
Pourquoi un test de localisation échoue-t-il uniquement dans la suite CI complète ?
Un simulateur partagé conserve souvent une autorisation, une position ou un trajet précédent. Utilisez un ensemble d’appareils par tâche et nettoyez explicitement chaque état avant et après le test.
Quand choisir une coordonnée fixe plutôt qu’un trajet GPX ?
La coordonnée fixe convient aux assertions déterministes sur une zone ou une limite. Le GPX sert à vérifier une succession de déplacements, sans imposer une heure d’arrivée exacte à la seconde.
Déployez vos workflows validés sur un Mac cloud disponible en continu
Choisissez BookaMac M4 ou BookaMac M4 Pro selon votre usage, puis vérifiez la région, la durée de location et les options de stockage au moment de la commande.