Estive adotando o TDD (Test-Driven Development) recentemente e isso teve um impacto maravilhoso no resultado do meu desenvolvimento e na resiliência da minha base de código. Gostaria de estender essa abordagem a alguns dos trabalhos de renderização que faço no OpenGL, mas não consegui encontrar boas abordagens para isso.
Vou começar com um exemplo concreto para sabermos que tipo de coisas eu quero testar; digamos que eu queira criar um cubo de unidade que gire em torno de algum eixo e que garanta que, para algum número de quadros, cada quadro seja renderizado corretamente.
Como posso criar um caso de teste automatizado para isso? De preferência, eu seria capaz de escrever um caso de teste antes de escrever qualquer código para renderizar o cubo (por práticas usuais de TDD). Entre muitas outras coisas, eu gostaria de garantir que o tamanho, o local e a orientação do cubo sejam correto em cada quadro renderizado. Talvez eu queira ter certeza de que as equações de iluminação em meus shaders estão corretas em cada quadro.
A única abordagem remotamente útil que encontrei envolve a comparação da saída renderizada com uma saída de referência, que geralmente impede a prática do TDD, e é muito complicada.
Eu poderia continuar com outros requisitos desejados, mas temo que os que eu listei já estejam fora de alcance.
Respostas:
Parece uma boa aplicação da estrutura Testes de aprovação ou algo parecido.
Conforme declarado nos comentários, você ainda terá um problema com falsos positivos, se aprovar resultados ruins, mas isso indica pelo menos quando a saída mudou significativamente.
Como você está usando o OpenGL, presumo que as aprovações não funcionem diretamente para você, mas a ideia é sólida. Basta verificar o hash do arquivo e, se for diferente, mostrar a falha em um visualizador de diferenças apropriado (como um programa de diferenças de imagem). Se você aprovar a nova versão, atualize o arquivo "aprovado" para corresponder ao novo resultado.
fonte
Eu não sou do ramo de jogos, então, por favor, tenha qualquer percepção estúpida e ingênua em potencial
Para mim, escrever testes que comparem imagens totalmente renderizadas não são realmente testes de unidade , mas testes de integração completa , porque tudo tem que funcionar bem para uma execução de teste bem-sucedida.
Que tal uma camada intermediária onde você pode verificar se está tudo bem? Há duas coisas que me vêm à mente:
Não desenhe diretamente, mas emita um fluxo de comando que se transforma em renderizar chamadas no caminho. O fluxo de comando pode ser verificado quanto à correção. Este não é um teste de ponta a ponta, mas você deseja testes de unidade , não testes de integração completa.
Essa é realmente uma variação do 1. Envolva o OpenGL, atenda todas as chamadas, reduza para o que você realmente deseja testar e verifique se a saída ainda corresponde. O wrapper OpenGL pode fazer a própria verificação, se configurado corretamente, e se transforma em uma farsa .
fonte
O problema é que os motores 3D não precisam gerar uma imagem exata, bit a bit. Alguma margem de manobra é tolerada desde que os artefatos causados por ela não sejam visíveis para o visualizador. Uma textura 1% mais escura que o esperado geralmente não é um problema sério ... geralmente. Sob algumas condições, pode ser um artefato visual. E esse é o problema: é difícil julgar por um teste automatizado quais artefatos seriam notados por um espectador humano e quais não são. Ainda assim, testes automatizados podem ser usados para verificações simples de sanidade quando usados em geometria muito simples.
O que você pode fazer é renderizar algumas cenas simples e comparar a imagem gerada com uma renderização de referência. Essa renderização de referência pode vir de outro mecanismo gráfico ou ser uma captura de tela anterior do mesmo mecanismo (teste de regressão).
Quando alguns testes falham após uma alteração no mecanismo gráfico, um testador humano deve comparar a saída com a imagem de referência e julgar por si próprio se a nova saída parece tão boa quanto antes (ou melhor ainda). Nesse caso, o teste deve ser alterado para comparar com os novos e aprimorados resultados.
Outra coisa que você pode verificar automaticamente são os requisitos de desempenho. Um desses requisitos poderia ser que, durante uma demonstração de execução automática (simulando uma sequência real do jogo), a taxa de quadros não caia abaixo de 40 Fps no sistema de teste. Isso é algo que você pode testar automaticamente. O que você não pode testar é que a renderização é satisfatória. Mas você pode usar esses testes para impedir que seus desenvolvedores desenvolvam um jogo que pareça excelente, mas que não funcione adequadamente em nenhum sistema acessível até anos após o lançamento (olá Crytek).
fonte