iOS-PDF-Exporte auf einem Cloud-Mac mit PDFKit prüfen

iOS-PDF-Exporte auf einem Cloud-Mac mit PDFKit prüfen

In einer iOS-App wurde für einen Bericht auf „Exportieren“ getippt. Die Teilen-Ansicht zeigte eine Datei an, doch beim Öffnen stellte der Empfänger fest, dass eine Seite fehlte. In einem solchen Fall reicht es nicht, nur den erfolgreichen Rückgabewert der Exportfunktion zu prüfen: Der Testlauf muss die fertige PDF-Datei erhalten, maschinell prüfbare Inhalte kontrollieren und alles Weitere einer Sichtprüfung überlassen. Der folgende Ablauf eignet sich für Simulatortests auf einem Cloud-Mac und lässt sich ebenso lokal durchführen.

Zuerst ein prüfbares Ergebnis festlegen

Wählen Sie feste Eingabedaten, zum Beispiel zwei Positionen und einen eindeutig vorgegebenen Berichtstitel. Der Test sollte den erwarteten Dateinamen, die Mindestseitenzahl und eine unveränderliche Textpassage kennen. Prüfen Sie Erstellungszeitpunkt, zufällige Kennung oder Gesamtsumme nicht über einen festen Zeichenkettenvergleich: Diese Felder können sich mit den Testdaten ändern. Verlässlicher ist es, die Eingabedaten festzulegen und für dynamische Felder gesondert klare Formatregeln zu definieren.

Lassen Sie die Testversion der App das PDF in ihrem eigenen Documents/export.pdf speichern. Das vereinfacht die Abnahme; das fertige Produkt muss die Datei nicht auf demselben Weg bereitstellen. Löschen Sie vor jedem Lauf die alte Datei und prüfen Sie nach dem Export, ob die neue Datei vorhanden und nicht leer ist. Sonst könnte ein Ergebnis aus dem vorherigen Lauf den aktuellen Test fälschlich bestehen lassen.

Eine vorhandene Datei, ein lesbares PDF und korrekte Inhalte sind drei verschiedene Prüfungen. Eine bestandene Prüfung ersetzt nicht die nächste.

Die Datei des aktuellen Testlaufs aus dem Simulator holen

Führen Sie die App und den Export zunächst in dem Simulator aus, dessen Kennung der Testlauf vorgibt. Fragen Sie nach Abschluss des Testlaufs den App-Container auf dem Gerät mit genau dieser Kennung ab. Verwenden Sie nicht booted, um das Zielgerät zu erraten: Gerade wenn mehrere Simulatoren gleichzeitig laufen, ist eine Verwechslung leicht möglich. Die Kennung und die Bundle-ID im folgenden Beispiel sollten aus der Testkonfiguration stammen:

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 setzt voraus, dass die App auf dem angegebenen Simulator installiert ist. Schlägt die Abfrage fehl, prüfen Sie zuerst die tatsächlich im Test verwendete Gerätekennung, die Bundle-ID und das Installationsergebnis, statt die gesamte Festplatte zu durchsuchen. Nach dem Kopieren prüfen Sie die Datei im Verzeichnis des Testlaufs. Verwenden Sie diese Kopie auch für die weitere Analyse und Archivierung, damit ein erneuter Schreibvorgang der App das Prüfobjekt nicht verändert. Die Ausgabe von file kann bei der Fehlersuche helfen, ersetzt aber keine PDF-Analyse.

Struktur und Text mit PDFKit prüfen

Speichern Sie den folgenden Swift-Code als scripts/check-pdf.swift. Er nimmt einen Dateipfad und eine erwartete Textpassage entgegen, prüft die Seitengrenzen jeder Seite und bestätigt, dass die Passage auf mindestens einer Seite vorkommt. Bei einem Exit-Code ungleich null kann der Build-Job die automatische Prüfung als fehlgeschlagen werten.

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)")

Führen Sie swift scripts/check-pdf.swift artifacts/export.pdf "Quarterly Report" aus. Ersetzen Sie die Beispielpassage durch Text, der in den festen Testdaten tatsächlich vorkommt. Wenn die Anforderungen genau zwei Seiten vorgeben, ergänzen Sie die Bedingung pdf.pageCount == 2. Eine Prüfung auf mehr als null Seiten erkennt Änderungen am Seitenumbruch nicht. Auch die Seitenmaße lassen sich anhand der Produktanforderungen einzeln prüfen. Ohne entsprechende Vorgabe sollten Sie jedoch nicht alle anderen gültigen Papierformate als Fehler werten.

Textextraktion ist keine Sichtprüfung

