Vérifier un export PDF iOS sur un Mac distant avec PDFKit

Vérifier un export PDF iOS sur un Mac distant avec PDFKit

Dans une application iOS, l’utilisateur touche « Exporter » pour un rapport. Le fichier apparaît dans la feuille de partage, mais il manque une page lorsque le destinataire l’ouvre. Dans ce type de situation, constater que la fonction d’export a renvoyé un succès ne suffit pas : le test doit récupérer le PDF final, contrôler ce qui peut l’être automatiquement et réserver le reste à un examen visuel. La procédure ci-dessous convient aux tests sur simulateur exécutés sur un Mac distant, mais s’applique aussi en local.

Définir d’abord un fichier dont on peut vérifier la conformité

Choisissez des données d’entrée fixes, par exemple deux lignes de détail et un titre de rapport explicite. Le test doit connaître le nom de fichier attendu, le nombre minimal de pages et une phrase stable présente dans le corps du document. Évitez de comparer directement, sous forme de chaînes, la date de génération, un identifiant aléatoire ou le montant total : ces valeurs peuvent varier selon les données du test. Il est plus fiable de figer les données d’entrée et de définir des règles de format explicites pour les champs dynamiques.

Faites écrire le PDF par la version de test de l’application dans son propre Documents/export.pdf. Ce chemin facilite la vérification ; le produit final n’a pas besoin d’utiliser le même mode de livraison. Supprimez l’ancien fichier avant chaque exécution, puis vérifiez après l’export que le nouveau fichier existe et n’est pas vide. Sans cela, un résultat antérieur pourrait faire passer le test à tort.

L’existence du fichier, sa capacité à être analysé et l’exactitude de son contenu sont trois contrôles distincts. Réussir le premier ne dispense pas des suivants.

Récupérer le fichier produit par cette exécution du simulateur

Exécutez d’abord l’application et l’opération d’export avec l’identifiant de simulateur défini pour le test. Une fois le test terminé, interrogez le conteneur de l’application sur l’appareil correspondant à ce même identifiant. Ne vous fiez pas à booted pour deviner lequel utiliser : le risque d’erreur est particulièrement élevé lorsque plusieurs simulateurs sont démarrés. Dans l’exemple suivant, l’identifiant et l’identifiant de bundle doivent provenir de la configuration du test :

UDID="替换为测试使用的模拟器标识"
BUNDLE_ID="替换为测试应用的包名"
CONTAINER="$(xcrun simctl get_app_container "$UDID" "$BUNDLE_ID" data)" || exit 1
mkdir -p artifacts
test -s "$CONTAINER/Documents/export.pdf" || exit 1
cp "$CONTAINER/Documents/export.pdf" artifacts/export.pdf
file artifacts/export.pdf

get_app_container suppose que l’application est installée sur le simulateur indiqué. Si la requête échoue, vérifiez d’abord l’identifiant de l’appareil réellement utilisé par le test, l’identifiant de bundle et le résultat de l’installation, plutôt que de lancer une recherche sur tout le disque. Après la copie, les contrôles portent sur le fichier du répertoire de travail. Utilisez également cette copie pour l’analyse et l’archivage, afin qu’une nouvelle écriture par l’application ne modifie pas le fichier examiné. La sortie de file peut aider au diagnostic, mais ne remplace pas l’analyse du PDF.

Contrôler la structure et le texte avec PDFKit

Enregistrez le code Swift suivant dans scripts/check-pdf.swift. Il reçoit le chemin du fichier et une phrase attendue, vérifie les limites de chaque page et confirme que cette phrase figure sur au moins une page. Un code de sortie non nul permet à la tâche de build de signaler l’échec de ce contrôle automatique.

import Foundation
import PDFKit

guard CommandLine.arguments.count == 3,
      let pdf = PDFDocument(url: URL(fileURLWithPath: CommandLine.arguments[1])),
      pdf.pageCount > 0 else {
    fputs("PDF is missing or cannot be parsed\n", stderr)
    exit(2)
}

let expected = CommandLine.arguments[2]
var extracted = ""
for index in 0..<pdf.pageCount {
    guard let page = pdf.page(at: index) else {
        fputs("PDF page is missing\n", stderr)
        exit(2)
    }
    let media = page.bounds(for: .mediaBox)
    let crop = page.bounds(for: .cropBox)
    guard media.width > 0, media.height > 0,
          crop.width > 0, crop.height > 0,
          media.contains(crop) else {
        fputs("PDF page bounds are invalid\n", stderr)
        exit(2)
    }
    extracted += page.string ?? ""
}
guard extracted.contains(expected) else {
    fputs("Expected text was not extracted\n", stderr)
    exit(2)
}
print("Checked \(pdf.pageCount) PDF page(s)")

