Code Snippet para TestMethods no VisualStudio

Filed Under (.NET, Boas Práticas, TDD, Visual Studio 2010) by Vinicius Quaiato on 09-03-2010

Tagged Under : ,

Sempre achei um “pé” ter que ficar copiando métodos de teste, tudo pela preguiça de colocar o attribute [TestMethod] public void etc, etc.

Criei um CodeSnippet pra ser usado com C# que resolve alguns desses problemas. Abaixo segue o código do Snippet, à noite eu mostro como inserir o mesmo no VisualStudio, e coloco um link para download também:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2010/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Test Method</Title>
      <Shortcut>test</Shortcut>
      <Description>Code snippet to create a test method</Description>
      <Author>Vinicius Quaiato</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>Test_Method_Name</ID>
          <ToolTip>The name of the method. Try using a name that indicates the purpose of the test</ToolTip>
          <Default>Test_Method_Name</Default>
       </Literal>
     </Declarations>
     <Code Language="csharp">
       <![CDATA[	[TestMethod]
	public void $Test_Method_Name$()
	{   
 
	}]]>
     </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Espero que ajude um pouco. É mais rápido digitar “test + tab + tab” do que copiar, colar e alterar o nome do método anterior.

Abraços,
Vinicius Quaiato.

Dojo .Net Architects: Vídeo e Apresentação

Filed Under (.NET, Boas Práticas, Dojos, Publicações, TDD) by Vinicius Quaiato on 27-02-2010

Tagged Under : , ,

Fala galera. Abaixo está o vídeo e apresentação do Coding Dojo do .Net Architects.

Apresentação:

Vídeo do Dojo:

Mais detalhes podem ser vistos aqui:
http://dojo.dotnetarchitects.net/index.php/2010/02/27/resultado-1-coding-dojo-net-architects/

Abraços,
Vinicius Quaiato.

Coding Dojo .NET Architects – 30/01/2010 – São Paulo

Filed Under (.NET, Boas Práticas, Dojos, TDD) by Vinicius Quaiato on 29-01-2010

Tagged Under : , ,

Fala galera! Sábado, dia 30/01/2010 teremos um Coding Dojo, organizado pela comunidade .NET Architects.

Este Coding Dojo dará início ao grupo de Dojo do .NET Architects, que fará encontros regulares focando os dojos nas diversas linguagens e tecnologias .NET.

Local: Unip Jaguaré – São Paulo – SP
Horário: à partir das 10hs
Data: sábado, 30/01/2010

Confira o mapa do local e faça sua incrição aqui: http://dojo.dotnetarchitects.net
Totalmente gratuito!

Não existem pré-requisitos para participar, basta ter vontade e comparecer!

Saiba mais sobre Coding Dojo aqui.

Abraços, nos vemos lá!

Vinicius Quaiato.

TDD na .Net Magazine 69

Filed Under (.NET, Boas Práticas, Publicações, TDD) by Vinicius Quaiato on 07-01-2010

Tagged Under : , ,

.NET Magazine edição 69

Acaba de chegar às bancas a .NET Magazine com um artigo sobre TDD.

Neste artigo eu demonstro passo-a-passo a utilização do TDD na criação de uma simples aplicação de compras.

Vários dos benefícios do TDD são demonstrados na prática.

O link para a matéria online é:
http://www.devmedia.com.br/articles/viewcomp.asp?comp=15242

Série de posts sobre TDD aqui no blog:
http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c/

http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-ii/

http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-iii/

http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-iv/

É isso aê galera, boa leitura e dêem seu feedback!

Abraços, Vinicius Quaiato.

TDD – Test-driven Development + c# + Mocks – Parte IV

Filed Under (.NET, Boas Práticas, TDD) by Vinicius Quaiato on 09-11-2009

Tagged Under : , , ,

Fala galera, beleza?

Dando continuidade a nossa série de artigos sobre TDD, vamos hoje falar de um ponto muito interessante: Mocks.

