Come posso eseguire l'output del rendering del test unitario?


19

Di recente ho abbracciato Test-Driven Development (TDD) e ha avuto impatti meravigliosi sul mio output di sviluppo e sulla resilienza della mia base di codice. Vorrei estendere questo approccio ad alcuni dei lavori di rendering che faccio in OpenGL, ma non sono stato in grado di trovare buoni approcci a questo.

Inizierò con un esempio concreto, quindi sappiamo quali tipi di cose voglio testare; diciamo che voglio creare un cubo di unità che ruota attorno ad un asse e che voglio assicurarmi che, per un certo numero di fotogrammi, ogni fotogramma sia reso correttamente.

Come posso creare un caso di test automatizzato per questo? Preferibilmente, sarei anche in grado di scrivere un test case prima di scrivere qualsiasi codice per eseguire il rendering del cubo (secondo le consuete pratiche TDD.) Tra le altre cose, vorrei assicurarmi che le dimensioni, la posizione e l'orientamento del cubo siano corretto in ogni fotogramma renderizzato. Potrei anche voler assicurarmi che le equazioni di illuminazione nei miei shader siano corrette in ogni frame.

L'unico approccio remotamente utile a questo che ho incontrato prevede il confronto dell'output renderizzato con un output di riferimento, che generalmente preclude la pratica TDD ed è molto ingombrante.

Potrei continuare su altri requisiti desiderati, ma temo che quelli che ho già elencato siano fuori portata.


3
L'intero problema qui è che il tuo test case è determinato da un buon output; ma cosa succede se quell'output è difettoso (falso positivo)? Ad ogni modo vorrei iniziare controllando prima i wireframe; quindi passa a una scena resa in avanti e infine differita (se la usi). Puoi XOR l'intera immagine per fare un rapido confronto (passaggi interamente neri). La GPU è davvero una brutta area per applicare TDD; ma se ti viene in mente qualcosa di intelligente, mi piacerebbe saperlo.
Jonathan Dickinson,

Ho il sospetto che non avrò esattamente la risposta che spero, ma spero ancora per alcune buone idee. Buona idea sul passaggio nero. Anche il test del buffer di profondità potrebbe essere utile.
notlesh


@Adam grazie per averlo condiviso. Purtroppo, è così fuori dalla portata di un indie come me a lavorare su giochi per cellulari :) Fallisce anche la maggior parte dei miei requisiti di base.
notlesh

@Adam dovresti assolutamente "rispondere" a quel link. Abbastanza romanzo.
Jonathan Dickinson il

Risposte:


8

Sembra una buona applicazione del framework dei test di approvazione o qualcosa del genere.

Come indicato nei commenti, continuerai a riscontrare un problema con falsi positivi, se ti capita di approvare un output errato, ma questo ALMENO ti dirà quando l'output è cambiato in modo significativo.

Dato che stai usando OpenGL, suppongo che le approvazioni non funzioneranno direttamente per te, ma l'idea è valida. Basta controllare l'hash del file e, se è diverso, mostrare l'errore in un visualizzatore diff appropriato (come un programma diff immagine). Se approvi la nuova versione, aggiorna il file "approvato" in modo che corrisponda al nuovo risultato.


Questo è uno strumento interessante. Se prendessi qualcosa come la farm di test nel link di Adam nei commenti sopra e applicassi un meccanismo di approvazione integrato come questo, probabilmente inizieresti ad avvicinarti a qualcosa che è piuttosto basso. Grazie per la condivisione!
notlesh

Il test di approvazione non è un test automatico.
zwcloud,

@zwcloud: cosa intendi? È automatizzato una volta creato, proprio come qualsiasi test. È solo che la prima approvazione fa parte del processo di creazione.
John Gietzen,

@JohnGietzen Non sono riuscito a capirlo dalla tua risposta. Penso che dovresti chiarire l'idea dei test di approvazione in modo più esplicito. Rimuoverò il downvote quando la risposta verrà aggiornata.
zwcloud,

6

Non mi occupo del gioco, quindi per favore sopporta ogni potenziale stupida e ingenua percezione

Per me, scrivere test che confrontano immagini completamente renderizzate non sono in realtà test unitari , ma test di integrazione completi , perché tutto deve funzionare bene per una corretta esecuzione del test.

Che dire di uno strato intermedio in cui è possibile verificare che tutto vada bene? Ci sono due cose che mi vengono in mente:

  1. Non disegnare direttamente, ma emettere un flusso di comandi che si trasforma in rendering chiamate lungo la strada. È possibile verificare la correttezza del flusso di comandi. Questo non è un test end-to-end, ma vuoi test unitari , non test di integrazione completi.

  2. Questa è davvero una variazione su 1. Avvolgi OpenGL, intercetta tutte le chiamate, riduci ciò che vuoi veramente testare e controlla se l'output corrisponde ancora. Il wrapper OpenGL può eseguire il controllo stesso se configurato correttamente e si trasforma in un mock .


3

Il problema è che i motori 3d non sono tenuti a produrre un'immagine bit per bit esatta. Un certo margine di manovra è tollerato fintanto che i manufatti da esso causati non sono visibili allo spettatore. Una trama più scura dell'1% del previsto non è di solito un problema serio ... di solito. In alcune condizioni potrebbe essere un artefatto visivo. E questo è il problema: è difficile giudicare per un test automatizzato quali artefatti sarebbero stati notati da uno spettatore umano e quali no. Tuttavia, i test automatizzati possono essere utilizzati per semplici controlli di integrità se utilizzati su geometrie molto semplici.

Quello che potresti fare è renderizzare alcune semplici scene e quindi confrontare l'immagine generata con un rendering di riferimento. Tale rendering di riferimento potrebbe provenire da un altro motore grafico o essere uno screenshot precedente dello stesso motore (test di regressione).

Quando alcuni test falliscono dopo una modifica al motore grafico, un tester umano dovrebbe confrontare l'output con l'immagine di riferimento e giudicare se stesso se il nuovo output ha lo stesso aspetto di prima (o anche meglio). In tal caso, il test deve essere modificato per confrontarlo con i nuovi output migliorati.

Un'altra cosa che puoi verificare automaticamente sono i requisiti di prestazione. Uno di questi requisiti potrebbe essere che durante una demo autogestita (simulando una sequenza reale dal gioco) il frame rate non deve scendere al di sotto di 40 Fps sul sistema di test. Questo è qualcosa che puoi testare automaticamente. Quello che non puoi testare è che il rendering è soddisfacente. Ma puoi usare questi test per impedire ai tuoi sviluppatori di sviluppare un gioco che sembra superbo ma non funziona correttamente su alcun sistema economico fino a anni dopo il lancio (ciao Crytek).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.