PDFUnitへのガイド

1前書き

この記事では、PDFをテストするためのhttp://www.pdfunit.com/[PDFUnit]ライブラリを調べます。

PDFUnitが提供する強力なAPIを使用して、PDFを操作したり、テキスト、画像、しおりなどのさまざまなことを検証できます。

最終的にはPDFUnitを使用して非常に複雑なテストケースを書くことができますが、ほとんどの本番PDFに適用される最も一般的なユースケースから始めて、さらなる開発のための優れた基盤を提供しましょう。

重要な注意:PDFUnitは評価目的のために無料で利用できますが、商業目的では利用できません。

2インストールと設定

PDFUnitの最新バージョン(2016.05)は、Maven Centralリポジトリでは利用できません。そのため、jarを手動でダウンロードしてインストールする必要があります。手動インストールについてはhttp://www.pdfunit.com/en/documentation/java/install__update/classpath.html[公式サイト上の指示]に従ってください。

3ページ数

与えられたPDFファイルのページ数を単純に検証する簡単な例から始めましょう。

@Test
public void givenSinglePage__whenCheckForOnePage__thenSuccess() {

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

getFilePath() は、PDFUnitとは無関係の単純なメソッドで、PDFファイルのパスを String として返すだけです。

すべてのPDFUnitテストは、テストのために文書を準備する AssertThat.document() の呼び出しから始まります。 hasNumberOfPages() は、PDFに含める必要があるページ数を指定する引数として int を取ります。この例では、 sample.pdf ファイルに含まれるページは1つだけなので、テストは成功します。

実際のページ数が引数と一致しない場合は、例外がスローされます。

例外がスローされたときにシナリオをテストする方法の例を見てみましょう。

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

この場合、ファイル multiple pages.pdf__には複数のページが含まれています。

したがって、 PDFUnitValidationException 例外がスローされます。

4パスワード保護ファイル

パスワードで保護されたファイルを扱うこともまたとても簡単です。唯一の違いは AssertThat.document() の呼び出しにあります。ここではファイルのパスワードである2番目の引数を渡す必要があります

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

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

5テキスト比較

テストPDF( sample.pdf )と参照PDF( sample reference.pdf__)を比較しましょう。テスト中のファイルのテキストが参照ファイルと同じであれば、テストは成功します。

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

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

haveSameText() は、2つのファイル間でテキストを比較するすべての作業を実行するメソッドです。

2つのファイル間でテキスト全体を比較したくない場合、代わりに特定のページの特定のテキストの存在を検証したい場合は、 containing() メソッドが便利です。

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

multiple pages.pdf ファイルの2ページ目にページのどこかに expectedText が含まれている場合、上記のテストは成功します。 expectedText__以外の他のテキストの有無は結果に影響しません。

特定のテキストがページ全体ではなくページの特定の領域に存在するかどうかを検証して、テストをより制限的にしましょう。

そのためには、 PageRegion の概念を理解する必要があります。

PageRegion は、テスト中の実際のページ内の長方形のサブセクションです。 PageRegion は、実際のページの下に完全に収まっていなければなりません。 PageRegion の一部が実際のページの外側にある場合は、エラーになります。

PageRegion は4つの要素によって定義されます。

  1. leftX - 垂直線が垂直線から何ミリメートル離れているか

ページの左端の垂直方向の端 。 upperY - 水平線が離れているミリメートル数

ページの一番上の水平方向の端 。 width - ミリメートル単位の領域の幅

  1. height - リージョンの高さ(ミリメートル)

この概念をよく理解するために、次の属性を使用して PageRegion を作成しましょう。

  1. leftX = 20

  2. upperY = 10

  3. width = 150

  4. __高さ= 50

これは、上記の__PageRegionのおおよその画像表現です。

リンク:/uploads/PageRegion-768x217.png%20768w[]

概念が明確になれば、対応するテストケースは比較的簡単になります。

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

ここでは、PDFファイルの1ページ目に PageRegion を作成し、この領域のテキストを確認しました。

6. ブックマーク

ブックマーク関連のテストケースをいくつか見てみましょう。

@Test
public void whenHasBookmarks__thenSuccess() {
    String filename = getFilePath("with__bookmarks.pdf");

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

PDFファイルに正確に5つのブックマークがある場合、このテストは成功します。

ブックマークのラベルも確認できます。

@Test
public void whenHasBookmarksWithLabel__thenSuccess() {
    String filename = getFilePath("with__bookmarks.pdf");

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

ここでは、与えられたPDFに「Chapter 2」というテキストのしおりがあることを確認しています。また、Page#3にリンクしているブックマークがあるかどうかを確認します。

7. 画像

画像はPDF文書のもう一つの重要な側面です。 PDF内の画像を単体テストするのはとても簡単です

@Test
public void whenHas2DifferentImages__thenSuccess() {
    String filename = getFilePath("with__images.pdf");

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

このテストでは、PDF内で2つの異なる画像が使用されていることを確認します。異なる画像の数は、PDF文書内に格納されている実際の画像の数を表します。

ただし、ドキュメント内に1つのロゴ画像が格納されていても、ドキュメントの各ページに表示されることがあります。これは目に見える画像の数を意味し、それは異なる画像の数よりも多い場合があります。

可視画像を確認する方法を見てみましょう。

@Test
public void whenHas2VisibleImages__thenSuccess() {
    String filename = getFilePath("with__images.pdf");
    AssertThat.document(filename)
      .hasNumberOfVisibleImages(2);
}
  • PDFUnitは、画像の内容をバイトごとに比較するのに十分強力です** これは、PDF内の画像と参照画像が正確に同じである必要があることも意味します。

バイト比較のために、BMPとPNGのような異なるフォーマットの画像は異なると見なされます。

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

ここでは AnyPage が使用されています。画像全体の特定のページではなく、特定のページに画像の表示を制限するのではありません。

比較するイメージは、ファイル名を表す String 以外に、 BufferedImage File InputStream 、または URL の形式をとることができます。

8埋め込みファイル

特定のPDF文書には埋め込みファイルまたは添付ファイルが付いています。それらもテストする必要があります。

@Test
public void whenHasEmbeddedFile__thenSuccess() {
    String filename = getFilePath("with__attachments.pdf");

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

これにより、テスト中の文書に少なくとも1つの埋め込みファイルがあるかどうかを確認します。

埋め込みファイルの名前も確認できます。

@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");
}
  • さらに一歩進めて、埋め込みファイルの内容も確認できます。

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

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

このセクションのすべての例は、比較的簡単でわかりやすいものです。

9結論

このチュートリアルでは、PDFテストに関連する最も一般的なユースケースをカバーするいくつかの例を見ました。

しかし、PDFUnitにできることはもっとたくさんあります。詳細については、http://www.pdfunit.com/en/documentation/java/[文書ページ]を参照してください。

前の投稿:未知のプロパティを持つJackson非整列化JSON
次の投稿:Java String.codePointCount ()