XCResult - comment et pourquoi lire





En 2018, Apple a pour la prochaine (troisième) fois mis à jour le format dans lequel les informations sur le test sont publiées. Si auparavant c'était un fichier plist, qui était un gros xml, maintenant c'est un gros fichier avec l'extension xcresult, qui s'ouvre via Xcode et contient un tas d'informations utiles, en commençant par les résultats des tests avec des journaux, des captures d'écran et se terminant par la couverture cible , des informations de diagnostic sur l'assemblage et bien plus encore. La plupart des développeurs ne travaillent pas avec cela tous les jours, mais les créateurs d'infrastructure de cet article pourraient trouver quelque chose d'utile.



Décrivons les avantages et les inconvénients de la mise à jour du format



Quels sont les inconvénients de la mise à jour du format?



  • Cela pèse beaucoup, ce qui signifie que l'échange de tels fichiers avec le serveur CI peut être long.
  • S'il n'y a pas de Xcode, alors il ne s'ouvrira pas (il est douteux que le testeur ou le développeur n'aura pas Xcode, mais quand même).
  • Panne possible des outils d'intégration existants. Apprendre à travailler à nouveau avec quelque chose de nouveau.


Comment le nouveau xcresult est-il pratique?



  • S'ouvre nativement via Xcode.
  • Vous pouvez transférer à des collègues de l'assurance qualité et du développement, même s'ils n'ont pas de projet local. Tout s'ouvrira et affichera les informations dont vous avez besoin.
  • Contient des informations complètes sur l'exécution des tests.
  • Peut être lu non seulement via Xcode.


Nous parlerons du dernier point de cet article.



Pourquoi lire XCResult en dehors de Xcode?



Si votre entreprise a mis en place des processus CI&CD, vous collectez probablement des métriques sur les constructions de projet, la stabilité et le nombre de tests, et, bien sûr, les données de couverture des tests. Très probablement, quelque part sur Bamboo, Jenkins, Github, vous avez abandonné les tests ou le statut CI, ou le pourcentage de couverture. Il est d'usage d'automatiser de telles opérations et de les laisser à la merci de machines sans âme. Quels outils avons-nous pour cela?

Apple, avec la sortie du nouveau format, a publié les outils xcresulttool et xccov, avec lesquels vous pouvez travailler à partir du terminal.



Que pouvons-nous obtenir en utilisant xccov?



xcrun xccov view --report --json /path/to/your/TestScheme.xcresult







La requête renverra des informations complètes sur la couverture de toutes les cibles, les méthodes et les classes couvertes, le nombre de fois qu'elles ont été exécutées et les lignes exécutées. Les objets ont une structure similaire. Il y a 4 niveaux au total: racine, cible, fichier, fonction. Tous les niveaux sauf la racine ont un champ de nom. Tous les niveaux ont des champs CoverLines et lineCoverage. Il est important de noter que les objets ont leur propre contexte. La structure entière peut être décrite dans plusieurs protocoles.







En plus des protocoles, nous mettons en évidence les structures suivantes: CoverageReport - agrégateur de tout et racine. Il contient un tableau d'objets Target. Chaque cible contient un tableau de File, qui, à son tour, contient un tableau de Function. Ces objets implémenteront les protocoles décrits ci-dessus.

Nous sommes intéressés par le champ lineCoverage. Pour composer un beau rapport (comme dans fastlane), tournez-vous vers le champ lineCoverage et parcourez tous les objets avec une fonction simple:







Nous obtiendrons quelque chose de similaire à:



Coverage Report Summary:

• Utils.framework: 51,04 %

• NavigationAssistantKit.framework: 0,0 %

• NavigationKit.framework: 35,85 %

• Logger.framework: 20,32 %

• FTCCardData.framework: 78,21 %

• FTCFeeSDK.framework: 25,25 %

• ErrorPresenter.framework: 2,8 %

• MTUIKit.framework: 0,24 %

• AnalyticsKit.framework: 47,52 %

• EdaSDK.framework: 1,18 %

• Alerts.framework: 85,19 %

• Resources.framework: 39,16 %

• QpayApiTests.xctest: 88,37 %

• FTCFeeSDKTests.xctest: 97,91 %
      
      





PS Pour que la couverture soit collectée, vous devez ajouter le paramètre -enableCodeCoverage YES à votre équipe de test ou l'activer dans les paramètres du schéma dans Xcode.



Quelles opportunités offrira xcresulttool?



En fait, xcresulttool n'a pas une très grande interface, mais vous pouvez en obtenir beaucoup d'informations si vous connaissez la structure de xcresult. Et c'est toute une base de données à laquelle vous pouvez faire des requêtes.



C'est une bonne idée de commencer avec l'interface elle-même:



xcrun xcresulttool --help

OVERVIEW: Xcode Result Bundle Tool (version 16015)

USAGE: xcresulttool subcommand [options] ...


SUBCOMMANDS:

  export                  Export File or Directory from Result Bundle

  formatDescription       Result Bundle Format Description

  get                     Get Result Bundle Object

  graph                   Print Result Bundle Object Graph

  merge                   Merge Result Bundles

  metadata                Result Bundle Metadata

  version                 XCResultKit Version
      
      





Pour lire la structure, il suffit d'appeler la commande:



xcrun xcresulttool get --path /path/to/your/res.xcresult --format json
      
      





C'est là que nous obtenons la «table des matières» de notre bundle xcresult. Qu'est-ce qui se passait, quels tests ont été exécutés, combien de temps cela a pris, où sont les captures d'écran et les journaux, et quels étaient les avertissements du compilateur. L'essentiel pour nous est d'obtenir les identifiants de fichiers contenant des informations sur les tests.



