A ferramenta de teste de carga do Team System é o Test Load Agent, certo?

Essa é uma dúvida muito comum. Um amigo MVP me fez essa pergunta há algum tempo. Assim, achei que era uma excelente oportunidade para blogar e tentar registrar a resposta.

 

A ferramenta de teste de carga do VSTS é o Visual Studio Test Edition.

 

Ponto. Simples assim. 🙂

VSTS Test Edition

Isso quer dizer que, para estressar aplicações Web (ASP.NET, PHP, Java, Ruby etc.), Web Services (ASMX, WCF, JEE etc.) e bancos de dados (SQL Server e quaisquer outros suportados pelo ADO.NET) você deve usar o Visual Studio Team System Test Edition (a ferramenta de testes do Team System). Com ela você pode:

  • Criar as definições (scripts) do teste de carga;
  • Executar os testes (contra um ou mais servidores ao mesmo tempo);
  • Consolidar os dados (recebendo os indicadores de performance de todos os servidores envolvidos);
  • Analisar os dados (através de gráficos e tabelas no próprio ou através de exportação para Excel e relatórios em SQL Server Reporting Services);
  • Notificar a equipe de desenvolvimento em caso de problemas de desempenho (através da criação de itens de trabalho do tipo  Bug).

scrshot2

Agora que esclarecemos que o VSTS Test Edition é a ferramenta que devo usar para fazer os testes de carga, vem a pergunta: para quê serve então o Test Load Agent?

Use o VSTS Test Load Agent para aumentar a quantidade de usuários virtuais dos seus testes

O VSTS Test Edition pode gerar tantos usuários virtuais quantos você quiser. O único limite será a capacidade do seu hardware. É difícil estimar quanta carga um determinado computador é capaz de gerar, porém eu arriscaria dizer que uma boa estação de desenvolvimento deve conseguir algo entre 500 e 1000 usuários virtuais (esse número pode variar muito dependendo do tipo de teste que você faz).

A fim de criar um estresse que simule as condições reais de uso de sua aplicação, pode ser que você precise simular mais do que 500 ou mil usuários virtuais – especialmente se você pretende colocar essa aplicação na internet. Nesse caso, você precisaria de mais computadores, trabalhando lado a lado com o seu, cada um deles executando parte dos usuários virtuais.

É aí que entra o Test Load Agent.

Com o Test Load Agent, você pode promover máquinas em sua rede a agentes de carga – dividindo a responsabilidade do trabalho com o computador onde está o Test Edition.

Assim, imaginemos o seguinte cenário:

  1. Preciso estressar uma aplicação web;
  2. Essa aplicação vai estar na internet;
  3. Espero uma carga de cinco mil usuários simultâneos;
  4. Nos primeiros testes executados pôde-se perceber que um computador consegue gerar no máximo mil usuários virtuais.

Para poder gerar a carga de cinco mil usuários você utiliza o Test Edition em conjunto com um ou mais computadores rodando o Test Load Agent para criar um conjunto de máquinas chamado de Test Rig. Test Rigs são o conjunto de um controlador e um ou mais agentes de teste de carga.

Uma outra distinção importante: testes de cargas executados a partir do Visual Studio estão limitados a um único core da minha máquina; o Load Agent, por outro lado, utiliza todos os cores. Como tipicamente o principal limitador na quantidade de usuários virtuais é a CPU, o Test Load Agente conseguiria gerar o dobro de usuário numa máquina dual-core, quando comparado com o Test Edition.

Por falar em testes de carga – WCF Load Test

No último post mencionei uma nova ferramenta dos VSTS Rangers para a criação de testes de carga para o SQL Server. Agora vale a menção de um projeto mais antigo dos mesmos Rangers, só que para o teste de carga de serviços WCF.

O WCF Load Test é uma ferramenta que converte um trace WCF em um teste unitário que pode ser usado como parte de um teste de carga. Combinado com os testes de carga Web e os para o SQL Server, você consegue criar as condições necessárias para testar sua aplicação o mais próximo possível da realidade, confirmando que ela efetivamente suporta a quantidade de usuários que você espera.

 

Technorati Tags: ,,

