sexta-feira, 10 de setembro de 2010

sexta-feira, 3 de setembro de 2010

Contextualizando os seus testes

O Giovanni Bassi postou em seu blog sobre a técnica AAA (Arrange, Act, Assert) para criação de testes. Ele aproveita para abordar o principio de que cada teste só deve testar uma única coisa, e o quanto isso pode ser complicado.

Aproveitando o gancho, partindo do exemplo que ele apresentou da calculado, vamos implementar o método de divisão:

[TestClass]
public class TestCalculadora
{
    private Calculadora _calculadora;
    private int _resultado;

    [TestInitialize]
    public void Inicializar()
    {
        Arrange();
        Act();
    }

    private void Arrange()
    {
        _calculadora = new Calculadora();
    }

    private void Act()
    {
        _resultado = _calculadora.Dividir(10, 5);
    }

    [TestMethod]
    public void Resultado2()
    {
        Assert.AreEqual(2, _resultado);
    }
}

public class Calculadora
{
    public int Dividir(int a, int b)
    {
        return a / b;
    }
}

Legal, mas também precisamos testar a divisão por zero para saber como o método irá se comportar. Como podemos fazer isso?

É nesse momento que precisamos contextualizar nossos testes, isso significa que vamos testar a mesma rotina em cenários diferentes, no exemplo da calculadora precisamos gerar o cenário do dividir com o divisor maior que zero e divisor zero. Podemos testar conforme abaixo:

public abstract class TestarCalculadora
{
    protected Calculadora Calculadora { get; private set; }
    protected int Resultado { get; set; }

    [TestInitialize]
    public void Inicializar()
    {
        Arrange();
        Act();
    }

    private void Arrange()
    {
        Calculadora = new Calculadora();
    }

    protected abstract void Act();

}

[TestClass]
public class TestarDivisaoComDivisorMaiorQueZero : TestarCalculadora
{

    protected override void Act()
    {
        Resultado = Calculadora.Dividir(10, 5);
    }

    [TestMethod]
    public void ResultadoIgual2()
    {
        Assert.AreEqual(2, Resultado);
    }
}

[TestClass]
public class TestarDivisaoComDivisorZero : TestarCalculadora
{
    private bool _divisaoPorZeroGerada = false;

    protected override void Act()
    {
        try { Resultado = Calculadora.Dividir(10, 0); }
        catch (DivideByZeroException) { _divisaoPorZeroGerada = true; }
    }

    [TestMethod]
    public void ExcecaoDivisaoPorZeroGerada()
    {
        Assert.IsTrue(_divisaoPorZeroGerada);
    }

    [TestMethod]
    public void ResultadoIgualZero()
    {
        Assert.AreEqual(0, 0);
    }
}

Contextualizar os testes em cenários nos permite realizar várias verificações em vários cenários de uma mesma transação.
Essa é uma técnica muito simples, porém muito poderosa. Se você utiliza BDD com certeza já conhecia.