xcrun xcresulttool get --path /path/to/your/res.xcresult --format json --id {id}
      
      





Ensuite, nous obtiendrons des objets avec des cibles de test, des types de tests, qui sont divisés en classes de test et combinaisons de test avec des rapports avec des journaux, des captures d'écran, le temps d'exécution et d'autres informations pour chaque test.



Malheureusement, la raison de l'échec des tests rouges ne sera pas facile à extraire - pour cela, vous devez faire une autre requête pour chaque test échoué (et en fait, même pas une!!



Pour le résumé des échecs, la même requête est utilisée :



xcrun xcresulttool get --path /path/to/your/res.xcresult --format json --id {id}







Mais pour les journaux de crash, vous devez supprimer --format json de la requête, car il n'y a qu'une chaîne et lors du passage du formateur, l'outil générera une erreur.



Que faire ensuite de ces connaissances de base?



Automatisez, bien sûr! Si vous essayez ces commandes, vous verrez que les réponses sont gigantesques et difficiles à lire. Comment automatiser? Ruby, Python ... ou Swift?

Bien sûr, rapide. Tout développeur iOS moderne le sait. Le projet s'ouvre dans Xcode, le débogage, la coloration syntaxique, le typage fort sont disponibles. Bref, un rêve! Surtout avec l'avènement du gestionnaire de paquets Swift.



Ce n'est un secret pour personne qu'avec Swift, nous pouvons facilement lancer des processus, écouter les erreurs et obtenir des résultats. Dans le cas le plus simple, nous pouvons nous en tirer avec une telle construction:







il ne nous reste plus qu'à explorer le format XCResult à travers les déjà familiers xcrun xcov et xcrun xcresulttool. Par exemple, pour lire la couverture des tests, nous utilisons:







Et pour obtenir la table des matières XCResult, nous devons exécuter:







Mais comment pouvons-nous obtenir nos précieuses structures CoverageReport et XCResult?

Nous obtenons une chaîne de Data, que la première commande Shell nous retournera et mettra le contenu ici: quicktype.io .



Le service nous générera quelque chose de similaire aux structures rapides requises. Certes, vous ne pourrez pas utiliser le résultat «tel quel». Nous devrons étudier la structure de la réponse de plus près et éliminer les doublons. Néanmoins, un tel travail n'est pas difficile. Vous pouvez supprimer les pièces inutiles ou faire des recherches et mettre en évidence quelques éléments de base:







sur cette base, décrivez le reste des structures, par exemple:







ou même de telles informations sur les ordinateurs sur lesquels l'analyse a été effectuée:







Eh bien, comment l'utiliser?



Il existe deux façons d'utiliser notre grattoir. Le premier est en tant qu'exécutable, et c'est là que la bibliothèque Swift-argument-parser d'Apple est utile. Avant cela, nous devions écrire nous-mêmes le traitement des arguments, le couvrir de tests et le supporter. Maintenant, ce travail a été repris par une bibliothèque populaire, dont les responsables peuvent être dignes de confiance.



Il existe deux commandes: obtenir un rapport de couverture de test et générer un rapport de test junit. Vous devez construire le projet et exécuter le binaire, en passant les arguments nécessaires:







La deuxième façon consiste à utiliser ce projet comme une bibliothèque. Nous avons un grand projet CI qui est responsable de l'assemblage, du test et de l'expédition de notre produit KoronaPay. Par exemple, sur la base des résultats des tests réussis, nous pouvons extraire tous les échecs d'assertion et les plantages dans des tests comme celui-ci:







Ou obtenir des tests rouges, analyser les flacons et ne redémarrer qu'eux.

Comment analyser? Tout est simple et pas facile à la fois. Pour obtenir les détails de la raison de l'échec du test, vous devez faire une demande supplémentaire à xcresult à l'aide de l'identificateur de résumé de l'échec. Et puis extrayez les informations du résumé de l'échec. Pour le moment, nous avons appris à rechercher les plantages dans les tests et les cas de perte de connexion, ainsi qu'à en extraire les raisons. Il n'est pas difficile de comprendre qu'un crash s'est produit. Vous avez juste besoin de trouver les mots précieux qui se sont écrasés dans FailSummaries.







Il est un peu plus difficile de trouver la cause de l'accident.



C'est là que le mécanisme de réflexion de Swift est utile, ce qui, bien que quelque peu limité, est idéal pour résoudre ce problème. Recherchez tous les objets Attachment nommés kXCTAttachmentLegacyDiagnosticReportData.







Il n'y a rien de magique dans la méthode reflectProperties, c'est une simple extension pour Mirror: une







autre catégorie de tests rouges est celle des assertions. Contrairement aux plantages, vous ne pouvez pas simplement rechercher la chaîne «crashed in» ici. Ces tests peuvent être déguisés en cas de perte de connexion. Pour aller au fond de la raison, vous devez parcourir plusieurs tableaux à l'intérieur de l'objet TestCase comme ceci:







Pour de telles opérations, notre bibliothèque a une entité TestsInspector qui peut fournir un résumé des tests rouges. Ainsi, les tests rouges sont regroupés par caractéristiques dans le rapport.







Au lieu d'une conclusion



Comme toutes les solutions existantes dans ce domaine, notre scrapper n'est pas un outil exhaustif d'analyse d'xcresult. Pour obtenir toutes les informations et voir les captures d'écran, vous devez toujours ouvrir xcresult via Xcode. Cependant, si vous avez configuré CI et que vous souhaitez voir les résultats des tests rapidement, vous pourrez probablement apprécier la combinaison de junit et de notre xcscrapper à sa juste valeur.



All Articles