page.string prüft extrahierbaren Text. Es garantiert weder, dass Zeichen nicht abgeschnitten sind, noch belegt es die korrekte Darstellung von Diagrammen, Bildern oder Farben. Umgekehrt lässt sich aus Scans oder als Bild gerendertem Text möglicherweise nichts extrahieren, obwohl die Seiten normal aussehen. Wenn die Textprüfung fehlschlägt, bewahren Sie das ursprüngliche PDF auf und klären Sie, ob der Inhalt fehlt oder ob die Extraktionsmethode für diese Seite ungeeignet ist. Entfernen Sie die Prüfung nicht einfach, damit der Testlauf besteht.

Fehler dem jeweiligen Schritt zuordnen

Pro Testlauf sollten Sie das Ergebnis des Exports, das Ergebnis des Kopiervorgangs und den PDFKit-Exit-Code getrennt festhalten. Bei einem Fehler können Sie dann der Reihe nach prüfen: Hat die App den Export ausgeführt? Liegt die Datei dieses Laufs im Container? Lässt sich die Kopie analysieren? Entsprechen Seitenzahl, Seitengrenzen und Text den Erwartungen? Geben Sie nicht nur „PDF-Test fehlgeschlagen“ aus, denn sonst muss für die Fehlersuche der gesamte Ablauf erneut durchlaufen werden.

Symptom Zuerst prüfen
Container nicht gefunden Simulatorkennung, Bundle-ID, Installationsergebnis
Datei ist leer Wurde die alte Datei gelöscht, ist der Schreibvorgang abgeschlossen?
PDF lässt sich nicht analysieren Kopiervorgang, Format der fertigen Datei
Text stimmt nicht überein Feste Eingabedaten, Seiteninhalt, Grenzen der Textextraktion

Archivieren Sie bei einem Fehler artifacts/export.pdf und die Testprotokolle, aber stellen Sie vorher sicher, dass der Bericht keine echten Nutzerdaten enthält. Könnte die Datei sensible Informationen enthalten, verwenden Sie synthetische Beispieldaten, beschränken Sie den Zugriff auf die Artefakte und löschen Sie sie nach den Regeln Ihres Teams. Laden Sie keine produktiven Berichte als öffentlich zugängliche Pipeline-Artefakte hoch.

Mit einem nachvollziehbaren Testlauf abschließen

Führen Sie den Ablauf vor der Freigabe zweimal hintereinander mit denselben festen Eingabedaten aus. Bei beiden Läufen muss der Export neu erfolgen, die Zieldatei überschrieben werden und die Prüfung von Seitenzahl und Text dasselbe Ergebnis liefern. Entfernen Sie anschließend absichtlich die erwartete Textpassage und vergewissern Sie sich, dass das Skript fehlschlägt. Lassen Sie die Test-App danach keine Datei erzeugen und prüfen Sie, ob der Kopierschritt fehlschlägt. Diese beiden Negativtests schließen aus, dass die Prüfungen in Wirklichkeit gar nicht ausgeführt wurden.

Auch nach bestandener automatischer Prüfung sollten Sie ein PDF mit repräsentativen Daten öffnen und Seitenübergänge, Umbrüche in langen Texten und Diagrammränder ansehen. Die Maschine prüft verlässlich Struktur- und Textanforderungen; ein Mensch beurteilt die tatsächliche Darstellung. Halten Sie beide Ergebnisse getrennt fest, damit Sie beim nächsten Exportfehler eine klare Vergleichsgrundlage haben.

Häufig gestellte Fragen

Ist ein PDF fehlerhaft, wenn PDFKit keinen Text extrahiert?

Nicht zwingend. Als Bild gerenderter Text oder bestimmte Schriften können die Extraktion verhindern. Bewahren Sie die Datei auf und prüfen Sie die Darstellung.

Wie gelangt die PDF-Datei aus dem Simulator in den Prüfjob?

Die App schreibt sie nach Documents. Mit simctl get_app_container ermitteln Sie den Datencontainer und kopieren die Datei in das Artefaktverzeichnis.

Lassen Sie Ihren nächsten Build auf einem dedizierten Cloud-Mac laufen.

Vergleichen Sie ViewMini-Modelle, Standorte und Laufzeiten und wählen Sie den physischen Rechner, der zu Ihrem Workflow passt.

Cloud-Mac konfigurieren

Prüfen Sie noch einmal Gerät und Laufzeit.

Die drei verfügbaren Modelle gibt es mit Tages-, Wochen-, Monats- und Quartalspreisen. Sehen Sie sich vor der Bestellung alle Tarife an.

Modelle und Preise ansehen Cloud-Mac konfigurieren