Como economizar muitas horas de trabalho através de automação de testes do seu jogo

0 Flares 0 Flares ×

Meu nome é Rogério Ranieri, sou paulistano, químico e mestre em engenharia civil pela Universidade de São Paulo.

Tenho cerca de 20 anos de experiência em desenvolvimento e gerenciamento de projetos de software onde pude trabalhar com equipes multidisciplinares em sistemas ERP e automação industrial.

Hoje trabalho com desenvolvimento de sistemas para automação de laboratórios químicos e farmacêuticos e também como desenvolvedor de games, usando Unity e C#.

Sobre a série de artigos Desenvolvimento de Games usando C#

Este é o primeiro de uma série de artigos que irá abordar técnicas e metodologias de desenvolvimento de games usando C#. Em muitos artigos terei que usar outras ferramentas, como o Unity, Facebook, Google, mas o ponto central sempre será a programação.

A internet está cheia de cursos básicos de linguagem C, então não pretendo escrever artigos básicos explicando sintaxe, mas sobre boas práticas de programação que podem ser aplicadas a games (ou em outros projetos também).

Vou compartilhar experiências e técnicas pude vivenciar em alguns projetos de desenvolvimentos de jogos ou em alguns casos sistemas ERP que participei como desenvolvedor ou gerente de projetos.

Nos próximos artigos irei abordar os seguintes temas:

  • “Desenvolvimento de software orientado a testes (TDD)” aplicado ao desenvolvimento de games;
  • Técnicas de desenvolvimento ágil;
  • Automação de testes;
  • Integração contínua e repositórios de códigos fonte;
  • Uso do Facebook Analytics para monitorar jogadas, performance do game e celulares (ou PC, console, etc.);
  • Uso de Frameworks como parse.com para gravar dados de usuários, criação de leaderboards e muito mais;
  • Construção de um Framework contendo classes que podem ser utilizadas em diversos tipos de games, como GameController, SceneController, GameManager, UserController, InputController e muitas outras. Neste artigos irei abordar algumas técnicas avançadas de programação em C# que irão facilitar sua vida no reuso de código, diminuindo o tempo de programação, gerenciamento e debug.

As publicações não irão seguir a ordem sequencial descrita acima e novos tópicos podem ser inseridos caso você, leitor, me envie um e-mail com sugestões.

Automação de Testes

Algumas semanas atrás alguém postou no fórum da Academia de Produção de Jogos uma questão sobre automação de testes em games.

Quando comecei a desenvolver jogos este foi um dos primeiros itens que me chamaram atenção, pois vindo de um mercado de ERP eu tive acesso a diversas ferramentas de testes (eu gosto muito do Telerik Test Studio) e integração contínua (eu uso o Jenkins), que facilitam a vida dos desenvolvedores e testadores aumentando a confiança no produto, reduzindo bugs e diminuindo o tempo entre cada versão do software.

Testar um sistema ERP com um formulário de input de dados é relativamente mais simples que testar um game.  Pense no seguinte exemplo:

Você quer automatizar os testes de um cadastro de clientes, incluindo validação de CEP, CNPJ, CPF, Inscrição estadual, etc.

As etapas para isso seriam:

  • Criar uma XML ou manter uma base de dados em um servidor SQL Server com dados genéricos para testes.
  • O sistema de testes abre a tela do sistema e lança em cada um dos campos os dados obtidos da base criada anteriormente.
  • Você pode lançar dados “bons” para ver se o cadastro é salvo com sucesso ou lançar dados “ruins”, como um CPF inválido, um telefone contendo letras ou mesmo um campo de extensão maior que o permitido.
  • A ferramenta de testes executa esta operação com alta velocidade e pode ser executada como uma função do Jenkins (vou falar mais sobre integração contínua em um próximo artigo), então, temos um fluxo de processos como abaixo:

fluxos-automacao

Este processo economiza inúmeras horas de trabalho da equipe de controle de qualidade e do programador, pois um bug que foi previsto ou já ocorreu e possui uma rotina automatizada de testes raramente irá voltar às mãos do time de qualidade.

Sem esta automação é frequente que um programador corrija o “bug A” e por conta disso crie o “bug B”. Depois, ao corrigir o bug B, o bug A é reintroduzido ao sistema, etc.

Além da agilidade, a automação dá confiança ao programador, que pode fazer alterações ou refatorar o código sabendo que o sistema completo será retestado e que novos bugs introduzidos serão detectados antes da equipe de qualidade ser envolvida.

Como reproduzir este processo num videogame?

O videogame não deixa de ser um software que recebe input de dados de uma pessoa e retorna algum tipo de resposta dependendo do input, então, a grosso modo, podemos criar um arquivo de dados (XML, TXT ou qualquer outro) de jogadas, movimentações e depois reaplica-la no game.

Citei anteriormente a integração continua e repositório de dados, mas podemos iniciar com algo bem mais simples. Os testes podem ser iniciados a partir de um click num botão.

Em um dos projetos que participei como desenvolvedor, o Plampi, eu vivenciei diversos desafios relacionados a testes e correção de bugs.

Nota do Raphael: Veja também a entrevista sobre o nascimento do jogo Plampi (inicialmente chamado de SMARP) – “Desenvolvedores Contam Como Fizeram um Jogo em 10 Dias

O Plampi é um Puzzle 2D (veja o trailler oficial) onde o jogador precisa conectar tubos e fazer a ligação entre um poço artesiano em um lençol freático.