Teste de carga de servidores SQL Server

O time VSTS Rangers (uma equipe dentro da Microsoft responsável por eliminar “entraves” na adoção do VSTS pelos clientes) acaba de lançar mais um projeto no CodePlex: é o SQL Load Test.

A proposta é bem simples: a ferramenta de teste de carga que faz parte do Visual Studio Team System é realmente incrível, porém oferece suporte nativo apenas a aplicações Web. Como fazer um teste de carga para, por exemplo, um aplicativo cliente/servidor desenvolvido em WPF ou Windows Forms? Tipicamente o que importa num teste de carga num cenário como esse é avaliar a performance do servidor de banco de dados. Para tanto, basta iniciar a gravação de um arquivo de trace do SQL Server e utilizar normalmente a aplicação, registrando sua interação com o servidor;

A partir desse arquivo de trace do SQL Server, é possível criar um teste unitário que contém as chamadas ADO.NET correspondentes ao conteúdo do arquivo de trace. Com isso, é possível criar um teste de carga que execute esse teste unitário para efetivamente estressar o servidor.

 

Technorati Tags: ,,

Cobertura de Código – Só para testes unitários?

Antes de discutir cobertura de código, uma rápida recapitulação:

  • Cobertura de código: Uma métrica que indica a efetividade dos testes feitos em uma aplicação. Expressa em termos de porcentagem do código-fonte da aplicação, mostra extaamente o quanto da aplicação foi testada durante uma dada bateria de testes;
  • Testes Unitários: Pequenas rotinas (tipicamente escritas na mesma linguagem de programação do sistema que será testado) que descrevem regras de negócios e outros comportamentos conhecidos e esperados do sistema. Os testes unitários invocam rotinas e outras pequenas porções de código do sistema-alvo, suprindo parâmetros com valores pré-definidos e analisando o comportamento resultante, que deve estar de acordo com a regra de negócio ou comportamento esperado em questão.

Para que os testes unitários sejam efetivos, eles devem cobrir o maior número possível de "caminhos" no código da aplicação. A cobertura de código visa a responder justamente o quanto desses caminhos foi realmente testado. Veja um exemplo (totalmente fictício, hein?!) que ilustra tudo isso:

 

Regra de Negócio:

Para o cálculo do salário líquido de um funcionário, dados:

  1. O valor do salário bruto;
  2. Um "flag" indicando a adesão ao plano de saúde;
  3. Um "flag" indicando a adesão ao vale-refeição;

Deve ser efetuado o seguinte cálculo:

  1. Descontar o imposto de renda de acordo com com as seguintes faixas:
    1. R$0 – R$1000: Isento;
    2. R$1001 – R$2000: 5%;
    3. R$2001 – R$3000: 15%;
    4. R$3001 em diante: 25.
  2. Descontar 10% de INSS;
  3. 10% do salário bruto, caso tenha aderido ao plano de saúde;
  4. 5% do salário bruto, caso tenha aderido ao vale-refeição.

Código-fonte da aplicação:

   1:  public class Empregado
2: {
3: public static double CalcularSalario(double salarioBruto, bool temPlanoSaude, bool temValeRefeicao)
4: {
5: var salarioLiquido = salarioBruto;
6:  
7: // Cálculo do imposto de renda
8:  
9: if (salarioBruto > 1000 && salarioLiquido <= 2000)
10: {
11: salarioLiquido -= (salarioBruto * .05);
12: }
13: else if (salarioBruto > 2000 && salarioBruto <= 3000)
14: {
15: salarioLiquido -= (salarioBruto * .15);
16: }
17: else if (salarioBruto > 3000)
18: {
19: salarioLiquido -= (salarioBruto * .25);
20: }
21:  
22: // Cálculo do plano de saúde
23:  
24: if (temPlanoSaude)
25: {
26: salarioLiquido -= (salarioBruto * .10);
27: }
28:  
29: // Cálculo do vale-refeição
30:  
31: if (temValeRefeicao)
32: {
33: salarioLiquido -= (salarioBruto * .05);
34: }
35:  
36: return salarioLiquido;
37: }
38: }

Teste Unitário:

