Перейти к основному содержимому

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

· 6 мин. чтения

1. Введение

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

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

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

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

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

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

3. Количество страниц

Давайте начнем с простого примера, который просто проверяет количество страниц в заданном файле PDF:

@Test
public void givenSinglePage_whenCheckForOnePage_thenSuccess() {

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

getFilePath () — это простой метод, не связанный с PDFUnit, который просто возвращает путь к файлу PDF в виде строки .

Все тесты 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() , где нам нужно передать второй аргумент, который является паролем файла :

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

Если мы не хотим сравнивать полный текст между двумя файлами, а вместо этого хотим проверить наличие определенного текста на определенной странице, нам пригодится метод contains () :

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

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

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

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

  1. leftX — количество миллиметров, на которое вертикальная линия отстоит от крайнего левого вертикального края страницы.
  2. upperY — количество миллиметров, на которое горизонтальная линия отстоит от самого верхнего горизонтального края страницы.
  3. width – ширина области в миллиметрах
  4. height – высота области в миллиметрах

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

  1. слеваX = 20
  2. верхний Y = 10
  3. ширина = 150
  4. высота = 50

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

./1583c8b8baad7690286323a3afd2b040.png

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

@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 достаточно мощен, чтобы сравнивать содержимое изображений по байтам. Это также означает, что изображение в 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 , за исключением строки , которая представляет имя файла.

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