Guide de PDFUnit

Guide de PDFUnit

1. introduction

Dans cet article, nous allons explorer la bibliothèquePDFUnit pour tester les PDF.

En utilisant les puissantes API fournies par PDFUnit, nous pouvons travailler avec des PDF et vérifier du texte, des images, des signets et un certain nombre d'autres choses.

Nous pouvons éventuellement écrire des cas de test assez complexes à l'aide de PDFUnit, mais commençons par les cas d'utilisation les plus courants qui s'appliqueront à la plupart de vos PDF de production et fourniront une excellente base pour un développement ultérieur.

Remarque importante: PDFUnit est disponible gratuitement à des fins d'évaluation, mais pas à des fins commerciales.

2. Installation et configuration

La version actuelle de PDFUnit (2016.05) n'est pas disponible dans le référentiel Maven Central. Par conséquent, nous devons télécharger et installer les fichiers JAR manuellement. Veuillez suivre lesinstructions on the official site pour une installation manuelle.

3. Nombre de pages

Commençons par un exemple simple qui valide simplement le nombre de pages dans un fichier PDF donné:

@Test
public void givenSinglePage_whenCheckForOnePage_thenSuccess() {

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

LegetFilePath() est une méthode simple, non liée à PDFUnit, qui renvoie simplement le chemin du fichier PDF sous forme deString.

Tous les tests PDFUnit commencent par un appel àAssertThat.document() qui prépare le document pour le test. LehasNumberOfPages() prend unint comme argument qui spécifie le nombre de pages que le PDF doit contenir. Dans notre cas, le fichiersample.pdf ne contient qu'une seule page, donc le test réussit.

Si le nombre réel de pages ne correspond pas à l'argument, une exception est levée.

Voyons un exemple sur la façon de tester un scénario lorsqu'une exception est levée:

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

Dans ce cas, le fichiermultiple_pages.pdf contient plusieurs pages. Par conséquent, une exceptionPDFUnitValidationException est levée.

4. Fichiers protégés par mot de passe

Le traitement des fichiers protégés par mot de passe est à nouveau très simple. La seule différence est dans l'appel àAssertThat.document() où nous avons besoin depass a second argument which is the password of the file:

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

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

5. Comparaison de texte

Comparons maintenant un PDF test (sample.pdf) à un PDF de référence (sample_reference.pdf). Si le texte du fichier à tester est identique au fichier de référence, le test réussit:

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

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

LehaveSameText() est la méthode qui fait tout le travail de comparaison du texte entre les deux fichiers.

Si nous ne voulons pas comparer le texte complet entre deux fichiers et à la place, nous voulons valider l’existence d’un texte particulier sur une certaine page, la méthodecontaining() est pratique:

@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);
}

Le test ci-dessus réussit si la page n ° 2 du fichiermultiple_pages.pdf contient lesexpectedText n'importe où sur la page. L'absence ou la présence de tout autre texte en dehors desexpectedText n'affecte pas les résultats.

Rendons maintenant le test plus restrictif en validant si un texte particulier est présent dans une certaine région d'une page au lieu de la page entière. Pour cela, nous devons comprendre le concept dePageRegion.

UnPageRegion est une sous-section rectangulaire dans la page en cours de test. LesPageRegion doivent complètement tomber sous la page réelle. Si une partie dePageRegion tombe en dehors de la page réelle, cela entraînera une erreur.

UnPageRegion est défini par quatre éléments:

  1. leftX - le nombre de millimètres entre une ligne verticale et le bord vertical le plus à gauche de la page

  2. upperY - le nombre de millimètres qu'une ligne horizontale est éloignée du bord horizontal supérieur de la page

  3. width - la largeur de la région en millimètres

  4. height - la hauteur de la région millimètres

Pour mieux comprendre ce concept, créons unPageRegion en utilisant les attributs suivants:

  1. leftX = 20

  2. upperY = 10

  3. width = 150

  4. height = 50

Voici une représentation d'image approximative desPageRegion: ci-dessus

image

Une fois que le concept est clair, le cas de test correspondant est relativement plus simple:

@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");
}

Ici, nous avons créé unPageRegion dans la page n ° 1 du fichier PDF et vérifié le texte dans cette région.

6. Signets

Voyons quelques cas de test liés aux favoris:

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

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

Ce test réussira si le fichier PDF contient exactement cinq signets.

L'étiquette des signets peut également être vérifiée:

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

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

Ici, nous vérifions que le PDF donné a un signet avec le texte «Chapitre 2». Il vérifie également s’il existe un signet qui renvoie à la page 3.

7. Images

Les images sont un autre aspect important des documents PDF. Tester à nouveau très facilement les images dans le PDF:

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

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

Ce test vérifie qu'il existe exactement deux images différentes utilisées dans le fichier PDF. Le nombre d'images différentes correspond à un nombre réel d'images stockées dans un document PDF.

Cependant, il est possible qu’une seule image de logo soit stockée dans le document mais qu’elle soit affichée sur chaque page du document. Cela fait référence au nombre d'images visibles, qui peut être supérieur au nombre d'images différentes.

Voyons comment vérifier les images visibles:

@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. Cela signifie également que l'image dans le PDF et l'image de référence doivent être exactement égales.

En raison de la comparaison d'octets, différents formats d'images tels que BMP et PNG sont considérés comme étant inéquitables:

@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);
}

Remarquez l'utilisation deAnyPage ici. Nous ne limitons pas l'occurrence de l'image à une page particulière, mais à une page du document entier.

L'image à comparer peut prendre la forme deBufferedImage,File,InputStream ouURL à l'exception desString qui représentent le nom du fichier.

8. Fichiers incorporés

Certains documents PDF sont livrés avec des fichiers incorporés ou des pièces jointes. Il faut aussi tester ceux-ci:

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

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

Cela permettra de vérifier si le document testé contient au moins un fichier incorporé.

Nous pouvons également vérifier le nom du fichier incorporé:

@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");
}

Nous pouvons aller plus loin et vérifier également le contenu des fichiers intégrés:

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

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

Tous les exemples de cette section sont relativement simples et explicites.

9. Conclusion

Dans ce didacticiel, nous avons vu plusieurs exemples qui couvrent les cas d'utilisation les plus courants liés aux tests PDF.

Cependant, PDFUnit peut faire beaucoup plus; assurez-vous de visiter ledocumentation page pour en savoir plus.