2010-08-03 3 views
8

Sto utilizzando Java Graphics2D per generare una rappresentazione grafica di un grafico. Sto anche usando ImageIO per scrivere un file PNG. (ImageIO.write(image, "png", out);)Test di generazione grafica con JUnit

Mi chiedo come scrivere i test di JUnit per verificare se la grafica generata è quella prevista. Potrei pre-generare i file PNG, ma cosa succede se il carattere è un po 'diverso su una macchina diversa?

+2

Bene, di cosa vorresti essere sicuro? –

+0

Buona domanda :-) Ora, come penso, forse non è così importante verificare se l'immagine è esattamente come previsto ma se sono presenti alcune caratteristiche previste. – PeWu

risposta

1

Si potrebbe provare il test per specifici, le caratteristiche note della uscita ad es .:

  • E c'è un pixel bianco al numero (100,100)?
  • Il bordo è completamente nero?
  • L'immagine è la dimensione prevista?

E/o si potrebbe scrivere i test per alcune "proprietà aggregate" che permettono per qualche confusione nei risultati:

  • il soggetto inquadrato almeno il 90% partita l'immagine di riferimento? (per consentire caratteri diversi, differenze di antialiasing ecc.)
  • Il colore più comune nell'immagine è uguale al colore di sfondo?
+0

Grazie. Sembra una buona idea testare alcune funzionalità invece dei pixel bitmap. Come notato da Vineet, potrebbe esserci anche una differenza nell'antialiasing. – PeWu

1

È possibile leggere tutti i valori RGB delle immagini generate in una matrice e confrontare quello 2D-array con uno che rappresenta un'immagine pre-generata, se si è veramente specifici sull'immagine completa.

Se si desidera ignorare i caratteri, è possibile fare lo stesso per le stesse per le regioni dell'immagine che non contengono dati variabili a seconda dell'ambiente in cui sono generate le immagini. Costruire in routine di correzione e normalizzazione per i test unitari sarebbe una perdita di tempo, a meno che l'applicazione non sia in grado di generare immagini con una precisione così elevata come garantito.

+0

È possibile fornire un file di font al test dell'unità e disabilitare l'anti-aliasing per il test. Nella mia esperienza questo produce risultati identici anche su più piattaforme. – The111

2

Per me, questa implementazione concreta sembra funzionare:

private void compareRasterImages(BufferedImage expectedPngIo, BufferedImage actualPngIo) throws AssertionError { 
    int minX = expectedPngIo.getMinX(); 
    int minY = expectedPngIo.getMinY(); 
    int maxX = expectedPngIo.getMinX() + expectedPngIo.getWidth(); 
    int maxY = expectedPngIo.getMinY()+ expectedPngIo.getHeight(); 

    assertEquals(minX, actualPngIo.getMinX()); 
    assertEquals(minY, actualPngIo.getMinY()); 
    assertEquals(expectedPngIo.getHeight(), actualPngIo.getHeight()); 
    assertEquals(expectedPngIo.getWidth(), actualPngIo.getWidth()); 
    for (int x_i = minX; x_i < maxX; x_i++){ 
     for (int y_i = minY; y_i < maxY; y_i++) { 
      assertEquals(expectedPngIo.getRGB(x_i, y_i), actualPngIo.getRGB(x_i, y_i)); 
     } 
    } 
} 

ho recuperare la BufferedImage dal mio PNG (come byte []) utilizzando ImageIO:

BufferedImage expectedPngIo = ImageIO.read(new ByteArrayInputStream(expectedPng)); 
enter code here 
1

ho trovato questo essere efficace nel rendere i font renderizzati identici cross-platform per test di unità grafiche pixel perfette di cose semplici come il testo sovrapposto a un'immagine statica.

  1. Iniettare l'Font e FontRenderContext nella classe di rendering dei font, in modo che può essere controllato in prova.
  2. Fornire un file .ttf al test dell'unità e utilizzare Font.createFont() per generare un carattere dal file.
  3. Nel test dell'unità, disabilitare l'anti-aliasing nello FontRenderContext utilizzato. Se salti questo passaggio, i risultati variano a seconda della piattaforma.

Sono curioso se gli altri pensano che questo sia fragile o incline al fallimento per qualsiasi motivo, ma finora ho avuto buoni risultati.