Руководство по PDFUnit

Руководство по PDFUnit

1. Вступление

В этой статье мы собираемся изучить библиотекуPDFUnit для тестирования PDF-файлов.

Используя мощные API, предоставляемые PDFUnit, мы можем работать с PDF-файлами и проверять текст, изображения, закладки и ряд других вещей.

Со временем мы сможем написать довольно сложные тестовые примеры с помощью PDFUnit, но давайте начнем с наиболее распространенных вариантов использования, которые будут применяться к большинству ваших рабочих PDF-файлов и обеспечат отличную основу для дальнейшей разработки.

Важное примечание: PDFUnit доступен бесплатно для ознакомительных целей, но не для коммерческого использования.

2. Установка и настройка

Текущая версия PDFUnit (2016.05) недоступна в репозитории Maven Central. Следовательно, нам нужно скачать и установить банки вручную. Пожалуйста, следуйтеinstructions on the official site для ручной установки.

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() принимаетint в качестве аргумента, который определяет количество страниц, которые должен содержать PDF. В нашем случае файлsample.pdf содержит только одну страницу, поэтому проверка прошла успешно.

Если фактическое количество страниц не совпадает с аргументом, выдается исключение.

Давайте посмотрим на пример того, как протестировать сценарий при возникновении исключения:

@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(), где нам нужноpass 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. Текстовое сравнение

Теперь сравним тестовый 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() - это метод, который выполняет всю работу по сравнению текста между двумя файлами.

Если мы не хотим сравнивать полный текст двух файлов, а вместо этого хотим проверить наличие определенного текста на определенной странице, нам пригодится метод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);
}

Вышеупомянутый тест считается успешным, если страница №2 файлаmultiple_pages.pdf содержитexpectedText где-нибудь на странице. Отсутствие или присутствие любого другого текста, кромеexpectedText, не влияет на результаты.

Теперь давайте сделаем тест более строгим, проверив, присутствует ли конкретный текст в определенной области страницы, а не на всей странице. Для этого нам нужно понять концепциюPageRegion.

PageRegion - это прямоугольный подраздел внутри тестируемой страницы. PageRegion должны полностью попадать под фактическую страницу. Если какая-либо частьPageRegion выходит за пределы реальной страницы, это приведет к ошибке.

APageRegion определяется четырьмя элементами:

  1. leftX - количество миллиметров, на которое вертикальная линия удалена от крайнего левого вертикального края страницы.

  2. upperY - количество миллиметров, на которое горизонтальная линия удалена от самого верхнего горизонтального края страницы

  3. width - ширина области в миллиметрах

  4. height - высота области в миллиметрах

Чтобы лучше понять эту концепцию, давайте создадимPageRegion, используя следующие атрибуты:

  1. leftX = 20

  2. upperY = 10

  3. width = 150

  4. height = 50

Вот приблизительное изображение вышеупомянутогоPageRegion:

image

Как только концепция понятна, соответствующий тестовый пример является относительно более простым:

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

Здесь мы создалиPageRegion на странице №1 файла PDF и проверили текст в этой области.

6. закладки

Давайте посмотрим на пару тестовых примеров, связанных с закладками:

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

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

Этот тест будет успешным, если PDF-файл содержит ровно пять закладок.

Также можно проверить ярлык закладок:

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

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

Здесь мы проверяем, что данный PDF имеет закладку с текстом «Глава 2». Он также проверяет, есть ли закладка, которая ссылается на страницу № 3.

7. Изображений

Изображения являются еще одним важным аспектом документов PDF. Модульное тестирование изображений внутри PDF снова очень просто:

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

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

Этот тест проверяет, что внутри PDF-файла используются ровно два разных изображения. Количество различных изображений относится к фактическому количеству изображений, хранящихся в документе PDF.

Тем не менее, возможно, что внутри документа хранится одно изображение логотипа, но оно отображается на каждой странице документа. Это относится к количеству видимых изображений, которое может превышать количество различных изображений.

Давайте посмотрим, как проверить видимые изображения:

@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. Это также означает, что изображение в 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. Мы не ограничиваем вхождение изображения какой-либо конкретной страницей, скорее, на любой странице во всем документе.

Изображение для сравнения может иметь формуBufferedImage,File,InputStream илиURL, за исключениемString, представляющего имя файла.

8. Встроенные файлы

Некоторые PDF-документы поставляются со встроенными файлами или приложениями. Также необходимо проверить это:

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

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

Это проверит, имеет ли проверяемый документ хотя бы один встроенный файл.

Мы также можем проверить имя внедренного файла:

@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 может сделать гораздо больше; не забудьте посетитьdocumentation page, чтобы узнать больше.