tiempo real hacer grafico graficas graficar funciones ejes ejemplos dibujar crear como codigos barras python unit-testing pdf-generation imagemagick cairo

hacer - ¿Cómo realizar una prueba unitaria de una función de Python que dibuja gráficos PDF?



graficar en tiempo real python (5)

Estoy escribiendo una aplicación CAD que genera archivos PDF utilizando la biblioteca de gráficos Cairo. Muchas de las pruebas unitarias no requieren realmente la generación de archivos PDF, como el cálculo de los cuadros de delimitación esperados de los objetos. Sin embargo, quiero asegurarme de que los archivos PDF generados "se vean" correctos después de cambiar el código. ¿Hay una forma automatizada de hacer esto? ¿Cómo puedo automatizar tanto como sea posible? ¿Necesito inspeccionar visualmente cada PDF generado? ¿Cómo puedo resolver este problema sin quitarme el pelo?


(Véase también la actualización a continuación!)

Estoy haciendo lo mismo usando un script de shell en Linux que envuelve

  1. El comando de compare de ImageMagick
  2. la utilidad pdftk
  3. Ghostscript (opcionalmente)

(Sería bastante fácil trasladar esto a un archivo .bat Batch para DOS / Windows).

Tengo algunos archivos PDF de referencia creados por mi aplicación que son "bien conocidos". Los PDF recién generados después de los cambios de código se comparan con estos PDF de referencia. La comparación se realiza píxel por píxel y se guarda como un nuevo PDF. En este PDF, todos los píxeles sin cambiar se pintan en blanco, mientras que todos los píxeles diferentes se pintan en rojo.

Aquí están los bloques de construcción:

pdftk

Utilice este comando para dividir archivos PDF de varias páginas en varios PDF de una sola página:

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

comparar

Utilice este comando para crear una página PDF "diff" para cada una de las páginas:

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

Debido a los metadatos que se insertan automáticamente (como la fecha y la hora actuales), la salida de PDF no funciona bien para las comparaciones de archivos basadas en MD5hash.

Si desea descubrir automáticamente todos los casos que consisten en páginas puramente blancas, también puede convertir a un formato de mapa de bits sin metadatos utilizando el dispositivo de salida bmp256 . Puede hacerlo para los PDF originales (referencia y comparación), o para las páginas diff-PDF:

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

Si el MD5sum es lo que usted espera de una página en blanco de 595x842 puntos PostScript, entonces su prueba de unidad pasó.

Actualizar:

No sé por qué no pensé anteriormente en generar una salida de histograma a partir de la compare ImageMagick ...

El siguiente es un canal de comando que encadena 2 comandos diferentes:

  1. el primero es el mismo que el de la compare anterior, que genera el formato de "los píxeles blancos son iguales, los píxeles rojos son diferencias" , y solo genera el formato interno de miff ImageMagick. No se escribe en un archivo, sino a la salida estándar.
  2. el segundo utiliza convert para leer la entrada estándar , generar un histograma y generar el resultado en forma de texto. Habrá dos líneas:
    • uno que indica el número de píxeles blancos
    • el otro indicando el número de píxeles rojos.

Aquí va:

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

Salida de muestra:

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

(La salida de muestra se generó utilizando estos archivos reference.pdf y current.pdf ).

Creo que este tipo de salida es muy adecuado para la prueba automática de unidades. Si evalúa los dos números, puede calcular fácilmente el porcentaje de "píxel rojo" e incluso podría decidir devolver PASADO o FALLIDO en función de un determinado umbral (si no necesita necesariamente "cero rojo" por algún motivo).


Escribí una herramienta en Python para validar archivos PDF para la documentación de mi empleador. Tiene la capacidad de comparar páginas individuales con imágenes maestras. Utilicé una biblioteca que encontré llamada swftools para exportar la página a PNG, luego usé la biblioteca de imágenes de Python para compararla con el maestro.

El código relevante se parece a esto (esto no se ejecutará ya que hay algunas dependencias en otras partes de la secuencia de comandos, pero debería tener una idea):

# 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())


La primera idea que aparece en mi cabeza es usar una utilidad de diferencias. Generalmente se utilizan para comparar textos de documentos, pero también pueden comparar el diseño del PDF. Usándolo, puede comparar la salida esperada con la salida suministrada.

El primer resultado que Google me da es this . Si bien es comercial, puede haber otras alternativas de código libre / abierto.


Lo intentaría usando xpresser - (https://wiki.ubuntu.com/Xpresser) Puede intentar hacer coincidir las imágenes con imágenes similares, no con copias exactas, lo cual es el problema en estos casos.

No sé si xpresser está siendo desarrollado activamente, o si se puede usar con archivos de imagen independientes (creo que sí). De todos modos, toma sus ideas del proyecto Sikuli (que es Java con una interfaz Jython, mientras que xpresser es Python).


Podría capturar el PDF como una imagen de mapa de bits (o al menos una comprimida sin pérdida) y luego comparar la imagen generada por cada prueba con una imagen de referencia de cómo se supone que debe ser. Cualquier diferencia se marcaría como un error para la prueba.