As fases iniciais possuem mecânica simples e não apresentavam muitos bugs, porém em fases mais avançadas havia um GameObject chamado Toupeira, que além de infernizar o jogador tornou a vida do programador um pouco mais complicada, pois muitas vezes para reproduzir um bug era preciso jogar a fase por cerca de 1 ou 2 minutos.

A princípio você pode pensar que 2 minutos é pouco tempo, mas multiplique isso por tentativas frustradas de se encontrar um problema, testes para garantir que o problema foi corrigido e novos testes para garantir que o bug não foi reintroduzido a partir de uma nova alteração no game. Os 2 minutos transformam-se facilmente em 2 semanas.

Em outros casos, um jogador ou o próprio game designer reportam o bug, mas por ser um bug que ocorre em fases avançadas e depende da forma que o jogador joga, o programador nunca o consegue reproduzi-lo, acarretando em mais perda de tempo e atrasos.

Este problema foi resolvido com automação de testes e de forma bem simples:

Foram criados alguns parâmetros de sistema para rastrear as jogadas. Existe uma variável chamada “Testador” e criamos uma identificação de “Testadores” do game. Estas pessoas possuem um arquivo texto na pasta do jogo com algumas informações: nome, nível do usuário, interno ou externo entre outras.

Você provavelmente não irá querer que todos os celulares dos jogadores de seu game armazenem arquivos textos gigantes com informações das jogadas então pode ativar/desativar a log de jogadas baseadas na variável testador.

Exemplo:

A propriedade Application.persistentDataPath irá indicar a pasta Windows ou Android onde os dados do seu game serão armazenadas.

No Windows fica dentro da pasta dos usuários:

C:\Users\username\AppData\LocalLow\Spox Studio\Plampi

Esta é uma forma bem prática de chavear uma propriedade num celular sem a necessidade de recompilar o game.

Se o arquivo existe na pasta você ativa Testador (e tudo que depender dela) e, se não estiver, as funções de teste são desabilitadas (obviamente existem questões de segurança envolvidas neste processo que não irei discutir neste artigo).

Quando este jogador inicia o jogo, sabemos que ele está TESTANDO e todos os seus cliques ou toques na tela são rastreados numa base de dados local em seu aparelho ou em seu PC caso os testes estejam sendo realizados em um emulador.

Quando um bug é encontrado, o testador abre o arquivo com suas jogadas, procura a jogada que causou o erro, e envia para o programador através de um sistema de gerenciamento de bugs (utilizamos o https://freshdesk.com).

Os arquivos das jogadas são criados da seguinte forma:

 

Para o Plampi, este arquivo seria algo semelhante ao texto abaixo:

Fase Unity : 12 em 10/20/2015 2:03:27 PM
10,4,1|2,4,2|0,5,2|4,6,2|2,6,3|4,7,3|2,7,4|4,8,4|3,8,5|5,7,5|3,7,6|5,6,6|FINALIZOU FASE

A primeira linha da log indica claramente a fase, plataforma usada, data e hora da partida. A segunda linha indica quais foram as jogadas feitas pelo jogador. Cada uma das jogadas é composta por 3 números, sendo que o primeiro indica o tubo usado e os seguintes indicam as coordenadas no puzzle.

Existe uma Enum no projeto chamada Tipos de Canos:

Então, 10,4,1 é o poço colocado na coluna 4 e linha 1, sendo que a contagem das colunas e linhas começa por ZERO. Na imagem abaixo a linha e coluna ZERO estão destacadas em vermelho.

2,4,2 é um cotovelo-cima-direita, colocado na coluna 4 e linha 2, indicado abaixo pela seta amarela.

As jogadas são mapeadas até que o jogador complete a fase e a log grava FINALIZOU FASE.

Em caso de Game Over a log traria GAME OVER (vou escrever um próximo artigo mostrando como fizemos esta log no Facebook Analytics para rastrear quais são as fases que os jogadores têm mais dificuldades, quais são as fases que eles desistem, etc.)

automacao-jogos-desenvolvimento

Com estas logs evitamos que o programador seja interrompido para que lhe expliquem o bug e mantemos uma rastreabilidade do que foi corrigido. O programador copia o texto contendo as jogadas cria um GameObject de testes com a jogada daquele bug.

No Unity fica assim:

jogos-automacao-teste

Este GameObject pode ser executado automaticamente e o programador vê o bug acontecer. Após a correção, o programador pode reexecutar a rotina de testes e certificar-se que o bug foi realmente corrigido.

Uma vez que o ticket é fechado o GameObject de testes passa a ser um Ativo do projeto e pode ser reexecutado rapidamente antes de fazer uma publicação do game na loja, ou quando a equipe de controle de qualidade julgar necessário.

A figura abaixo mostra a lista de testes que é executada antes de uma publicação na loja Android:

desenvolvimento-jogo-teste

Considerações finais

A automação de testes vem nos ajudando muito, economizando tempo da equipe. Na Unity Asset Store existem diversos assets que ajudam neste processo.

Optamos pelo desenvolvimento de nossos próprios assets para conseguirmos flexibilidade de vincular os dados de testes ao Facebook e ao Parse.  

Este artigo foi uma breve introdução à automação de testes usando C#, mas outros artigos serão disponibilizados para quem tiver interesse em se aprofundar no assunto.

Se tiverem dúvidas não deixem de comentar abaixo.

Até o próximo Post! =)