Руководство по 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 определяется четырьмя элементами:
-
leftX - количество миллиметров, на которое вертикальная линия удалена от крайнего левого вертикального края страницы.
-
upperY - количество миллиметров, на которое горизонтальная линия удалена от самого верхнего горизонтального края страницы
-
width - ширина области в миллиметрах
-
height - высота области в миллиметрах
Чтобы лучше понять эту концепцию, давайте создадим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 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, чтобы узнать больше.