public void CalcularSalarioTest()
{
    // "Valores conhecidos". São arbitrários; posso usar qualquer valor

    double salarioBruto = 1500; 
    bool temPlanoSaude = false; 
    bool temValeRefeicao = true; 

    // "Valor esperado". Deve estar de acordo com a regra de negócio e com
    // os valores dados acima

    double expected = 1350; 

    // "Valor real". É o valor que será retornado pela minha rotina de cálculo;
    // se tudo der certo, deve ser igual ao "valor esperado"

    double actual;

    // Executa a rotina passando os valores acima como parâmetros

    actual = Empregado.CalcularSalario(salarioBruto, temPlanoSaude, temValeRefeicao);

    // Confere se os resultados ("valor esperado", "valor real") são iguais; se forem,
    // o teste é considerado bem-sucedido

    Assert.AreEqual(expected, actual);
} 

Compare a regra de negócio, o código-fonte da aplicação e o teste unitário:

  • A rotina de cálculo está atendendo a todas as premissas da regra de negócio? No exemplo acima, sim.
  • O teste unitário está testando todas as variações possíveis da rotina de cálculo? No exemplo acima, não está:
    • Não foram feitos testes para todas as faixas de salários (para garantir que o IRPF está sendo calculado corretamente);
    • Não foram testadas outras variações para "plano de saúde" e "vale-refeição".

É justamente nesse momento que entra a cobertura de código. Ela nos ajuda a identificar quais pontos da rotina não foram testados:

image

Viu? A cobertura de código é quase indispensável quando estamos trabalhando com testes unitários. Ela nos dá a medida da eficácia do teste que escrevemos e acabamos de executar. Daí vem uma dúvida bastante comum quando discutimos cobertura de código e testes unitários no Team System. Tipicamente esses dois recursos são mostrados em conjunto – e por isso há quem acredite que são parte da mesma funcionalidade, e que portanto cobertura de código significa "porcentagem do código testado pelos testes unitários", quando na verdade significa "porcentagem do código testado"!

Cobertura de Código e outros testes

Veja como a cobertura de código se comporta em conjunto com alguns dos outros testes disponíveis no Team System. Para isso, crie uma solução com dois projetos: uma Web Application e um Test Project. Não se esqueça de ativar a cobertura de código para seu projeto Web Application (Test | Edit Test Run Configurations | Local Test Run):

image

Testes Manuais

Faça uma experiência: adicione um teste manual e execute-o. Enquanto ele estiver em execução, abra o seu web site (que deve ter sido carregado automaticamente pelo Visual Studio). Navegue à vontade pelas páginas de teste que você deve ter criado (espero que sim!). Depois, no Visual Studio, marque o teste manual como concluído:

image

Ao clicar numa das opções acima (e em seguida em Apply) você terá concluído o teste. Inspecione agora a janela de resultado da cobertura de código (Test | Windows | Code Coverage Results). Veja como a cobertura de código foi corretamente preenchida de acordo com as páginas que você navegou:

image

Testes Web e Testes de Carga

Testes Web (Web Test) e Testes de Carga (Load Test) também alimentam a cobertura de código. Faça seus testes e confira!

Outros tipos de testes

Veja como alguns dos outros tipos de teste disponíveis no Team System se comportam quanto à cobertura de código:

  • Testes Unitários de Banco de Dados: Esses testes nada mais são que o teste unitário convencional com algumas facilidades para a execução de T-SQL. Na verdade, por baixo dos panos eles são .NET puro. Assim, se por acaso invocarem trechos da sua aplicação então a cobertura de código refletirá tal fato;
  • Testes Ordenados: Como estes são nada mais que agrupadores de outros testes, estarão sujeitos às regras aplicáveis a cada um dos "sub-testes" que os compõem;
  • Testes Genéricos: Esses testes existem para que possamos testar componentes não- .NET ou que sejam externos à nossa aplicação. Assim, não faz sentido esperar que esses testes "sensibilizem" a cobertura de código.

Conclusão

A cobertura de código é um recurso muito importante da Test Edition do Visual Studio Team System, e está disponível para a maioria dos tipos de testes – não só para testes unitários. Use e abuse da cobertura de código!