Artigos anteriores:

Parte I – http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c/
Parte II – http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-ii/
Parte III – http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-iii/

De uma maneira resumida mocks são objetos que simulam o comportamento de outros objetos. Desta forma quando testamos com mocks geralmente testamos o comportamento entre os objetos e não os seus estados.

Utilizar mocks é algo muito interessante, pois eles nos permitem realizar testes com objetos “de mentira” ao invés de objetos que temos implementados como bancos de dados, serviços, web services, por exemplo. Ou seja, conseguimos verificar o comportamente de nossos objetos de negócios quando relacionados com objetos/ações que não temos o controle para testar (por exemplo uma ida ao web service), ou que são muito pesadas para colocar em unit testes automatizados (idas ao banco, chamadas a um webservice, envios de e-mail, etc).

Vamos continuar nosso exemplo das contas bancárias, e imaginar que a cada operação se depósito realizada é necessário utilizar um webservice do banco para registrar um log da ação.

Não vou abordar a criação do Web Service, e de fato nem vou utilizar um, vamos apenas definir que ele implementa a seguinte interface que recebe uma string com o nome da operação e o valor:

public interface IWebServiceContas
{
    string RegistrarOperacaoEmConta(string nomeOperacao, decimal valorOperacao);
}

Para trabalhar com mocks neste post utilizarei o framework Moq(lê-se Mock you), que pode ser baixado aqui: http://code.google.com/p/moq/

Para que possamos adicionar este comportamento às nossas contas(fazer chamada ao webservice), precisaremos alterar o código que já funciona, desta forma os testes que já existem nos ajudarão a saber se algo novo quebrou algo que já estava funcionando.
Vamos começar criando um teste de depósito que deverá fazer uma chamada para o webservice:

[TestMethod]
public void Deve_Realizar_Deposito_10_E_Chamar_WebService()
{
    var conta = new ContaBancaria(10);
    conta.Depositar(10);
}

Este teste por enquanto só está realizando o depósito, precisamos então garantir que o webservice seja chamado, e é utilizando um mock que faremos isso.
Adicione a dll do Moq ao seu projeto:

Adicionar Dll Moq

Adicionar Dll Moq

Agora vamos criar nosso primeiro mock e também incluir a referência na classe de testes:

using Moq;

e

[TestMethod]
public void Deve_Realizar_Deposito_10_E_Chamar_WebService()
{
    var mockWebService = new Mock<IWebServiceContas>();
 
    var conta = new ContaBancaria(10);
    conta.Depositar(10);
}

Podemos perceber que, agora, estamos com um problema. Nossa classe de contas não possui uma instância de IWebServiceContas, e não me parece uma boa solução passar esta instância para o método Depositar. Sendo assim, vamos deixar este teste “pausado” por enquanto.
Para fazermos isso basta colocarmos o Attribute [Ignore] antes do teste e ele não será executado:

