Как выполнить модульное тестирование функции Python, которая рисует графику PDF? - PullRequest
19 голосов
/ 12 января 2011

Я пишу CAD-приложение, которое выводит PDF-файлы с использованием графической библиотеки Cairo.Большая часть модульного тестирования не требует фактической генерации файлов PDF, таких как вычисление ожидаемых ограничивающих рамок объектов.Тем не менее, я хочу убедиться, что сгенерированные PDF-файлы «выглядят» правильно после изменения кода.Есть ли автоматизированный способ сделать это?Как я могу максимально автоматизировать?Нужно ли визуально проверять каждый сгенерированный PDF?Как я могу решить эту проблему, не вырывая мои волосы?

Ответы [ 5 ]

19 голосов
/ 13 января 2011

(См. Также обновление ниже!)

Я делаю то же самое, используя сценарий оболочки в Linux, который включает

  1. Команда compare ImageMagick
  2. утилита pdftk
  3. Ghostscript (опционально)

(было бы довольно просто перенести это в .bat Batch-файл для DOS / Windows.)

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

Вот строительные блоки:

pdftk

Используйте эту команду, чтобы разбить многостраничные PDF-файлы на несколько одностраничных PDF-файлов:

pdftk  reference.pdf  burst  output  somewhere/reference_page_%03d.pdf
pdftk  comparison.pdf burst  output  somewhere/comparison_page_%03d.pdf

сравнить

Используйте эту команду для создания PDF-страницы "diff" для каждой из страниц:

compare \
       -verbose \
       -debug coder -log "%u %m:%l %e" \
        somewhere/reference_page_001.pdf \
        somewhere/comparison_page_001.pdf \
       -compose src \
        somewhereelse/reference_diff_page_001.pdf

Ghostscript

Из-за автоматически вставленных метаданных (например, текущей даты +время), вывод PDF не работает хорошо для сравнений файлов на основе MD5hash.

Если вы хотите автоматически обнаруживать все случаи, которые состоят из чисто белых страниц, вы также можете преобразовать в растровый формат без метаданных, используяbmp256 устройство вывода.Вы можете сделать это для оригинальных PDF-файлов (справка и сравнение) или для страниц diff-PDF:

 gs \
   -o reference_diff_page_001.bmp \
   -r72 \
   -g595x842 \
   -sDEVICE=bmp256 \
    reference_diff_page_001.pdf

 md5sum reference_diff_page_001.bmp

Если сумма MD5 - это то, что вы ожидаете для полностью белой страницы 595x842 точек PostScript, тогдаваш модульный тест пройден.


Обновление:

Я не знаю, почему я раньше не думал о создании гистограммы вывода из ImageMagick compare ...

Ниже приведен конвейер команд, объединяющий две разные команды:

  1. первая такая же, как и выше compare, который генерирует белый цвет пиксели равны, красные пиксели - формат различий, только он выводит внутренний формат miff ImageMagick.Он не записывает в файл, но в stdout .
  2. второй использует convert для чтения stdin , генерирует гистограмму и выводит результат втекстовая форма.Будет две строки:
    • одна указывает на количество белых пикселей
    • другая указывает на количество красных пикселей.

Вот так:

compare \
   reference.pdf \
   current.pdf \
  -compose src \
   miff:- \
| \
convert \
   - \
  -define histogram:unique-colors=true \
  -format %c \
   histogram:info:-

Пример вывода:

 56934: (61937,    0, 7710,52428) #F1F100001E1ECCCC srgba(241,0,30,0.8)
444056: (65535,65535,65535,52428) #FFFFFFFFFFFFCCCC srgba(255,255,255,0.8)

(Пример вывода был создан с использованием этих reference.pdf и current.pdf files.)

Я думаю, что этот тип вывода действительно хорошо подходит для автоматического модульного тестирования.Если вы вычислите два числа, вы можете легко вычислить процент «красного пикселя», и вы даже можете решить вернуть PASSED или FAILED на основе определенного порога (если вы необязательно нужен "ноль красный" по какой-то причине).

8 голосов
/ 12 января 2011

Вы можете захватить PDF как растровое (или, по крайней мере, сжатое без потерь) изображение, а затем сравнить изображение, сгенерированное каждым тестом, с эталонным изображением того, как оно должно выглядеть.Любые различия будут помечены как ошибки для теста.

0 голосов
/ 18 июля 2011

Я написал инструмент на Python для проверки PDF-файлов для документации моего работодателя.Он имеет возможность сравнивать отдельные страницы с мастер-изображениями.Я использовал найденную библиотеку swftools , чтобы экспортировать страницу в PNG, а затем Библиотека изображений Python , чтобы сравнить ее с мастером.

Соответствующий код выглядитчто-то вроде этого (это не будет работать, так как есть некоторые зависимости от других частей скрипта, но вы должны понять):

# exporting

gfxpdf = gfx.open("pdf", self.pdfpath)
if os.path.isfile(pngPath):
    os.remove(pngPath)
page = gfxpdf.getPage(pagenum)
img = gfx.ImageList()
img.startpage(page.width, page.height)
page.render(img)
img.endpage()
img.save(pngPath)
return os.path.isfile(pngPath)

# comparing

outPng = os.path.join(outpath, pngname)
masterPng = os.path.join(outpath, "_master", pngname)
if os.path.isfile(masterPng):
    output = Image.open(outPng).convert("RGB") # discard alpha channel, if any
    master = Image.open(masterPng).convert("RGB")
    mismatch = any(x[1] for x in ImageChops.difference(output, master).getextrema())
0 голосов
/ 13 января 2011

Я бы попробовал это с помощью xpresser - (https://wiki.ubuntu.com/Xpresser) Вы можете попытаться сопоставить изображения с похожими изображениями, а не с точными копиями - что является проблемой в этих случаях.

Я не знаю, разрабатывается ли xpresser, или его можно использовать с автономными файлами изображений (я так думаю) - в любом случае он берет свои идеи из проекта Sikuli (который является Java с Jython) конец, в то время как xpresser - это Python).

0 голосов
/ 13 января 2011

Первая идея, которая появляется у меня в голове, - использовать утилиту diff.Они обычно используются для сравнения текстов документов, но они также могут сравнивать макет PDF.Используя его, вы можете сравнить ожидаемый результат с предоставленным.

Первый результат, который Google дает мне, - this .Несмотря на то, что он коммерческий, могут быть и другие бесплатные / открытые альтернативы.

...