O que é Teste Unitário?

A qualidade do software é uma das variáveis mais complexas de um software. Vai desde o processo administrativo até o padrão de código aplicado. Qualquer dia eu falo de qualidade e outras coisas do gênero; hoje vou falar apenas sobre uma pequena fatia dessa torta: Testes Unitários.
Os testes unitários têm um objetivo simples: garantir que os retornos dos métodos estejam de acordo com as expectativas. Certamente existem definições melhores e mais completas, mas repare: não falei que teste garante a qualidade. É um erro comum acreditar que os testes são a solução para todos os problemas, a bala de prata, infelizmente não são.
Testes unitários são aplicados as unidades de código, como funções, propriedades, procedures e semelhantes.  Veja uma código de exemplo de uma calculadora simples, como exemplo.

namespace calculadora
{
    public class Calculadora
    {
        int soma(int i, int j)
        {
            return i + j;
        }
        int multiplicacao(int i, int j)
        {
            return i * j;
        }
        int subtracao(int i, int j)
        {
            return i - j;
        }
        int divisao(int i, int j)
        {
            return i / j;
        }
    }
}
Parece um código simples demais para um programador  vacilar e cometer erros. Mas, vamos ver.

Como seria um teste unitário?
Veja um  teste unitário aplicado a calculadora do exemplo:
[TestMethod()]
public void CalculadoraConstructorTest()
{
    Calculadora target = new Calculadora();
}

[TestMethod()]
[DeploymentItem("calculadora.exe")]
public void divisaoTest()
{
    Calculadora_Accessor target = new Calculadora_Accessor();
    int i = 50;
    int j = 2;
    int expected = 25;
    int actual;
    actual = target.divisao(i, j);
    Assert.AreEqual(expected, actual);
}
[TestMethod()]
[DeploymentItem("calculadora.exe")]
public void multiplicacaoTest()
{
    Calculadora_Accessor target = new Calculadora_Accessor();
    int i = 50;
    int j = 2;
    int expected = 100;
    int actual;
    actual = target.divisao(i, j);
    Assert.AreEqual(expected, actual);
}

[TestMethod()]
[DeploymentItem("calculadora.exe")]
public void somaTest()
{
    Calculadora_Accessor target = new Calculadora_Accessor();
    int i = 50;
    int j = 2;
    int expected = 52;
    int actual;
    actual = target.divisao(i, j);
    Assert.AreEqual(expected, actual);
}

[TestMethod()]
[DeploymentItem("calculadora.exe")]
public void subtracaoTest()
{
    Calculadora_Accessor target = new Calculadora_Accessor();
    int i = 50;
    int j = 2;
    int expected = 48;
    int actual;
    actual = target.divisao(i, j);
    Assert.AreEqual(expected, actual);
}


Parece muito simples e fácil. Parece até mesmo desnecessário de tão óbvio. Entretanto, este teste está incorreto. Ele não considera que a classe Calculadora poderia realizar divisões por zero ou gerar estouros de buffer. Num projeto com diversas classes e chamadas os testes unitários ganham destaque.

Porque os testes unitários não garantem qualidade?
Não garantem porque o número de variantes de testes possíveis é grande demais. E a avaliação sobre que testes devem ser feitos e como devem ser feitos é humana, e não automática. A variável humana insere infinitas incertezas aos projetos de teste.

Porque utilizar Testes Unitários?
Eles são úteis para melhorar a qualidade dos softwares. Quando um software é modificado é comum perceber vários problemas decorrentes da alteração. Uma modificação impacta diversas coisas que nem sempre são pensadas pelos programadores, em primeiro momento. Aí que entra o teste unitário. É possível, automaticamente rodar todos os testes unitários e saber o impacto unitário da modificação realizada.

Passo a Passo: Como Fazer Teste Unitário no Visual Studio?
Novo Projeto

Projeto de Teste

Projeto de teste criado

Adicionar > Teste Unitário

Wizard para criação de Testes Unitários

Projeto criado pelo wizard

Projeto Alterado para refletir a realidade

Testes realizados pelo Visual Studio

Um comentário: