«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 (пример .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);
}
Вышеупомянутое test завершается успешно, если страница № 2 файла multiple_pages.pdf содержит ожидаемый текст в любом месте страницы. Отсутствие или присутствие любого другого текста, кроме ожидаемого текста, не влияет на результаты.
Давайте теперь сделаем тест более строгим, проверив, присутствует ли конкретный текст в определенной области страницы, а не на всей странице. Для этого нам нужно понять концепцию PageRegion.
PageRegion — это прямоугольный подраздел внутри тестируемой страницы. PageRegion должен полностью находиться под фактической страницей. Если какая-либо часть PageRegion выходит за пределы фактической страницы, это приведет к ошибке.
PageRegion определяется четырьмя элементами:
- leftX – the number of millimeters a verticle line is away from the leftmost vertical edge of the page
- upperY – the number of millimeters a horizontal line is away from the topmost horizontal edge of the page
- width – the width of the region in millimeters
- height – the height of the region millimeters
Чтобы лучше понять эту концепцию, давайте создадим PageRegion, используя следующие атрибуты:
- leftX = 20
- upperY = 10
- width = 150
- height = 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-файле и эталонное изображение должны точно совпадать.
@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);
}
Из-за сравнения байтов различные форматы изображений, такие как BMP и PNG, считаются неравными:
Обратите внимание на использование AnyPage здесь. Мы не ограничиваем появление изображения на какой-либо конкретной странице, а на любой странице всего документа.
Изображение для сравнения может принимать форму BufferedImage, File, InputStream или URL, за исключением строки, представляющей имя файла.
8. Встроенные файлы
@Test
public void whenHasEmbeddedFile_thenSuccess() {
String filename = getFilePath("with_attachments.pdf");
AssertThat.document(filename)
.hasEmbeddedFile();
}
Некоторые PDF-документы содержат встроенные файлы или вложения. Их также необходимо протестировать:
Это проверит, есть ли в тестируемом документе хотя бы один встроенный файл.
@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.