[Ignore]
[TestMethod]
public void Este_Teste_Esta_Ignorado() { //teste ignorado }

Vamos alterar nossos testes para que garantam que a nossa conta receba uma instância de IWebServiceContas(injeção de dependância) no seu construtor, para isso vamos alterar nosso primeiro teste bem como o seu nome (lembrem, os testes devem evoluir junto com o código e com o modelo do domínio):

[TestMethod]
public void Deve_Criar_Conta_Com_Deposito_Inicial_E_InstanciaWebService()
{
    Mock mockWebService = new Mock<IWebServiceContas>();
 
    ContaBancaria conta = new ContaBancaria(50, mockWebService.Object);
 
    Assert.AreEqual(50, conta.SaldoAtual);
}

Ok, agora nada compila. Perfeito! Vamos alterar nossa classe para que ela receba um objeto que implemente IWebServiceContas:

public ContaBancaria(decimal depositoInicial, IWebServiceContas webservice)
{
    Validar(depositoInicial);
 
    this.SaldoAtual += depositoInicial;
}

Comos todos os nossos testes criam instâncias de contas, vamos atualizá-los para que compilem e então vamos executar todos os testes:

Executando todos os testes

Executando todos os testes

Agora podemos voltar ao teste que estávamos escrevendo, afinal nossa alteração não quebrou nada.
Para que configuremos nosso mock para atuar como o webservice precisamos fazer seu setup (linhas 5 e 6), e depois verificamos se tudo ocorreu como esperado (linha 11):

[TestMethod]
public void Deve_Realizar_Deposito_10_E_Chamar_WebService()
{
    var mockWebService = new Mock<IWebServiceContas>();
    mockWebService
        .Setup(ws => ws.RegistrarOperacaoEmConta("Depósito", 10));
 
    var conta = new ContaBancaria(10, mockWebService.Object);
    conta.Depositar(10);
 
    mockWebService.VerifyAll();
}

O que fizemos nas linhas 5 e 6 foi dizer ao mock “hey mock! Espero que o método RegistrarOperacaoEmConta seja chamado com os argumentos “Depósito” e 10″.
Depois na linha 11 dizemos para ele “hey! Verifique se tudo o que eu configurei aconteceu aê!”.
Desta forma nosso mock se comporta como se fosse o webservice, ele está imitando o comportamento do webservice através de sua interface IWebServiceContas, com a enorme vantagem de que temos total controle sobre o mock e não estamos dependentes do webservice e nem de uma implementação concreta para testar.

Se rodarmos nossos testes teremos:

Executand teste com Mock do Moq

Executand teste com Mock do Moq

É bem simples o que aconteceu, configuramos nosso mock dizendo que o método RegistrarOperacaoEmConta seria chamado, no entanto esse método não foi chamado. Para isso precisamos alterar nossa classe conta, para que de fato ela chame o método do webservice (ou melhor, do objeto que implementa a interface do webservice).
Porém quando passamos o parâmetro no construtor da nossa classe de ContaBancaria não armazenamos este objeto em um campo da classe. Vamos então criar uma propriedade privada deste tipo na classe conta bancária(linhas 5 e 9):

public class ContaBancaria
{
    //outros membros da classe
 
    private IWebServiceContas webServiceContas = null;
 
    public ContaBancaria(decimal depositoInicial, IWebServiceContas webservice)
    {
        this.webServiceContas = webservice;
 
        Validar(depositoInicial);
 
        this.SaldoAtual += depositoInicial;
    }
//continuação da classe

Agora que fizemos uma alteração, vamos rodar todos os testes e ver se tudo está ok. O resultado deve ser de que tudo está funcionando perfeitamente.

Agora vamos retomar a alteração do método Depositar para que ele passe no teste do mock:

public void Depositar(decimal valorDoDeposito)
{
    this.SaldoAtual += valorDoDeposito;
 
    this.webServiceContas.RegistrarOperacaoEmConta("Depósito", 10);
}

E quando rodamos os testes obtivemos vários erros:

Rodando Teste Mock

Rodando Teste Mock

Isso ocorreu pois eu alterei meus testes passando null para o parâmetro do IWebServiceContas, desta forma vou acrescentar uma validação extra ao meu construtor, garantindo que o serviço esteja presente na construção da conta (vamos imaginar que é uma regra):

[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void Deve_Lancar_Excecao_Deposito_Inicial_Valido_E_Servico_Nulo()
{
    ContaBancaria conta = new ContaBancaria(10, null);
}

E agora altero o construtor para respeitar a regra:

public ContaBancaria(decimal depositoInicial, IWebServiceContas webservice)
{
    Validar(depositoInicial);
    Validar(webservice);
 
    this.webServiceContas = webservice;
    this.SaldoAtual += depositoInicial;
}
 
private void Validar(IWebServiceContas webservice)
{
    if (webservice == null)
        throw new ArgumentException("Serviço de Contas não pode ser nulo!");
}

E rodando os testes vamos ver que só falharam os lugares onde eu mantive o construtor passando null, ou seja, sem respeitar a regra, desta forma vou atualizar os testes para respeitar.

Agora vou executar novamente todos os testes e ver o que aconteceu:

Rodando Todos Testes e Teste Mock

Rodando Todos Testes e Teste Mock

Pronto agora podemos ver que até mesmo nosso teste com o mock está funcionando!

O que isso quer dizer? Quer dizer que a nossa classe ContaBancaria está se comportando como esperado. Está está enviando uma chamada para o objeto webservice, passando os parâmetros corretamente no momento em que é feito um depósito.
Para garantir isso, vamos escrever mais um teste, passando outros valores:

[TestMethod]
public void Deve_Realizar_Deposito_15_E_Chamar_WebService_Passando_Deposito_E_Valor_15()
{
    var mockWebService = new Mock<IWebServiceContas>();
    mockWebService
        .Setup(ws => ws.RegistrarOperacaoEmConta("Depósito", 15));
 
    var conta = new ContaBancaria(10, mockWebService.Object);
    conta.Depositar(15);
 
    mockWebService.VerifyAll();
}

Este teste irá falhar, pois eu deixei hardcoded a chamada para o webservice dentro do método, para isso vamos alterar a chamada do método:

public void Depositar(decimal valorDoDeposito)
{
    this.SaldoAtual += valorDoDeposito;
 
    this.webServiceContas.RegistrarOperacaoEmConta("Depósito", valorDoDeposito);
}

E finalmente, rodando nossos testes:

Rodando Todos Testes e Testes com Mocks passando

Rodando Todos Testes e Testes com Mocks passando

Bom galera é isso.
Sei que existe muito mais complexidade em realizar testes, usar mocks, etc. E sei também que TDD não é algo que podemos sair aplicando da noite para o dia. É preciso maturidade. No entanto a maturidae só virá com a prática e a utilização.
Corroborando o Giovanni Bassi: “Testar é caro, não testar é mais caro ainda!”.

Neste post vimos como usar mocks, e também vimos como os testes nos ajudaram a encontrar erros, afinal, fizemos algumas alterações no código e alguns testes pararam de rodar. É disso que eu estou falando! É para isso que os testes servem!

Qualquer dúvida podem entrar em contato comigo.

Abraços,
Vinicius Quaiato.

TDD – Test-driven Development + c# – parte III

Filed Under (.NET, Boas Práticas, TDD) by Vinicius Quaiato on 02-11-2009

Tagged Under : , ,

Vamos lá galera, vamos continuar nossa série sobre TDD + C#.
Para conferir os outros posts da série:
Parte I – http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c/
Parte II – http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-ii/

Neste artigo abordaremos depósitos.

A primeira coisa que precisamos fazer para realizar nosso depósito é escrever um teste:

[TestMethod]
public void Deve_Realizar_Deposito()
{
    var conta = new ContaBancaria(10);
    conta.Depositar(10);
}

Este método ainda nem compila, afinal precisamos implementar o método Depositar na classe ContaBancaria.
E o resultado deve ser este (lembrando que fazemos o mínimo para o programa compilar e rodarmos o teste):

public void Depositar(decimal valorDoDeposito)
{
}

Agora vamos executar todos os nossos testes. É importante executarmos todos os testes para garantir que tudo funciona:

TDD Realizando testes

TDD Realizando testes


Percebam também a importância de um nome descritivo para os testes. Desta forma podemos saber exatamente o que está sendo garantido com aquele teste.

Agora conseguimos um verde, afinal nosso teste apenas garante um depósito. Vamos prosseguir criando um teste para verificar se o valor depositado foi somado ao saldo:

[TestMethod]
public void Deve_Realizar_Deposito_de_5_Em_Conta_Com_Saldo_10_E_Saldo_Deve_Ficar_15()
{
    var conta = new ContaBancaria(10);
    conta.Depositar(5);
 
    Assert.AreEqual(15, conta.SaldoAtual);
}

E ao rodarmos nossos testes temos:

TDD realizando tetses obtendo erro

TDD realizando tetses obtendo erro


O erro é bem claro: diz que estávamos esperando 15 e o resultado foi 10. Isso por que nosso método de depósito não possui nenhuma implementação.
Agora vamos alterar o código para que consigamos um verde nos testes:

public void Depositar(decimal valorDoDeposito)
{
    this.SaldoAtual = 15;
}

E executando nossos testes:

TDD obtendo um verde nos testes

TDD obtendo um verde nos testes

Agora que conseguimos um verde, devemos escrever mais testes para garantir que tudo funciona:

[TestMethod]
public void Deve_Realizar_Deposito_de_10_Em_Conta_Com_Saldo_10_E_Saldo_Deve_Ficar_20()
{
    var conta = new ContaBancaria(10);
    conta.Depositar(10);
 
    Assert.AreEqual(20, conta.SaldoAtual);
}

E rodando nossos testes temos:

TDD obtendo erro em segundo teste

TDD obtendo erro em segundo teste


Isso mostra que o código que escrevemos para o teste anterior passar deve ser alterado para que todos os testes passem. Desta forma obtemos o seguinte código no método Depositar:

public void Depositar(decimal valorDoDeposito)
{
    this.SaldoAtual += valorDoDeposito;
}

Agora precisamos executar todos nossos testes para ver se tudo está ok:

TDD todos testes verdes

TDD todos testes verdes

Bom galera, espero ter mostrado mais um pouco de TDD para vocês.

Na próxima parte do artigo abordaremos como testar a interação com um repositório de contas.

Abraços e até a próxima.

TDD – Test-driven Development + c# – Parte II

Filed Under (.NET, TDD) by Vinicius Quaiato on 23-10-2009

Tagged Under : , , ,

TDD – Test-driven Development – Parte I
TDD – Test-driven Development – Parte III

Após o que foi apresentado no primeiro post da série, faremos nesta segunda parte um exemplo prático de TDD.

Para efeito didático este será um exemplo bem simples e trivial, para que possamos focar nas práticas de TDD.

Antes de começarmos gostaria de mencionar o “mantra do TDD”:

Redgreenrefactoring

Ou seja, escreva um teste que falhe, na verdade um teste que nem compila (vermelho). Escreva um código que compile e faça o teste passar (verde), mesmo que seja um código ruim. Então, após o teste passar melhoramos o código, com a finalidade de deixá-lo mais claro, coeso e simples (refactoring).

Tendo isso em mente, vamos para o nosso caso de uso em C#:

Desenvolver uma aplicação bancária que controle saques, depósitos e transferências.

Como eu disse o caso de uso é simples, para que foquemos no TDD.

Vamos criar uma nova solution no Visual Studio. Aqui já começa a mudança de pensamento. Antes de criar o projeto da conta bancária, eu começo criando o projeto de testes da conta bancária. Eu gosto de pensar assim para ir me acostumando com a idéia do Test First.

TDD_criando_projeto_testes

TDD - criando projeto de testes

Agora que estamos com o projeto criado, vamos escrever nosso primeiro teste. Vocês vão perceber que a prática do TDD nos leva a pensar melhor em nossas classes. Vamos ver.

Bom, em nosso primeiro teste vamos nos assegurar de que quando uma conta seja criada ela obrigatóriamente necessite de um depósito inicial:

[TestMethod]
public void Deve_Criar_Conta_Com_Deposito_Inicial()
{
    ContaBancaria conta = new ContaBancaria(50.0m);
 
    Assert.AreEqual(50, conta.SaldoAtual);
}

Como podemos ver, este teste nem irá compilar, afinal, estamos criando o teste antes mesmo de criarmos a classe ContaBancaria.

public class ContaBancaria
{
    public decimal SaldoAtual { get; set; }
    public ContaBancaria(decimal depositoInicial) { }
}

Assi podemos executar nosso teste. Eu gosto de utilizar dois atalhos CTRL + R + T (executa o teste corrente em modo debug) ou CTRL + R + A (executa todos os testes da solution em modo debug).
Teremos o resultado como abaixo:

TDD - executando primeiro teste

TDD - executando primeiro teste

Este teste falhou. Ótimo! Obtemos um red e sabemos que estamos no caminho certo. Aconteceu que estávamos esperando um saldo de 50 e o saldo obtido foi 0.
Agora devemos voltar ao código e fazer o teste passar:

public class ContaBancaria
{
    public decimal SaldoAtual { get; set; }
    public ContaBancaria(decimal depositoInicial)
    {
        this.SaldoAtual += depositoInicial;
    }
}

Neste caso nossa mudança é bem pequena. Agora vamos executar o mesmo teste e ver o que acontece:

TDD - executando primeiro teste verde

TDD - executando primeiro teste verde

Pronto! Obtivemos um verde, e isso quer dizer que podemos prosseguir, escrevendo os próximos testes. Antes disso acontecer, devemos lembrar do próximo passo: refactoring!
Vamos voltar ao nosso código e entender o que pode ser refatorado.
Me parece que a propriedade SaldoAtual não deveria ter um setter público, desta forma vamos torná-lo privado:

public class ContaBancaria
{
    public decimal SaldoAtual { get; private set; }
    public ContaBancaria(decimal depositoInicial)
    {
        this.SaldoAtual += depositoInicial;
    }
}

Agora devemos novamente executar nossos testes, para termos certeza de que não acabamos estragando nada.

Agora precisamos garantir que o depósito inicial seja um depósito válido. Ou seja, o que acontece com um depósito inicial igual a 0? E se for menor que 0?
De acordo com a regra de negócio que eu inventei, uma conta sempre deve ser criada com um depósito inicial. Quando quisermos carregar uma conta específica, utilizaremos outra notina e não o construtor público.
Assim, vamos criar um deste que garanta que o depósito inicial seja válido.

Vamos usar um atributo(attribute) do framework de testes do visual studio que nos permite testar se um determinado teste lança uma exceção – ExpectedException:

[TestMethod]
[ExpectedException(typeof(DepositoInicialInvalidoException))]
public void Deve_Lancar_Excecao_Deposito_Inicial_Invalido()
{
    ContaBancaria conta = new ContaBancaria(0);
}

Para que este teste compile, vamos criar uma Exception:

public class DepositoInicialInvalidoException : Exception
{
    public DepositoInicialInvalidoException()
        : base("Depósito inicial deve ser um valor maior que 0(Zero)!") { }
}

Agora vamos rodar nosso test. Pumba! Obtivemos um red. Afinal, não estamos validando o depósito inicial. Vamos fazer o código passar:

public ContaBancaria(decimal depositoInicial)
{
    if (depositoInicial &lt;= 0)
        throw new DepositoInicialInvalidoException();
 
    this.SaldoAtual += depositoInicial;
}

Agora já podemos executar nossos testes (sim, devemos executar todos os testes, para ter certeza que nada quebrou no meio do caminho). Pronto, temos um verde. Vamos para o refactoring. A validação dentro do construtor não ficou muito elegante. Afinal, no futuro podemos ter outros tipos de validações, desta forma vamos refatorar:

TDD - refatorando

TDD - refatorando

Assim o visual studio criará para nós um método, e ficaremos com a seguinte estrutura:

public ContaBancaria(decimal depositoInicial)
{
    Validar(depositoInicial);
 
    this.SaldoAtual += depositoInicial;
}
private void Validar(decimal depositoInicial)
{
    if (depositoInicial &lt;= 0)
        throw new DepositoInicialInvalidoException();
}

É importante que a cada refatoring, cada mudança de código, executemos novamente os testes. Mesmo que achemos que a mudança é pouca e pequena, isso nos fará ter o hábito de sempre executar os testes, e no futuro faremos isso para mudanças mais drásticas e severas.

Bom pessoal, nesta segunda parte espero ter mostrado o início do TDD utilizando C# + Visual Studio.

Na próxima parte deste artigo criaremos os testes para depósitos e saques.

Abraços,
Vinicius Quaiato.

TDD – Test-driven Development – Parte I

Filed Under (TDD) by Vinicius Quaiato on 20-10-2009

Tagged Under :

Bom, estive pensando sobre como começar este novo espaço e decidi que nada melhor do que a prática que mais vem me fascinando nos últimos tempos TDD – Test-Driven Development.

TDD – Test-driven Development – Parte II

http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-ii/


TDD – Test-driven Development – Parte III

http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-iii/


TDD – Test-driven Development – Parte IV
http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-iv/

TDD não é algo novo, e nem específico para uma tecnologia. Podemos dizer que o mesmo surgiu, ou ficou conhecido, em meados de 2002, com a publicação do livro de Kent Beck, chamado Test-driven Development by Example.

Basicamente o TDD significa:

  1. Escreva um teste, antes mesmo de escrever o código que este teste consome;
  2. Faça o teste funcionar, escrevendo o código do qual o teste depende, mesmo que seja um código ruim;
  3. Refatore, eliminando duplicações de código, tanto nos testes quanto nas implementações.

Basicamente isto é TDD, simples, não?!

Você deve estar se perguntando:

Que tipo de loucura é essa de escrever testes, ainda mais antes do código?

Bem, existe uma série de fatores que podem levá-lo a querer escrever testes de unidade antes de escrever o código, vou citar aqui alguns que me fizeram repensar a forma de desenvolver:

  1. Testes asseguram que o que existe funciona, o que existia continua funcionando, e o que virá a existir funcionará;
  2. Testes de unidade nos dão confiança no código;
  3. Escrever os testes antes do código nos faz pensar em como realmente escrever aquele código do ponto de vista de quem irá utilizá-lo (ainda que sejamos nós mesmos);
  4. “Testes são documentação executável” (Giovanni Bassi aqui);
  5. Teste escrito antes do código é especificação (Giovanni Bassi aqui);
  6. TDD foca em software que SEMPRE funciona;

TDD nos leva a buscar e implementar boas práticas de programação. Para se realizar um bom teste de unidade, e antes do código estar escrito, é necessário que nossas classes sejam realmente coesas, que elas tenham um baixo acoplamento, que seus métodos sejam também coesos, com apenas uma responsabilidade. Nos faz pensar seriamente em Inversão de Controle e Injeção de Dependência.

Estes itens já nos levam a considerar com muito carinho o uso de TDD.

Com TDD, sem dúvida teremos software que funciona, software fácil de testar, software fácil de alterar, e o melhor de tudo, software feito por profissionais!

Sim! Testar e garantir que funciona é obrigação de todo desenvolvedor de software.
Imagine você comprar um carro e só quando for dirigir descobrir que a primeira marcha anda de ré!? Ou então comprar uma geladeira e quando colocar água para gelar descobrir que ela na verdade ferve a água?!

Somos pagos, e muito bem pagos, para entregar software de qualidade, e quem deve garantir isso somos nós mesmos. Devemos ser profissionais. Mais do que isso, devemos ser bons profissionais!

Para finalizar esta primeira parte, encerro com uma frase do UncleBob:

“Desenvolvedor que não testa é como um médico que não lava as mãos antes de fazer uma cirurgia.”

No próximo post mostrarei como fazermos algo bem simples usando TDD + C# + Visual Studio.

Abraços galera.