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 определяется
четырьмя элементами:
leftX
— количество миллиметров, на которое вертикальная линия отстоит от крайнего левого вертикального края страницы.upperY
— количество миллиметров, на которое горизонтальная линия отстоит от самого верхнего горизонтального края страницы.width
– ширина области в миллиметрахheight
– высота области в миллиметрах
Чтобы лучше понять эту концепцию, давайте создадим PageRegion
, используя следующие атрибуты:
слеваX
= 20верхний Y
= 10ширина
= 150высота
= 50
Вот примерное изображение указанного выше PageRegion:
Когда концепция понятна, соответствующий тестовый пример становится относительно проще:
@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 может сделать гораздо больше; не забудьте посетить страницу документации, чтобы узнать больше.