Anleitung zur PDFUnit

Leitfaden zu PDFUnit

1. Einführung

In diesem Artikel werden wir diePDFUnit-Bibliothek zum Testen von PDFs untersuchen.

Mit den leistungsstarken APIs von PDFUnit können wir mit PDFs arbeiten und Text, Bilder, Lesezeichen und eine Reihe anderer Dinge überprüfen.

Mit PDFUnit können wir schließlich recht komplexe Testfälle schreiben. Beginnen wir jedoch mit den häufigsten Anwendungsfällen, die für die meisten Ihrer Produktions-PDFs gelten und eine hervorragende Grundlage für die weitere Entwicklung bieten.

Wichtiger Hinweis: PDFUnit steht zu Testzwecken kostenlos zur Verfügung, jedoch nicht für kommerzielle Zwecke.

2. Installation und Einrichtung

Die aktuelle Version von PDFUnit (2016.05) ist nicht im Maven Central-Repository verfügbar. Daher müssen wir die Gläser manuell herunterladen und installieren. Bitte befolgen Sie dieinstructions on the official site für die manuelle Installation.

3. Seitenzahl

Beginnen wir mit einem einfachen Beispiel, das einfach die Anzahl der Seiten in einer bestimmten PDF-Datei überprüft:

@Test
public void givenSinglePage_whenCheckForOnePage_thenSuccess() {

    String filename = getFilePath("sample.pdf");
    AssertThat.document(filename)
      .hasNumberOfPages(1);
}

getFilePath() ist eine einfache Methode, die nicht mit PDFUnit zusammenhängt und einfach den Pfad der PDF-Datei alsString zurückgibt.

Alle PDFUnit-Tests beginnen mit einem Aufruf vonAssertThat.document(), der das Dokument für den Test vorbereitet. DashasNumberOfPages() nimmt einint als Argument, das die Anzahl der Seiten angibt, die das PDF enthalten muss. In unserem Fall enthält die Dateisample.pdf nur eine Seite, sodass der Test erfolgreich ist.

Wenn die tatsächliche Anzahl der Seiten nicht mit dem Argument übereinstimmt, wird eine Ausnahme ausgelöst.

Sehen wir uns ein Beispiel zum Testen eines Szenarios an, wenn eine Ausnahme ausgelöst wird:

@Test(expected = PDFUnitValidationException.class)
public void givenMultiplePages_whenCheckForOnePage_thenException() {
    String filename = getFilePath("multiple_pages.pdf");
    AssertThat.document(filename)
      .hasNumberOfPages(1);
}

In diesem Fall enthält die Dateimultiple_pages.pdf mehrere Seiten. Daher wird einePDFUnitValidationException Ausnahme ausgelöst.

4. Passwortgeschützte Dateien

Der Umgang mit passwortgeschützten Dateien ist wieder ganz einfach. Der einzige Unterschied besteht im Aufruf vonAssertThat.document(), wo wirpass a second argument which is the password of the file benötigen:

@Test
public void givenPwdProtected_whenOpenWithPwd_thenSuccess() {
    String filename = getFilePath("password_protected.pdf");
    String userPassword = "pass1";

    AssertThat.document(filename, userPassword)
      .hasNumberOfPages(1);
}

5. Textvergleich

Vergleichen wir nun ein Test-PDF (sample.pdf) mit einem Referenz-PDF (sample_reference.pdf). Wenn der Text der zu testenden Datei mit der Referenzdatei übereinstimmt, ist der Test erfolgreich:

@Test
public void whenMatchWithReferenceFile_thenSuccess() {
    String testFileName = getFilePath("sample.pdf");
    String referenceFileName = getFilePath("sample_reference.pdf");

    AssertThat.document(testFileName)
      .and(referenceFileName)
      .haveSameText();
}

haveSameText() ist die Methode, mit der der gesamte Text zwischen den beiden Dateien verglichen wird.

