2016-07-20 4 views
-1

Ich schreibe eine kleine Python-Bibliothek, die Matplotlib und Seaborn verwendet, um Diagramme zu zeichnen, und ich frage mich, wie ich testen kann, ob die Diagramme so aussehen, wie ich eigentlich will.Wie kann ich prüfen, ob PDF-Dateien korrekt generiert wurden?

Also, bei einer Referenz-PDF-Datei, die ich als richtig deklariert habe, wie würde ich automatisch prüfen, ob es einer dynamisch erzeugten Datei mit Dummy-Daten entspricht?

Ich gehe davon aus, dass es nicht zuverlässig ist die Datei aufgrund Zeitstempel usw.

Antwort

0

Einige Ideen hash:

  • Verwenden diff-pdf
  • wandelt es in ein Bild (zB ImageMagick) und verwenden PerceptualDiff
  • Holen Sie die Daten aus dem PDF irgendwie (PyPDF2 vielleicht?) Und vergleichen Sie das
  • Verwenden Sie etwas (PyPDF2? pdftk?) Die Header-Informationen zu patchen (wie Zeitstempel) zu dem Punkt, die Dateien gleich sind und Hashes
1

Für mit Regressionstests Verwendung vergleichen, ich habe diffpdf.sh geschrieben, um einen Seite-an-Seite visuellen diff für PDF-Dateien ausführen . Es verwendet ImageMagick und die Poppler PDF-Dienstprogramme pdftoppm und pdfinfo.

diffpdf.sh gibt einen Rückgabecode ungleich null aus, wenn die PDFs nicht identisch angezeigt werden und die Seitennummern für die unterschiedlichen Seiten sowie eine Zahl, die angibt, wie stark die Seiten unterschiedlich sind, gedruckt werden. Ein visuelles Diff-Bild für jede Seite wird ebenfalls im Verzeichnis pdfdiff gespeichert.

#!/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 

EDIT: Eine verbesserte Version dieses Skripts kann here finden in Python geschrieben.