Um grupo dentro da Microsoft tem trabalhado na construção de um “novo” tipo de teste para o Visual Studio, que tem a finalidade de criar testes unitários para serviços WCF baseando-se nas requisições que chegam para ele ou através de uma análise de um arquivo de tracing, que também é gerado pelo próprio WCF.
Esses testes unitários servirão apenas como uma forma de automatizar/criar as chamadas que serão realizadas para as operações expostas pelo serviço, mas a grande utilidade será a possibilidade de criar um teste de carga para serviços WCF, incluindo esses testes unitários como uma forma de customizar e automatizar como e quantas requisições serão disparadas contra o mesmo e, consequentemente, conseguirmos mensurar o consumo de alguns recursos como memória e processamento que estarão sendo utilizados pelo mesmo. Note que o nome do projeto é WCF Load Test, que está em sua versão 3.0.
Como exemplo, vamos criar um contrato que recebe uma string como parâmetro e retorna um array, também do tipo string, representando os itens que foram encontrados baseando-se naquele parâmetro. Abaixo temos o contrato para ilustrar:
[ServiceContract]
public interface IBuscador
{
[OperationContract]
string[] Buscar(string parametro);
}
A implementação para este contrato é extremamente simples, onde tudo o que temos dentro do serviço é a leitura de todo o conteúdo de um arquivo texto que contém um conjunto de tecnologias Microsoft, qual faremos a busca para ver se encontramos o item dentro deste arquivo. A classe que representa o serviço está abaixo:
public class ServicoDeBusca : IBuscador
{
public string[] Buscar(string parametro)
{
string[] linhas = File.ReadAllLines(@”C:TempTecnologias.txt”);
Thread.Sleep(200); //Simula um processamento
return
(
from s in linhas
where s.IndexOf(parametro, StringComparison.CurrentCultureIgnoreCase) > -1
select s
).ToArray();
}
}
O serviço está sendo exposto através do binding BasicHttpBinding, mas a configuração do mesmo será omitida aqui, assim como a configuração do tracing de mensagens, que precisa estar habilitado para submetermos para a criação do teste. Se você quiser saber mais sobre o tracing do WCF, você pode consultar este artigo ou este vídeo.
Depois do projeto WCF Load Test instalado, você já será capaz de adicionar um teste do tipo WCF Test em seu projeto de testes. A imagem abaixo ilustra esse novo item que é adicionado após a instalação do arquivo MSI que você precisa baixar.
Quando clicar no botão OK, um wizard será inicializado, onde você poderá customizar o teste do serviço. O primeiro passo determina a fonte de onde quer extrair as informações para gerar os testes, onde a primeira opção é selecionar a aplicação cliente que consome o serviço, ou utilizar um arquivo de log previamente criado. Além disso, é necessário selecionar uma das três opções que estão logo abaixo: Client-side, Server-side e Fiddler text. As duas primeiras se referem aos arquivos de tracing gerados pelo WCF, e como estamos gerando o tracing através do serviço, temos que selecionar a opção Server-side. Além disso, ainda há a possibilidade de utilizar um arquivo de log do Fiddler, caso o serviço esteja sendo exposto através do protocolo HTTP. A imagem abaixo ilustra este passo:
Observação: Para poder gerar uma requisição para o serviço, podemos utilizar o utilitário WCF Test Client, que nos permite consumir um serviço WCF sem a necessidade de ter que criar uma aplicação para efetuar a requisição.
O próximo passo consiste em selecionar quais operações (SOAP Actions) serão envolvidas no teste. Lembrando que o serviço pode possuir várias delas, e você tem a possibilidade de envolver somente aquelas que julgar necessário para compor os testes. Podemos visualizar este passo através da imagem abaixo:
Para finalizar, precisamos informar no último passo do wizard onde estão os contratos (de serviço, de dados ou faults) que serão utilizados pelo cliente. A ideia é selecionar o assembly onde estão este tipos. E se dentro deste assembly você tiver somente os contratos ou tiver o proxy efetivamente criado, a geração do código de testes é ligeiramente diferente.
Quando o wizard é finalizado, uma classe é gerada encapsulando toda a comunicação com esse serviço, respeitando os métodos selecionados. Para cada operação do serviço, um método de teste é criado e decorado com o atributo TestMethodAttribute. Além disso, um método de inicialização (TestInitializeAttribute) é criado em uma classe parcial, que é utilizado para construir a instância o proxy. Esse método exige uma customização, que é o binding a ser utilizado e o endereço até o serviço.
Abaixo temos a classe gerada para efetuar os testes, qual o Visual Studio (MSTest) utiliza para rodar como sendo um teste unitário. Note que como temos o método Buscar, ele é colocado dentro desta classe, abastecendo o parâmetro com o valor que também foi extraído do arquivo de tracing. Depois disso, envolvemos a chamada para a operação no timer fornecido pela classe TestContext, que será utilizado mais tarde por um teste de carga.
[TestClass]
public partial class ServicoDeBuscaTests
{
private Servicos.IBuscador buscadorClient;
public TestContext TestContext { get; set; }
[TestMethod]
public void ServicoDeBusca()
{
this.Buscar();
}
private string[] Buscar()
{
string parametro = “Windows”;
this.CustomiseBuscar(ref parametro);
this.TestContext.BeginTimer(“ServicoDeBusca_Buscar”);
try
{
return buscadorClient.Buscar(parametro);
}
finally
{
this.TestContext.EndTimer(“ServicoDeBusca_Buscar”);
}
}
}
Como já mencionei acima, uma configuração necessária para o teste funcionar corretamente, é a necessidade de definir o binding que será utilizado e o endereço até o serviço. Para isso, você pode utilizar o construtor da classe ChannelFactory<TChannel>, que está localizada dentro da classe parcial que foi criada automaticamente através dos passos acima. Você poderá analisar essa configuração no projeto que está anexado no final deste artigo.
Finalmente você pode rodar o projeto de teste através do Visual Studio para se certificar de que a chamada seja realizada, e com isso visualizar o andamento através da janela que sumariza os testes, indicando o status da execução e se sucedeu ou não:
Conclusão: Neste artigo exploramos uma ferramenta que podemos integrá-la no Visual Studio para podermos gerar testes unitários se baseando em serviços WCF. O grande intuito dele é ser utilizado dentro de um outro teste, como é o caso de um teste de carga, que nos permite adicionar um teste previamente criado para compor a carga que será disparada contra o serviço, assunto qual será abordado em um futuro artigo.