Wenn wir nicht den vollständigen Text zwischen zwei Dateien vergleichen und stattdessen das Vorhandensein eines bestimmten Textes auf einer bestimmten Seite überprüfen möchten, ist die Methodecontaining()hilfreich:

@Test
public void whenPage2HasExpectedText_thenSuccess() {

    String filename = getFilePath("multiple_pages.pdf");
    String expectedText = "Chapter 1, content";

    AssertThat.document(filename)
      .restrictedTo(PagesToUse.getPage(2))
      .hasText()
      .containing(expectedText);
}

Der obige Test ist erfolgreich, wenn die Seite 2 dermultiple_pages.pdf-Datei dieexpectedText an einer beliebigen Stelle auf der Seite enthält. Das Fehlen oder Vorhandensein eines anderen Textes außerexpectedText hat keinen Einfluss auf die Ergebnisse.

Lassen Sie uns den Test jetzt restriktiver gestalten, indem wir überprüfen, ob ein bestimmter Text in einem bestimmten Bereich einer Seite anstelle der gesamten Seite vorhanden ist. Dazu müssen wir das Konzept vonPageRegion verstehen.

APageRegion ist ein rechteckiger Unterabschnitt innerhalb der tatsächlich zu testenden Seite. DiePageRegion müssen vollständig unter die tatsächliche Seite fallen. Wenn ein Teil vonPageRegion außerhalb der tatsächlichen Seite liegt, führt dies zu einem Fehler.

EinPageRegion wird durch vier Elemente definiert:

  1. leftX - Die Anzahl der Millimeter, die eine Vertikellinie vom linken vertikalen Rand der Seite entfernt ist

  2. upperY - Die Anzahl der Millimeter, die eine horizontale Linie vom obersten horizontalen Rand der Seite entfernt ist

  3. width - die Breite des Bereichs in Millimetern

  4. height - die Höhe des Bereichs Millimeter

Um dieses Konzept besser zu verstehen, erstellen wir einPageRegion mit den folgenden Attributen:

  1. leftX = 20

  2. upperY = 10

  3. width = 150

  4. height = 50

Hier ist eine ungefähre Bilddarstellung der obigenPageRegion:

image

Sobald das Konzept klar ist, ist der entsprechende Testfall relativ einfach:

@Test
public void whenPageRegionHasExpectedtext_thenSuccess() {
    String filename = getFilePath("sample.pdf");
    int leftX = 20;
    int upperY = 10;
    int width = 150;
    int height = 50;
    PageRegion regionTitle = new PageRegion(leftX, upperY, width, height);

    AssertThat.document(filename)
      .restrictedTo(PagesToUse.getPage(1))
      .restrictedTo(regionTitle)
      .hasText()
      .containing("Adobe Acrobat PDF Files");
}

Hier haben wir einPageRegion auf Seite 1 der PDF-Datei erstellt und den Text in dieser Region überprüft.

6. Lesezeichen

Sehen wir uns einige Testfälle an, die mit Lesezeichen zusammenhängen:

@Test
public void whenHasBookmarks_thenSuccess() {
    String filename = getFilePath("with_bookmarks.pdf");

    AssertThat.document(filename)
      .hasNumberOfBookmarks(5);
}

Dieser Test ist erfolgreich, wenn die PDF-Datei genau fünf Lesezeichen enthält.

Die Beschriftung der Lesezeichen kann ebenfalls überprüft werden:

@Test
public void whenHasBookmarksWithLabel_thenSuccess() {
    String filename = getFilePath("with_bookmarks.pdf");

    AssertThat.document(filename)
      .hasBookmark()
      .withLabel("Chapter 2")
      .hasBookmark()
      .withLinkToPage(3);
}

Hier prüfen wir, ob das angegebene PDF ein Lesezeichen mit dem Text "Kapitel 2" enthält. Es wird auch überprüft, ob ein Lesezeichen vorhanden ist, das auf Seite 3 verweist.

7. Bilder

Bilder sind ein weiterer wichtiger Aspekt von PDF-Dokumenten. Testen Sie die Bilder in der PDF-Datei noch einmal ganz einfach:

