É prático usar uma estrutura de teste como o JUnit em uma situação de desenvolvimento de jogos? Que tipo de considerações de design você pode seguir para tornar seu jogo mais testável? Quais partes de um jogo podem / devem ser testadas e quais partes devem / devem ser deixadas para testes em humanos?
Por exemplo, se o loop do jogo estiver encapsulado em uma função, parece que seria terrivelmente difícil de testar. Eu gosto de refatorar uma função de "atualização" que leva um tempo delta e avança a lógica do jogo; isso permite alguns truques interessantes, como a capacidade de desacelerar o jogo, alimentando deltas falsos e mais lentos.
architecture
unit-testing
Ricket
fonte
fonte
Respostas:
Um dos princípios do TDD é que você permite que o TDD, em alguns casos, influencie seu design. Você escreve um teste para o sistema, depois escreve o código para fazer esse teste passar, mantenha as dependências o mais superficial possível.
Para mim, existem apenas duas coisas que não testo como parte do teste de unidade:
Primeiro, não testo elementos visuais e como as coisas se parecem. Eu testei que e o objeto estará no lugar certo após a atualização, que uma câmera selecionará um objeto fora dos limites, que as transformações (pelo menos as que são feitas fora dos shaders) são executadas corretamente antes de serem entregues ao mecanismo gráfico , mas assim que atinge o sistema gráfico, eu traço a linha. Não gosto de zombar de coisas como o DirectX.
Segundo, eu realmente não testei a função principal do loop do jogo. Testo que todo sistema funcionará quando for aprovado em um delta razoável e que os sistemas funcionem juntos corretamente quando necessário. Depois, atualizo cada sistema com o delta correto no loop do jogo. Na verdade, eu poderia fazer um teste para mostrar que cada sistema foi chamado com o delta correto, mas em muitos casos eu acho esse exagero (a menos que você esteja fazendo uma lógica complexa para obtê-lo, então não há exagero).
fonte
Noel Llopis cobriu os testes unitários na medida em que acredito que você está procurando:
Com relação ao teste de todo o ciclo do jogo, há outra técnica para impedir regressões funcionais no seu código. A idéia é fazer com que seu jogo seja reproduzido por meio de um sistema de repetição (por exemplo, primeiro a gravação das entradas dos jogadores e, em seguida, reproduzi-las em uma execução diferente). Durante a reprodução, você gera um instantâneo do estado de cada objeto para cada quadro. Essa coleção de estados pode então ser chamada de "imagem de ouro". Ao refatorar seu código, você executa a reprodução novamente e compara o estado de cada quadro ao estado de imagem dourada. Se for diferente, o teste falhou.
Embora os benefícios dessa técnica sejam óbvios, há algumas coisas com as quais você precisa ter cuidado:
fonte
Concordo com os comentários de Jeff e jpaver. Eu também queria acrescentar que a adoção de um modelo de componente para sua arquitetura aumenta muito a testabilidade. Com um modelo de componente, cada componente deve estar executando uma única unidade de trabalho e deve ser testado isoladamente (ou com objetos simulados limitados).
Da mesma forma, as outras partes do jogo que dependem de entidades devem confiar apenas em um subconjunto dos componentes para funcionar. Na prática, isso significa que você geralmente pode simular alguns componentes falsos para facilitar o teste dessas áreas ou simplesmente compor entidades parciais para fins de teste. por exemplo, você deixa de fora os componentes de renderização e entrada porque eles não são necessários para testar a física.
Por fim, eu ignoraria os conselhos sobre desempenho que você recebe de algumas pessoas da comunidade de jogos sobre interfaces. Escreva o código bem com interfaces e, se tiver problemas de desempenho no futuro, poderá criar um perfil, identificar e refatorar facilmente para resolver o problema. Não fiquei convencido pelas preocupações de Noel sobre o impacto no desempenho das interfaces ou a sobrecarga de complexidade que elas adicionaram.
Dito isto, não exagere tentando testar cada coisinha de forma independente. Como a maioria das coisas, o teste e o design têm como objetivo encontrar o equilíbrio certo.
fonte
Pensei em adicionar uma segunda resposta, respondendo ao comentário do OP de que o usuário poderia substituir os testes de unidade. Acredito que isso esteja completamente errado, pois o objetivo dos testes de unidade não é garantir a qualidade. Se você deseja realizar testes para garantir a qualidade do seu programa, provavelmente deve investigar testes de cenário ou investir em um ótimo monitoramento.
(Com um ótimo monitoramento e um produto em execução como serviço, é realmente possível enviar alguns "testes" ao cliente, mas você precisa de um sistema sofisticado que detecte erros rapidamente e reverta as alterações responsáveis. Provavelmente isso é demais para uma pequena equipe de desenvolvimento.)
O principal benefício dos testes de unidade é que eles forçam o desenvolvedor a escrever um código melhor projetado. O ato de testar desafia o desenvolvedor a separar preocupações e encapsular dados. Também incentiva o desenvolvedor a usar interfaces e outras abstrações para que ele teste apenas uma coisa.
fonte