quinta-feira, 2 de setembro de 2010

Utilizando TestDecorator do DUnit parte 1/2

Esses dias precisei utilizar uma classe chamada TTestDecorator que está disponível no DUnit e possui esse nome por implementar o design pattern Decorator (GOF). Podemos utilizar este recurso para mudar um determinado comportamento de uma classe de testes e ou método de teste.

Antes de prosseguirmos é interessante ressaltar que o padrão decorator será aplicado a classe de testes e não a classe a ser testada.

Principais utilizações da classe TTestDecorator:

Mudar o comportamento principal da classe de testes.
Executar uma suite de testes com configurações diferentes, muito util para testes de componentes.
Evitar a instanciação múltipla desnecessária de componentes de conexão com bancos de dados para agilizar os testes.
Executar uma suite de testes múltiplas vezes.

Vamos entender primeiro o funcionamento interno de uma suite de testes observando a imagem abaixo:

Comportamento padrão DUnit


Para quem nunca reparou quando você cria teste unitário para uma classe o tipo da classe do teste unitário por padrão herda de TTestCase e a declaração para registro desta classe de teste fica desta forma:

initialization
RegisterTest(TestTCalculator.Suite);


Note que o TestTCalculator é passado para o RegisterTest sem ser instânciado através de um construtor, Suite é uma class function que cria uma instância de TTestSuite e não de sua classe de testes em especifico. Esta classe TTestSuite funciona da forma mencionada na imagem acima.
Na imagem abaixo podemos ver o funcionamento utilizando Decorator.

Comportamento DUnit Decorator



Para utilizar o decorator precisamos primeiro declarar nossa classe utilizada para decorar nossa classe e/ou método, que deverá herdar de TTestDecorator localizado na unit TestExtensions, nesta classe devemos sobre-escrever o método RunTest e implementar nossas modificações nele. Feito isso precisamos apenas mudar a nossa declaração de registro de nossa classe de testes




initialization
RegisterTest(TMeuDecorator.Create( TestTCalculator.Suite ));


Como mostrei na imagem acima sua personalização deverá ser realizada dentro do método RunTest ficando algo assim:

//Meu Decorador
TMeuDecorator = class (TTestDecorator)
protected
procedure RunTest(ATestResult: TTestResult); override;
public
//Utilizado para retornar o nome a ser exibido na tela de tests.
function  GetName: string; override;
end;

function TMeuDecorator.GetName: string;
begin
Result := Format('Meu decorador de %s',['Testes']);
end;

procedure TMeuDecorator.RunTest(ATestResult: TTestResult);
begin
//Executa seu código personalizado antes de executar todos os testes
ShowMessage('Código disparado antes!');
try
//Este RunTest executa todos os testes de nossa classe de métodos,
//podemos executa-los quantas vezes quisermos de acordo com o necessário.
inherited RunTest( ATestResult ) ;
finally
//Executa seu código personalizado depois de executar todos os testes
ShowMessage('Código disparado depois!');
end;
end;


No próximo artigo mostrarei como compartilhar dados entre o nosso decorador de testes e nosso teste.

Dúvidas postem nos comentários.

Abraço,
Diego Garcia

4 comentários: