尽管这个问题已经很老了,但我的猜测是我可以为这个主题做出贡献。
我们有多个应用程序生成大量 PDF。其中一个应用程序是用 Python 编写的,最近我想编写集成测试来检查 PDF 生成是否正常工作。
测试 PDF 生成非常困难,因为 PDF 文件的规格非常复杂且不确定。使用完全相同的输入数据生成的两个 PDF 将生成不同的文件,因此放弃直接文件比较。
解决方案:我们必须测试它们的外观(因为这应该是确定性的!)。
在我们的例子中,PDF 是通过reportlab包生成的,但这从测试的角度来看并不重要,我们只需要生成器中的文件名或 PDF blob(字节)。我们还需要一个包含“良好”PDF 的期望文件,以便与来自生成器的 PDF 进行比较。
PDF 将转换为图像,然后进行比较。这可以通过多种方式完成,但我们决定使用ImageMagick,因为它非常通用且非常成熟,几乎可以绑定所有编程语言。对于 Python 3,绑定由包提供Wand。
该测试如下所示。我们删除了实现的具体细节并简化了示例:
import os
from unittest import TestCase
from wand.image import Image
from app.generators.pdf import PdfGenerator
DIR = os.path.dirname(__file__)
class PdfGeneratorTest(TestCase):
def test_generated_pdf_should_match_expectation(self):
# `pdf` is the blob of the generated PDF
# If using reportlab, this is what you get calling `getpdfdata()`
# on a Canvas instance, after all the drawing is complete
pdf = PdfGenerator().generate()
# PDFs are vectorial, so we need to set a resolution when
# converting to an image
actual_img = Image(blob=pdf, resolution=150)
filename = os.path.join(DIR, 'expected.pdf')
# Make sure to use the same resolution as above
with Image(filename=filename, resolution=150) as expected:
diff = actual.compare(expected, metric='root_mean_square')
self.assertLess(diff[1], 0.01)
Run Code Online (Sandbox Code Playgroud)
该0.01值是我们可以容忍的小差异的最低值。考虑到diff[1]使用指标的变化范围为 0 到 1 root_mean_square,与样本预期文件相比,我们在此接受所有通道上最多 1% 的差异。
"差异"是什么意思?PDF文本或某些布局更改的差异(例如,调整了嵌入图形的大小).第一个很容易检测,第二个几乎不可能得到(PDF是一种非常复杂的文件格式,提供无限的文件格式化功能).
如果你想获得文本差异,只需在两个PDF上运行pdf to text实用程序,然后使用Python的内置差异库来获得转换文本的差异.
这个问题涉及python中的pdf到文本转换:用于将PDF转换为文本的Python模块.
此方法的可靠性取决于您使用的PDF生成器.如果您使用例如Adobe Acrobat和一些基于Ghostscript的PDF-Creator从SAME word文档制作两个PDF,尽管源文档是相同的,您仍可能会得到差异.
这是因为有许多方法可以将源文档的信息编码为PDF,并且每个转换器使用不同的方法.通常,pdf到文本转换器无法找出正确的文本流,尤其是对于复杂的布局或表格.
我不知道你的用例,但是对于使用 reportlab 生成 pdf 的脚本的回归测试,我做 diff pdfs
例如
im1 = Image.open(imagePath1)
im2 = Image.open(imagePath2)
imDiff = ImageChops.difference(im1, im2)
Run Code Online (Sandbox Code Playgroud)
在我的情况下,这适用于标记由于代码更改而引入的任何更改。
| 归档时间: |
|
| 查看次数: |
11924 次 |
| 最近记录: |