@Test
public void whenHas2DifferentImages_thenSuccess() {
    String filename = getFilePath("with_images.pdf");

    AssertThat.document(filename)
      .hasNumberOfDifferentImages(2);
}

Dieser Test überprüft, ob genau zwei verschiedene Bilder in der PDF-Datei verwendet werden. Die Anzahl der verschiedenen Bilder bezieht sich auf die tatsächliche Anzahl der Bilder, die in einem PDF-Dokument gespeichert sind.

Möglicherweise ist jedoch ein einzelnes Logo im Dokument gespeichert, das jedoch auf jeder Seite des Dokuments angezeigt wird. Dies bezieht sich auf die Anzahl der sichtbaren Bilder, die mehr als die Anzahl der verschiedenen Bilder sein können.

Mal sehen, wie Sie die sichtbaren Bilder überprüfen:

@Test
public void whenHas2VisibleImages_thenSuccess() {
    String filename = getFilePath("with_images.pdf");
    AssertThat.document(filename)
      .hasNumberOfVisibleImages(2);
}

PDFUnit is powerful enough to compare the content of images byte-by-byte. Dies bedeutet auch, dass das Bild im PDF und das Referenzbild genau gleich sein müssen.

Aufgrund des Byte-Vergleichs werden unterschiedliche Bildformate wie BMP und PNG als ungleich betrachtet:

@Test
public void whenImageIsOnAnyPage_thenSuccess() {
    String filename = getFilePath("with_images.pdf");
    String imageFile = getFilePath("Superman.png");

    AssertThat.document(filename)
      .restrictedTo(AnyPage.getPreparedInstance())
      .hasImage()
      .matching(imageFile);
}

Beachten Sie hier die Verwendung vonAnyPage. Wir beschränken das Auftreten des Bildes nicht auf eine bestimmte Seite, sondern auf eine Seite im gesamten Dokument.

Das zu vergleichende Bild kann die Form vonBufferedImage,File,InputStream oderURL haben, abgesehen vonString, die den Dateinamen darstellen.

8. Eingebettete Dateien

Bestimmte PDF-Dokumente werden mit eingebetteten Dateien oder Anhängen geliefert. Es ist auch notwendig, diese zu testen:

@Test
public void whenHasEmbeddedFile_thenSuccess() {
    String filename = getFilePath("with_attachments.pdf");

    AssertThat.document(filename)
      .hasEmbeddedFile();
}

Hiermit wird überprüft, ob das zu testende Dokument mindestens eine eingebettete Datei enthält.

Wir können auch den Namen der eingebetteten Datei überprüfen:

@Test
public void whenHasmultipleEmbeddedFiles_thenSuccess() {
    String filename = getFilePath("with_attachments.pdf");

    AssertThat.document(filename)
      .hasNumberOfEmbeddedFiles(4)
      .hasEmbeddedFile()
      .withName("complaintform1.xls")
      .hasEmbeddedFile()
      .withName("complaintform2.xls")
      .hasEmbeddedFile()
      .withName("complaintform3.xls");
}

Wir können noch einen Schritt weiter gehen und auch den Inhalt der eingebetteten Dateien überprüfen:

@Test
public void whenEmbeddedFileContentMatches_thenSuccess() {
    String filename = getFilePath("with_attachments.pdf");
    String embeddedFileName = getFilePath("complaintform1.xls");

    AssertThat.document(filename)
      .hasEmbeddedFile()
      .withContent(embeddedFileName);
}

Alle Beispiele in diesem Abschnitt sind relativ einfach und selbsterklärend.

9. Fazit

In diesem Tutorial haben wir einige Beispiele gesehen, die die häufigsten Anwendungsfälle im Zusammenhang mit PDF-Tests abdecken.

Es gibt jedoch noch viel mehr, was PDFUnit tun kann. Besuchen Sie unbedingt diedocumentation page, um mehr zu erfahren.