17 de jan de 2014

Primeiro passo do refactoring - Testes


Sempre que for fazer o refactoring, o primeiro passo sempre é o mesmo. É necessário construir um conjunto de testes sólidos para  a seção de código que será trabalhada. Os teste são fundamentais, pois mesmo que sigamos o refactoring de forma estruturada, ainda há o risco de inserir bugs no programa, afinal somos humanos e podemo cometer equívocos. Por isso precisamos de testes sólidos.

Vamos a implementação de testes automatizados. O refactoring é uma ferramenta do TDD, e é por isso que estamos tratando desse assunto primeiro. Quando formos discutir TDD, vocês perceberão que já sabem tudo de TDD por que aprenderam TDD estudando refactoring.

Em qualquer aplicação os testes são simples, rápidos de implementar e executar. É o conjunto deles que garantirá a efetividade da automatização de testes. Lembre-se para testar algo é preciso saber o que será testado, é preciso possuir um resultado ou valor esperado. O teste apenas vai executar algo, e consultar se o resultado esperado ocorreu ou não. O segredo do teste está a mensagem de retorno do resultado. Se o teste ocorreu conforme esperado, a mensagem pode ser um simples Ok. Mas se o teste deu errado, o próprio teste deve retornar dizendo o que deu errado. Qual o valor esperado que não foi encontrado, qual valor foi retornado no lugar do valor esperado. São essas informações que irão direcionar a solução para o problema detectado no teste. Por isso dizemos que o testes devem ser auto verificáveis. Se não fizermos dessa forma, perderemos tempo verificando números, consultando registros para saber onde o teste falhou.

O refactoring se apoia totalmente nos testes. Nós vamos nos apoiar nos teste para nos dizer quando introduzimos um bug no programa. Por isso é essencial ter bons testes, testes abrangentes. Vale a pena gastar um tempo na implementação dos testes, pois eles lhe darão a segurança necessária para realizar as mudanças no programa.

Vamos aos testes logo né!
Para testar, sugiro a criação de testes que simule a locação de cada tipo de filme e com quantidade de dias de locação variados. Como o retorno do método Relatorio é uma string,o teste se concentrará na validação da string gerada pelo método em comparação com a string que esperamos que seja gerada. Podemos executar e simular todas as situações de testes e capturar as string geradas, em seguida basta adiciona-las ao teste. Vale ressaltar que o nosso exemplo nesse momento está correto e sem bugs, gerado os dados da forma que o usuário deseja, portanto faz todo o sentido utilizar esses dados na validação dos testes.

Vou montar os testes, mas vou deixar uma amostra de alguns necessários para que possam basear.
Continuo no próximo post.
Até mais.

Segue abaixo alguns testes (Esses são somente alguns testes, serão necessários mais testes, para ficar sólido e seguro):



unit uTesteLocacao;

interface

uses TestFramework, uCliente, uFilme, uAluguel;

type
  TTestLocacao = class(TTestCase)
  published
    procedure LocacaoFilmeInfantil1Dia;
    procedure LocacaoFilmeInfantil4Dias;
    procedure LocacaoFilmeLancamento1Dia;
    procedure LocacaoFilmeLancamento2Dias;
  end;

implementation

{ TTestLocacao }

procedure TTestLocacao.LocacaoFilmeInfantil1Dia;
var
  Filme: TFilme;
  Cliente: TCliente;
  Locacao: TLocacao;
  Resultado: String;
  Esperado: String;
begin
  Filme := TFilme.Create('Tarzan', TFilme.Infantil);
  Locacao := TLocacao.Create(Filme,1);
  Cliente := TCliente.Create('Alice');
  Cliente.AdicionaLocacao(Locacao);
  Resultado := Cliente.Relatorio();
  Esperado := 'Registro de locação de Alice'+#13+
              '|Tarzan|1,5' + #13 +
              'O total é: 1,5'+#13+
              'Você ganhou: 1 pontos';
  Check(Resultado = Esperado, 'Falha no teste: Esperado: '+ Esperado + ' Realizado:' + Resultado);
end;


procedure TTestLocacao.LocacaoFilmeInfantil4Dias;
var
  Filme: TFilme;
  Cliente: TCliente;
  Locacao: TLocacao;
  Resultado: String;
  Esperado: String;
begin
  Filme := TFilme.Create('Tarzan', TFilme.Infantil);
  Locacao := TLocacao.Create(Filme,4);
  Cliente := TCliente.Create('Alice');
  Cliente.AdicionaLocacao(Locacao);
  Resultado := Cliente.Relatorio();
  Esperado := 'Registro de locação de Alice'+#13+
              '|Tarzan|3' + #13 +
              'O total é: 3'+#13+
              'Você ganhou: 1 pontos';
  Check(Resultado = Esperado, 'Falha no teste: Esperado: '+ Esperado + ' Realizado:' + Resultado);
end;


procedure TTestLocacao.LocacaoFilmeLancamento1Dia;
var
  Filme: TFilme;
  Cliente: TCliente;
  Locacao: TLocacao;
  Resultado: String;
  Esperado: String;
begin
  Filme := TFilme.Create('O Hobbit', TFilme.Lancamento);
  Locacao := TLocacao.Create(Filme,1);
  Cliente := TCliente.Create('Alice');
  Cliente.AdicionaLocacao(Locacao);
  Resultado := Cliente.Relatorio();
  Esperado := 'Registro de locação de Alice'+#13+
              '|O Hobbit|3' + #13 +
              'O total é: 3'+#13+
              'Você ganhou: 1 pontos';
  Check(Resultado = Esperado, 'Falha no teste: Esperado: '+ Esperado + ' Realizado:' + Resultado);
end;

procedure TTestLocacao.LocacaoFilmeLancamento2Dias;
var
  Filme: TFilme;
  Cliente: TCliente;
  Locacao: TLocacao;
  Resultado: String;
  Esperado: String;
begin
  Filme := TFilme.Create('O Hobbit', TFilme.Lancamento);
  Locacao := TLocacao.Create(Filme,2);
  Cliente := TCliente.Create('Alice');
  Cliente.AdicionaLocacao(Locacao);
  Resultado := Cliente.Relatorio();
  Esperado := 'Registro de locação de Alice'+#13+
              '|O Hobbit|6' + #13 +
              'O total é: 6'+#13+
              'Você ganhou: 2 pontos';
  Check(Resultado = Esperado, 'Falha no teste: Esperado: '+ Esperado + ' Realizado:' + Resultado);
end;

initialization
  TestFramework.RegisterTest(TTestLocacao.Suite);

end.




Nenhum comentário:

Postar um comentário