Testes unitários em iOS

Eduardo Lombardi
4 min readAug 3, 2021

--

Photo by National Cancer Institute on Unsplash

Pode parecer um bicho de sete cabeças, mas não é. Neste artigo vou desmistificar o teste unitário , focando na plataforma de desenvolvimento mobile iOS.

A IDE Xcode ajuda a gente. Ao criar um arquivo novo podemos especificar que ele é de teste, escolhendo a opção descrita na imagem abaixo

Imagem que descreve as opções de novos arquivos para o Xcode com a opção Unit Test Case Class

O arquivo criado será como o abaixo:

Temos quatro funções criadas nele. A última pode ser descartada por enquanto, pois só será utilizada em casos mais específicos de testes de performance. Vamos ver como funcionam as outras:

  • setupWithError() — O código colocado aqui será executado antes de cada teste.
  • tearDownWithError() — O código colocado aqui será executado após cada teste
  • testExample() — O teste de fato. Todos os métodos de teste devem começar com a palavra test, e é de convenção que o nome das classes de teste termine com test.

Mas de fato o que é um teste? Onde vive? O que come? Sexta, no glob… Vamos ver 5 exemplos aqui que devem ajudar no entendimento dos testes, do mais básico ao mais complicado.

Exemplo 1: O título desta tela é “Minha lista”. Devemos criar uma função que compare o título da tela em questão com “Minha lista”. Se bater, tudo certo.

Exemplo 2: O mar é azul. Quando a gente for criar um teste, a gente vai ter que criar uma função que compare a cor do mar com azul. Isso previne que por exemplo, algum outro desenvolvedor chegue lá e troque a cor do mar para amarelo. Se ele o fizer, na hora que rodar o teste, o mesmo vai falhar.

Exemplo 3: Para dirigir um carro, precisamos estar com a chave do mesmo na ignição e colocar ela na posição de ligada garantindo que o carro esteja ligado. Nesse caso, podemos verificar se um determinado carro é dirigível, verificando se temos uma chave compatível presente na ignição do mesmo e se a mesma está na posição de ligada. Então criamos uma função que valida essas três coisas: A chave é compatível? Está na ignição? Está girada para a posição ligada? Caso uma dessas coisas falhe, o carro não é dirigivel.

Exemplo 4: Para chegar em tal tela, precisamos passar pelos métodos X, Y e Z. (Se atente ao fato de que isso podem ser camadas da arquitetura da aplicação) Precisamos criar uma função que garanta que, se a tela for exibida, passamos pelos métodos X,Y e Z. Para isso, podemos criar versões de teste de X,Y e Z, colocar variáveis de controle booleanas neles e garantir que todo mundo está verdadeiro. Se um desenvolvedor mudar alguma lógica de apresentação da tela em questão, o teste falhará.

Exemplo 5: Dada uma função qualquer no seu código que esteja na estrutura

Devemos nas funções de testes chamar a função passando valores nos argumentos e validando os resultados de acordo com o esperado. 2+2 não pode ser 5, certo? Se alguém alterar a lógica dentro da função que faça com que 2+2 resulte em 5, esse erro será capturado.

Nem toda função é testável e tudo bem. O que deve ser levado em conta é a idéia central do que está sendo desenvolvido. Ela deve sempre ser testada para evitar bugs. E seguindo os exemplos acima, você deve ter idéias de como desenvolver o que precisa para que a idéia seja testável.

Os mocks são seus amigos na hora do teste. Servem como uma representação simulada dos dados. Em um formulário você pode criar um objeto que represente o formulário preenchido e no teste garantir que, depois de passar pelas funções de "salvar" o mesmo, os dados presentes são os dados esperados, com a formatação correta. A injeção de dependência também ajuda, de modo que você pode extrapolar os mocks para simulações de protocolos. No botão de salvar do formulário apresentado acima esperamos que seja executada uma ação baseada no protocolo FormSaveDelegate. No teste você pode criar um objeto que conforma com esse protocolo e verificar se esse objeto foi instanciado corretamente, e se passou no método esperado do protocolo com as informações corretas.

O conjunto de testes unitários nada mais é no entanto, que simulações controladas do nosso código, exercitando todos os possíveis cenários. Provê garantias ao desenvolvedor, principalmente contra os sabotadores (ou criadores de bugs alheios). Se quiser saber mais sobre como evitar a criação de bugs alheios, recomendo este artigo

--

--