Exécutez swift scripts/check-pdf.swift artifacts/export.pdf "Quarterly Report". Remplacez la phrase d’exemple par un texte effectivement présent dans les données de test fixes. Si la spécification exige exactement deux pages, ajoutez aussi pdf.pageCount == 2 aux assertions : vérifier seulement que le nombre de pages est supérieur à zéro ne détecte pas un changement de pagination. Vous pouvez contrôler séparément les dimensions des pages selon les exigences du produit, sans toutefois rejeter des formats de papier valides qui n’ont pas été exclus au préalable.

L’extraction de texte ne vaut pas validation visuelle

page.string contrôle le texte extractible. Il ne garantit ni que les caractères ne sont pas coupés, ni que les graphiques, les images ou les couleurs sont corrects. À l’inverse, un document numérisé ou du texte dessiné sous forme d’image peut paraître normal sans fournir de texte extractible. Si l’assertion sur le texte échoue, conservez le PDF d’origine et déterminez si le contenu est absent ou si la méthode d’extraction ne convient pas à cette page. Ne supprimez pas l’assertion simplement pour faire passer le test.

Localiser précisément l’étape en échec

Consignez séparément, pour chaque exécution, le résultat de l’export, celui de la copie du fichier et le code de sortie de PDFKit. En cas d’échec, vous pourrez ainsi vérifier dans l’ordre si l’application a lancé l’export, si le conteneur contient le fichier de cette exécution, si la copie peut être analysée et si le nombre de pages, leurs limites et le texte correspondent aux attentes. Un simple message « Échec du test PDF » obligerait à relancer toute la procédure pour trouver la cause.

Symptôme À vérifier en priorité
Conteneur introuvable Identifiant du simulateur, identifiant de bundle, résultat de l’installation
Fichier vide Suppression de l’ancien fichier, fin de l’écriture
Analyse impossible Opération de copie, format du fichier final
Texte différent du texte attendu Données d’entrée fixes, contenu des pages, limites de l’extraction de texte

En cas d’échec, archivez artifacts/export.pdf et les journaux du test, mais vérifiez d’abord que le rapport ne contient pas de données réelles d’utilisateurs. Si le fichier risque de contenir des informations sensibles, utilisez un échantillon synthétique, limitez l’accès aux résultats et supprimez-les selon les règles de l’équipe. Ne publiez pas de rapports de production parmi les artefacts d’un pipeline public.

Terminer par une exécution reproductible et vérifiable

Avant de soumettre la procédure de validation, exécutez-la deux fois de suite avec les mêmes données d’entrée fixes. Chaque exécution doit relancer l’export, écraser le fichier cible et produire les mêmes résultats pour le nombre de pages et le contrôle du texte. Retirez ensuite volontairement la phrase attendue pour confirmer que le script échoue. Faites aussi en sorte que l’application de test ne génère aucun fichier et confirmez que l’étape de copie échoue. Ces deux tests négatifs permettent d’écarter le cas où les assertions ne seraient jamais exécutées.

Même après la réussite des contrôles automatiques, ouvrez un PDF représentatif pour examiner les sauts de page, les retours à la ligne des textes longs et les bords des graphiques. À la machine les exigences stables de structure et de texte ; à la personne, la vérification du rendu réel. Consignez ces conclusions séparément pour disposer d’une base de comparaison claire lors du prochain incident d’export.

Questions fréquentes

Une extraction de texte vide signifie-t-elle que le PDF est invalide ?

Non. Du texte dessiné comme image ou certaines polices peuvent empêcher l’extraction. Conservez le fichier et vérifiez aussi son rendu.

Comment récupérer le PDF créé dans le simulateur ?

Faites écrire le fichier dans Documents par l’app, localisez son conteneur avec simctl get_app_container, puis copiez-le dans les artefacts du job.

Confiez votre prochain build à un Mac cloud dédié.

Comparez les modèles, les régions et les durées de location ViewMini, puis choisissez un nœud physique adapté à votre workflow.

Configurer un Mac cloud

Comparez les équipements et les durées de location.

Les trois modèles disponibles proposent des tarifs à la journée, à la semaine, au mois ou au trimestre. Consultez les offres complètes avant de commander.

Voir les modèles et les tarifs Configurer un Mac cloud