Автоматизируем проверку содержимого PDF-файлов с помощью pdf-test

от автора

Многие сервисы в различных отраслях генерируют печатные формы счетов, отчётов и прочего в формате PDF. И конечно, перед специалистами тестирования встаёт вопрос о проверке этих документов.

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

В этой статье мы познакомим вас с инструментом, который достаточно просто может закрыть потребность в проверке содержания PDF-файлов. Это инструмент с открытым исходным кодом — pdf-test. Он по сути является обёрткой pdfbox и позволяет из коробки использовать основные мэтчеры, не задумываясь о том, чтобы писать свои или о том, как именно парсить документ. Рассмотрим далее его применение на языке Java.

Установка

Как и для любого другого инструмента, необходимо добавить зависимость в ваш файл проекта (актуальная версия на момент февраля 2024 года – 1.8.1):

pom.xml для Maven

<dependency> <groupId>com.codeborne</groupId> <artifactId>pdf-test</artifactId> <version>1.8.1</version> <scope>test</scope> </dependency>

build.gradle для Gradle

testImplementation 'com.codeborne:pdf-test:1.8.1' 

Можно начинать пользоваться.

Использование

Сценарий использования данного инструмента состоит всего из двух шагов:

  1. Создание экземпляра класса PDF;

  2. Проверка этого объекта средствами AssertJ или Hamcrest;

Рассмотрим всё по порядку.

Создание экземпляра класса PDF

Pdf-test позволяет создать экземпляр для дальнейшей работы несколькими способами:

  • Из файла: PDF pdf = new PDF(new File("test.pdf"));

  • Из адреса URL или URI: PDF pdf = new PDF(URL())/PDF pdf = new PDF(URI());

  • Из InputStream:  PDF pdf = new PDF(getClass().getClassLoader().getResourceAsStream("test.pdf"));

  • Из массива байтов: PDF pdf = new PDF(byteArray);

Для каждого из этих способов создать экземпляр класса PDF, существует перегрузка с указанием страниц, которые нужно парсить в объект:

PDF pdf = new PDF(new File("test.pdf"), 1, 2);

Данный метод создаст экземпляр класса PDF, в котором будут страницы исходного документа с 1 по 2. Если вы попытаетесь создать объект из того, что файлом PDF не является, pdf-test вас об этом предупредит, выдав следующее исключение:

IllegalArgumentException – Invalid PDF file: test.pdf

Итак, теперь у нас есть объект PDF, который мы можем проверять.

Проверки PDF-файла

Что же мы можем проверить в нашем файле? Вообще, весь текст, кроме картинок и таблиц (хотя на таблицы в репозитории есть задача, за которую, возможно, кто-то возьмётся). Кроме содержимого мы можем проверить свойства файла при их наличии. Вот список свойств, которые доступны для проверки в pdf-test:

  int numberOfPages — число страниц в файле;   String author — автор файла;   Calendar creationDate — время создания файла;   String creator — источник файла;   String keywords — ключевые слова;   String producer — программа-генератор файла;   String subject — тема;   String title  название файла;   boolean encrypted — присутствие шифрования;   boolean signed — присутствие электронной подписи;   String signerName — имя подписанта;   Calendar signatureTime — время подписания;

Следующие методы нужны уже для проверки содержимого PDF:

containsText(String text, String... texts) – проверка вхождения переданных строк в файл. Данная проверка регистрозависима, игнорирует множественные пробелы в переданной строке (то есть строки «Hello   world» и «Hello world» посчитает одинаковыми). Если будет передано несколько строк для проверки, то будет проверятся их вхождение в документ именно в том порядке, в каком они были переданы в метод. Если в файле несколько одинаковых подстрок, то находится только первое вхождение.

doesNotContainText(String text, String... texts) – проверка отсутствия переданных строк в тексте. Обладает теми же свойствами, что и предыдущая проверка.

containsExactText(String substring) – проверка присутствия в файле в точности переданного текста. Регистрозависима и не пропускает пробелы, в отличие от метода containsText(String text, String… texts).

doesNotContainExactText(String substring) – проверка, противоположная по смыслу предыдущей. Регистрозависима и не пропускает пробелы,  в отличие от метода doesNotContainsText(String text, String… texts).

containsTextCaseInsensitive(String substring) – регистронезависимая проверка присутствия в файле строки текста. Игнорирует пробелы, как и метод containsText(String text, String… texts).

И самое интересное:

matchesText(String regex) / matchesText(Pattern regex) – проверка того, что в файле есть подстрока, удовлетворяющая регулярному выражению. С помощью этой проверки можно проверять повторные вхождения текста, взаимное расположение текста, а также большие текстовые формы или текст, в котором есть меняющиеся данные (номера, имена, название и прочее).

Перейдём к практике

Приведём немного утрированный, но показательный пример того, как всё это может применяться на практике. Допустим, у нас есть генерируемое платёжное поручение с названием transaction.pdf:

Тогда тест по проверке нашего документа с использованием AssertJ будет выглядеть примерно так:

@Test   public void bankTransactionTest() throws Exception { PDF pdf = new PDF(new File("transaction.pdf")); assertThat(pdf, containsText("11.11.2023")); assertThat(pdf, containsText("Поступ. в банк плат.", "Списано со сч. плат.")); assertThat(pdf, matchText(".*ПЛАТЕЖНОЕ ПОРУЧЕНИЕ № \\d{3}.*")); assertThat(pdf, containsText("Дата", "Вид платежа", "Сумма прописью")); assertThat(pdf, containsText("ИНН", "КПП")); assertThat(pdf, containsExactText("Иван Тестов")); assertThat(pdf, containsText("Плательщик")); assertThat(pdf, matchText(".*Сч.№ \\d{20}.*")); assertThat(pdf, containsTextCaseInsensitive("ПАО \"БАНК \"САНКТ-ПЕТЕРБУРГ\"")); assertThat(pdf, containsText("Отметки банка")); assertThat(pdf, matchText(".*БИК \\d{9}.*")); assertThat(pdf, matchText(".*Код операции \\d{12}.*"));    assertThat(pdf, doesNotContainsText("Test", "dev"));   }

Вывод

Теперь вы знаете, как применить несложный и достаточно удобный инструмент проверки текста внутри pdf-файлов, и сможете прокачать им свои тесты. Пусть в нём не так много функциональности, но этого вполне достаточно, чтобы проверить PDF на то, что в нём есть вся нужная информация и ничего не потеряно, например, при генерации какой-нибудь важной квитанции. 

К тому же, это опенсорс-проект, и, скорее всего, со временем в нём появятся новые методы. Например, в данный момент открыта задача на добавление метода для проверки таблиц, может, именно вы её и решите.

Подробнее познакомиться с исходниками pdf-test, примерами использования и предложить свои нововведения можно, перейдя в репозиторий.

Конечно, это не единственный инструмент для работы с PDF, но кажется, наиболее простой в освоении и в работе. Про библиотеку pdfbox, которая находится у него под капотом, можно почитать здесь.

Спасибо за внимание!

Больше авторских материалов для разработчиков в тестировании от моих коллег читайте в соцсетях SimbirSoft – ВКонтакте и Telegram.


ссылка на оригинал статьи https://habr.com/ru/articles/794728/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *