如何逐步测试PDF文件是否已正确生成?

时间:2016-07-20 13:38:07

标签: python unit-testing pdf pytest

我写了一个小的python库,使用matplotlib和seaborn绘制图表,我想知道如何测试图表是否与我真正想要的一样。

因此,给定一个我声明为正确的参考pdf文件,我如何自动检查它是否等于动态生成的文件与虚拟数据?

我认为由于时间戳等问题而散列文件是不可靠的。

2 个答案:

答案 0 :(得分:2)

为了与回归测试一起使用,我编写了diffpdf.sh来为PDF执行逐页的视觉差异。它使用ImageMagick和Poppler PDF实用程序pdftoppmpdfinfo

如果PDF显示不相同,则

diffpdf.sh将输出非零返回码,并打印不同页面的页码,以及反映页面差异的数字。每个页面的可视差异图像也会保存到pdfdiff目录。

#!/bin/bash

# usage: diffpdf.sh fidle_1.pdf file_2.pdf

# requirements:
# - ImageMagick
# - Poppler's pdftoppm and pdfinfo tools (works with 0.18.4 and 0.41.0,
#                                         fails with 0.42.0)

DIFFDIR="pdfdiff"                        # directory to place diff images in
MAXPROCS=$(getconf _NPROCESSORS_ONLN)    # number of parallel processes

pdf_file1=$1
pdf_file2=$2

function diff_page {
    # based on http://stackoverflow.com/a/33673440/438249
    pdf_file1=$1
    pdf_file2=$2
    page_number=$3
    page_index=$(($page_number - 1))

    (cat $pdf_file1 | pdftoppm -f $page_number -singlefile -gray - | convert - miff:- ; \
     cat $pdf_file2 | pdftoppm -f $page_number -singlefile -gray - | convert - miff:- ) | \
    convert - \( -clone 0-1 -compose darken -composite \) \
            -channel RGB -combine $DIFFDIR/$page_number.jpg

    if (($? > 0)); then
        echo "Problem running pdftoppm or convert!"
        exit 1
    fi
    grayscale=$(convert pdfdiff/$page_number.jpg -colorspace HSL -channel g -separate +channel -format "%[fx:mean]" info:)
    if [ "$grayscale" != "0" ]; then
        echo "page $page_number ($grayscale)"
        return 1
    fi
    return 0
}

function num_pages {
    pdf_file=$1

    pdfinfo $pdf_file | grep "Pages:" | awk '{print $2}'
}

function minimum {
    echo $(( $1 < $2 ? $1 : $2 ))
}

# guard agains accidental deletion of files in the root directory
if [ -z "$DIFFDIR" ]; then
    echo "DIFFDIR needs to be set!"
    exit 1
fi

echo "Running $MAXPROCS processes in parallel"

pdf1_num_pages=$(num_pages $pdf_file1)
pdf2_num_pages=$(num_pages $pdf_file2)

min_pages=$(minimum $pdf1_num_pages $pdf2_num_pages)

if [ "$pdf1_num_pages" -ne "$pdf2_num_pages" ]; then
    echo "PDF files have different lengths ($pdf1_num_pages and $pdf2_num_pages)"
    rc=1
fi

if [ -d "$DIFFDIR" ]; then
    rm -f $DIFFDIR/*
else
    mkdir $DIFFDIR
fi


# get exit status from subshells (http://stackoverflow.com/a/29535256/438249)
function wait_for_processes {
    local rc=0

    while (( "$#" )); do
        # wait returns the exit status for the process
        if ! wait "$1"; then
            rc=1
        fi
        shift
    done
    return $rc
}

function howmany() {
    echo $#
}

rc=0
pids=""
for page_number in `seq 1 $min_pages`;
do
    diff_page $pdf_file1 $pdf_file2 $page_number &
    pids+=" $!"
    if [ $(howmany $pids) -eq "$MAXPROCS" ]; then
        if ! wait_for_processes $pids; then
            rc=1
        fi
        pids=""
    fi
done

if ! wait_for_processes $pids; then
    rc=1
fi

exit $rc

编辑:可以找到用Python编写的此脚本的改进版here

答案 1 :(得分:1)

一些想法:

  • 使用diff-pdf
  • 将其转换为图片(例如使用ImageMagick)并使用PerceptualDiff
  • 以某种方式从PDF中获取数据(PyPDF2可能?)并比较
  • 使用某些东西(PyPDF2?pdftk?)将标题信息(如时间戳)修补到文件相等的点并比较哈希