Este artigo foi traduzido por máquina.

Execução de teste

Testando aplicativos do Silverlight usando mensagens

James McCaffrey

Baixe o código de exemplo

Sou um grande fã do Silverlight e na coluna deste mês descrevo uma técnica que você pode usar para testar aplicativos do Silverlight.

Silverlight é uma estrutura de aplicativo Web completa que foi lançada inicialmente em 2007. A versão atual, o Silverlight 3, foi lançada em julho de 2009. Visual Studio 2010 oferece suporte Avançado para o Silverlight, em especial, um designer visual totalmente integrado que faz o Silverlight criando interfaces de usuário um snapshot.

A melhor maneira de ver em que eu estou cabeças neste artigo é dar uma olhada em aplicativos próprios. Figura 1 mostra um aplicativo simples mas representativo do Silverlight chamado MicroCalc. Você pode ver que MicroCalc é hospedado dentro do Internet Explorer, embora os aplicativos do Silverlight também podem ser hospedados por outros navegadores como Firefox, opera e Safari.

Figure 1 MicroCalc Silverlight App
Figura 1 aplicativo MicroCalc Silverlight

Figura 2 mostra um conjunto de teste leve, que também é um aplicativo do Silverlight.


Figura 2 de estrutura de teste para MicroCalc

Neste exemplo, o primeiro caso de teste foi selecionado. Quando o controle de botão chamado Run Test selecionado foi clicado, o utilitário de teste do Silverlight enviou uma mensagem que contém os dados de entrada selecionado caso de teste para o aplicativo do Silverlight MicroCalc em teste. Esses dados em caso de teste consistem em instruções para simular um usuário digitando 2.5 e 3.0 para as áreas de entrada do aplicativo, Selecionar operação de multiplicação e, em seguida, clicando no botão de computação.

O aplicativo aceita os dados do caso de teste e exercidos própria usando código de teste que é instrumentado no aplicativo programaticamente. Após um pequeno intervalo, o utilitário de teste envia uma mensagem segunda para o aplicativo em teste, solicitando que o aplicativo enviar uma mensagem que contém informações sobre o estado do aplicativo — ou seja, o valor no campo resultados. O utilitário de teste recebido a mensagem resultante do aplicativo e determinado se o valor real no aplicativo, 7.5000, correspondeu ao valor esperado nos dados do caso de teste e exibido um resultado de caso de teste passar na área de comentários de equipamento.

Este artigo pressupõe que você possui familiaridade básica com o idioma translation from VPE for Csharp, mas não assume que você tem qualquer experiência com o Silverlight. As seções desta coluna a seguir, primeiro descrevo o aplicativo do Silverlight em teste. Eu orientá os detalhes de criar a estrutura de teste baseados no Silverlight leve mostrada no 1 Figura e, em seguida, explicarei como instrumentar o aplicativo. Concluir descrevendo métodos alternativos de testes.

O aplicativo em teste

Let’s dar uma olhada no código do aplicativo do Silverlight MicroCalc que é o destino de meu exemplo de automação de teste. Criei MicroCalc usando o Visual Studio 2010 beta 2. 3 Do Silverlight é totalmente integrado ao Visual Studio 2010, mas o código que apresento aqui também funciona com o Visual Studio 2008 com o SDK do Silverlight 3 instalado separadamente.

Depois de iniciar o Visual Studio, cliquei no File | New | Project. Observe que um aplicativo do Silverlight é um componente .NET que pode ser hospedado em um aplicativo da Web, em vez de um aplicativo da Web propriamente dito. Na caixa de diálogo New Project, selecionei a opção de modelos de idioma translation from VPE for Csharp. Aplicativos do Silverlight também podem ser criados usando o Visual Basic e pode até criar bibliotecas do Silverlight usando a nova linguagem F #.

Selecionei a opção de biblioteca de Microsoft .NET Framework 4 padrão e o modelo de aplicativo do Silverlight. Silverlight contém um subconjunto do .NET Framework, portanto, não que todas as partes do .NET Framework 4 estão disponíveis para aplicativos do Silverlight. Depois de preencher os campos (C:\SilverlightTesting) local e nome (SilverCalc), cliquei no botão OK. (Observe que SilverCalc é o nome de projeto do Visual Studio e MicroCalc é o nome do aplicativo.)

O Visual Studio, em seguida, me solicitado em uma caixa de diálogo Novo aplicativo do Silverlight que pode ser confusa para iniciantes do Silverlight. Let’s dar uma olhada mais de perto as opções em do Figura 3.


Figura 3 do novas opções de caixa de diálogo Silverlight Application

A primeira entrada, “ hospedar o aplicativo do Silverlight em um novo site ” é marcada por padrão. Isso instrui o Visual Studio para criar duas páginas da Web diferentes para hospedar seu aplicativo do Silverlight.

A próxima entrada é o nome do projeto Visual Studio que contém as páginas dois host. O projeto será adicionado à sua solução do Visual Studio.

A terceira entrada na caixa de diálogo é um controle suspenso com três opções: Projeto de aplicativo Web ASP.NET, ASP.NET Web Site e projeto de Web do ASP.NET MVC. Uma discussão completa sobre essas opções é fora do escopo deste artigo, mas o resultado final é que a melhor opção de finalidade geral é ASP.NET Web Application Project.

A quarta entrada na caixa de diálogo é uma lista suspensa para selecionar a versão do Silverlight, nesse caso 3.0. Depois de clicar em OK, o Visual Studio cria um aplicativo do Silverlight em branco.

Eu clicou duas vezes no arquivo MainPage.xaml para carregar as definições de interface do usuário baseada em XAML no editor do Visual Studio. Adicionando atributos width e Height e alterando o atributo de cor de plano de fundo, modifiquei os atributos padrão para o controle de grade de nível superior:

<Grid x:Name="LayoutRoot"
  Background="PaleGreen" 
  Width="300" Height="300">

Por padrão, um aplicativo do Silverlight ocupa toda a área do cliente na sua página de hospedagem. Aqui eu definir a largura e altura para 300 pixels para tornar o meu aplicativo do Silverlight se parecem com o tamanho padrão de um aplicativo WinForm. Ajustei a cor para tornar a área ocupada pelo meu aplicativo do Silverlight claramente visível.

Em seguida usei o Visual Studio para adicionar os rótulos, três controles TextBox, dois controles RadioButton e um controle Button em meu aplicativo, como mostra a 1 Figura . Visual Studio 2010 tem um modo de exibição de design totalmente integrada para que quando arrasto um controle, como um TextBox para a superfície de design, o código subjacente do XAML é gerado automaticamente:

<TextBox Width="99" Height="23" Name="textBox1" ... />

Depois de colocar os rótulos e controles em meu aplicativo MicroCalc, eu duas vezes no controle de botão para adicionar seu manipulador de eventos para o arquivo MainPage.xaml.cs. No editor de código digitado o seguinte código translation from VPE for Csharp dar MicroCalc sua funcionalidade:

private void button1_Click(
  object sender, RoutedEventArgs e) {

  double x = double.Parse(textBox1.Text);
  double y = double.Parse(textBox2.Text);
  double result = 0;
  if (radioButton1.IsChecked == true)
    result = x * y;
  else if (radioButton2.IsChecked == true)
    result = x / y;
  textBox3.Text = result.ToString("0.0000");
}

Começo apanhar os valores inseridos como texto nos controles textBox1 e textBox2 e convertê-las digite dupla. Observe que, para manter meu exemplo breve, eu ter omitido a normal verificação de erro que você deseja executar em um aplicativo real.

Em seguida, determine qual controle RadioButton foi selecionado pelo usuário. Eu deve usar a expressão booleana totalmente qualificado:

if radioButton1.IsChecked == true

Você pode ter esperado que eu poderia usar o formulário atalho:

if radioButton1.IsChecked

Usar o formulário totalmente qualificado como a propriedade IsChecked é bool tipo anulável? em vez de simples bool.

Depois de calcular o resultado indicado, eu coloque o resultado formatado para quatro casas decimais no controle textBox3.

MicroCalc agora está pronto para ser usado e possa pegar a tecla F5 para instruir o Visual Studio para executar o aplicativo. Por padrão, o Visual Studio irá iniciar o Internet Explorer e carregar a página host .aspx associado que foi gerada automaticamente. O Visual Studio executa uma página de host de teste do Silverlight por meio do servidor de desenvolvimento de Web interno, em vez de fazê-lo através do IIS. Juntamente com um .aspx teste página host, também, o Visual Studio gera uma página de teste HTML que você pode carregar manualmente digitando seu endereço no Internet Explorer.

O conjunto de teste

Agora que você já viu o aplicativo do Silverlight em teste, vou descrever a estrutura de teste.

Decidi usar o local de mensagens para enviar mensagens entre o equipamento e o aplicativo. Começo iniciando uma nova instância do Visual Studio 2010. Usando o mesmo processo conforme descrito na seção anterior, criei um novo aplicativo do Silverlight chamado TestHarness. Como com o aplicativo MicroCalc, eu editado no controle de grade nível superior para alterar seu tamanho padrão para 300 x 300 pixels e sua cor de plano de fundo para Bisque para tornar o controle do Silverlight se destacam claramente. Em seguida adicionei um controle Label, dois controles ListBox e um controle Button para a superfície de design da estrutura.

Depois de alterar a propriedade Content do controle Button para executar teste selecionados, eu duas vezes com o botão para gerar seu manipulador de eventos. Antes de adicionar o código da lógica ao manipulador, declaro um escopo de classe LocalMessageSender objeto e casos de teste dados no arquivo MainPage.xaml.cs do equipamento de para que o equipamento pode enviar mensagens para o aplicativo sob teste:

public partial class MainPage : UserControl {
  LocalMessageSender lms = null;
  private string[] testCases = new string[] {
    "001:2.5:3.0:Multiply:7.5000",
    "002:8.6:2.0:Divide:4.3000"
  };
...

A classe LocalMessageSender está contida no namespace System.Windows.Messaging para que eu adicionei uma referência a ele com o uso de um arquivo de instrução na parte superior da. cs para que eu Don tenha que qualificar totalmente o nome da classe. Eu empregar uma abordagem simples para dados do meu caso de teste e use uma seqüência de caracteres delimitada por vírgula com campos para ID de caso de teste, valor de entrada primeiro, segundo valor de entrada, operação e resultado esperado. Em seguida, adiciono variáveis de seqüência de caracteres de escopo de classe para cada campo de caso de teste:

private string caseID;
private string input1;
private string input2;
private string operation;
private string expected;
...

Essas variáveis não são tecnicamente necessárias, mas tornam mais fácil de ler e modificar o código de teste.

Agora, instancio um objeto LocalMessageReceiver no construtor MainPage para que o conjunto de teste pode aceitar mensagens de aplicativo em teste:

public MainPage() {
  InitializeComponent();

  try {
    LocalMessageReceiver lmr =
      new LocalMessageReceiver("HarnessReceiver",
        ReceiverNameScope.Global,
        LocalMessageReceiver.AnyDomain);
...

O construtor de objeto LocalMessageReceiver aceita três argumentos. O primeiro argumento é um nome para identificar o receptor — isso será usado por um objeto LocalMessageSender para especificar qual receptor ao destino. O segundo argumento é um tipo de enumeração que especifica se o nome do receptor com escopo global no domínio ou para um domínio mais restrito. O terceiro argumento especifica onde o receptor aceitará mensagens de, nesse caso, qualquer domínio.

Em seguida, conectar um manipulador de eventos para o receptor e, em seguida, acionar o objeto receptor:

lmr.MessageReceived += HarnessMessageReceivedHandler;
lmr.Listen();
...

Aqui eu indicam que, quando o utilitário de teste recebe uma mensagem, controle deve ser transferido para um método definido pelo programa chamado HarnessMessageReceivedHandler. O método Listen, como era de se esperar, monitora continuamente mensagens de entrada enviadas de um LocalMessageSender no aplicativo em teste.

Agora posso criar uma instância do objeto remetente que declarei anteriormente:

lms = new LocalMessageSender(
  "AppReceiver", LocalMessageSender.Global);
lms.SendCompleted += HarnessSendCompletedHandler;
...

Observe que o primeiro argumento para o objeto do remetente é o nome de um objeto receptor de destino, não um nome de identificação do remetente. Aqui meu remetente de equipamento de teste estará enviando mensagens somente para um receptor chamado AppReceiver localizado no aplicativo em teste. Em outras palavras, objetos de destinatário têm nomes e aceitarão mensagens de qualquer remetente objetos, mas objetos do remetente não têm nomes e enviarão as mensagens apenas a um receptor específico.

Depois de criar uma instância do objeto de remetente, eu conectar um manipulador de eventos para o evento SendCompleted. Agora posso criar meus casos de teste de carga e tratar qualquer exceção:

...
    foreach (string testCase in testCases) {
      listBox1.Items.Add(testCase);
    }
  } // try
  catch (Exception ex) {
    listBox2.Items.Add(ex.Message);
  }
} // MainPage()

Eu simplesmente iterar 
array caso de teste, adicionando cada seqüência de caracteres do caso de teste para o controle listBox1. Se nenhuma exceção é detectada, eu apenas exibir o texto no controle listBox2 usado para comentários.

Nesse ponto eu ter um objeto de remetente no equipamento que pode enviar a entrada do caso de teste do aplicativo e um objeto receptor no equipamento que pode aceitar as informações de estado do aplicativo. Agora, volte para o método do manipulador Button1_Click adicionados anteriormente. No manipulador do começo ao analisar o caso de teste selecionado:

string testCaseData = (string)listBox1.SelectedItem;
string[] tokens = testCaseData.Split(':');
caseID = tokens[0];
input1 = tokens[1];
input2 = tokens[2];
operation = tokens[3];
expected = tokens[4];
...

Agora estou pronto para enviar os dados de entrada de caso de teste ao aplicativo do Silverlight em teste:

string testCaseInput = 
  input1 + ":" + input2 + ":" + operation;
listBox2.Items.Add("========================");
listBox2.Items.Add("Test case " + caseID);
listBox2.Items.Add(
  "Sending ‘" + testCaseInput + "’ to application");
lms.SendAsync("data" + ":" + testCaseInput);
...

Eu reunir novamente apenas entrada do caso de teste. Eu não envie o ID de caso de teste ou o valor esperado para o aplicativo porque somente a estrutura lida com esses valores. Depois de exibir alguns comentários para o controle listBox2, uso o método SendAsync do objeto LocalMessageSender para enviar os dados do caso de teste. Eu colocar a seqüência de dados de “ ” para que o aplicativo tem uma maneira de identificar o tipo de mensagem está sendo recebido.

Meu manipulador de eventos do botão de conclusão, fazendo uma pausa por um segundo para dar tempo o aplicativo para executar e, em seguida, eu envie uma mensagem solicitando o aplicativo para suas informações de estado:

System.Threading.Thread.Sleep(1000); 
  lms.SendAsync(“response”);
} // button1_Click

Lembre-se de que eu cabeada até um manipulador de eventos para conclusão do envio mas neste projeto não precisam executar qualquer processamento post-send explícito.

A parte final do código de estrutura lida com a mensagem enviada do aplicativo do Silverlight para o equipamento:

private void HarnessMessageReceivedHandler(object sender,
  MessageReceivedEventArgs e) {

  string actual = e.Message;
  listBox2.Items.Add(
    "Received " + actual + " from application");
  if (actual == expected)
    listBox2.Items.Add("Pass");
  else
    listBox2.Items.Add("**FAIL**");

  listBox2.Items.Add("========================");
}

Aqui eu buscar a mensagem do aplicativo, que é o valor no controle de resultado textBox3 e armazenar esse valor em uma variável chamada real. Depois de exibir um comentário, compare o valor real que foi enviado pelo aplicativo com o valor esperado analisado a partir de dados do caso de teste para determinar e exibir um resultado de êxito/falha do caso de teste.

Instrumentar o aplicativo do Silverlight

Agora let’s examinar o código instrumentado dentro do aplicativo do Silverlight em teste. Começo declarando um objeto LocalMessageSender do escopo de classe.

Esse remetente enviará mensagens para a estrutura de teste:

public partial class MainPage : UserControl {
  LocalMessageSender lms = null;
  public MainPage() {
    InitializeComponent();
...

Em seguida, eu instanciar um receptor no construtor MainPage para aceitar mensagens de equipamento de teste, fios um manipulador de eventos e iniciar a escuta de mensagens do equipamento de:

try {
  LocalMessageReceiver lmr =
    new LocalMessageReceiver("AppReceiver",
      ReceiverNameScope.Global,
      LocalMessageReceiver.AnyDomain);
  lmr.MessageReceived += AppMessageReceivedHandler;
  lmr.Listen();
...

Como antes, observe que você atribuir um nome para o objeto receptor, e que esse nome corresponde ao primeiro argumento para o objeto do remetente no equipamento de. Em seguida, eu lidar com exceções:

...
  }
  catch (Exception ex) {
    textBox3.Text = ex.Message;
  }
} // MainPage()

Posso exibir mensagens de exceção no controle textBox3, que é o campo de resultado MicroCalc aplicativo. Essa abordagem é completamente ad hoc, mas enviar a mensagem de exceção de volta para a estrutura de teste pode não ser viável se o código mensagens lança a exceção. Agora posso lidar com as mensagens enviadas pelo equipamento de teste:

private void AppMessageReceivedHandler(object sender,
  MessageReceivedEventArgs e) {
  string message = e.Message;
  if (message.StartsWith("data")) {
    string[] tokens = message.Split(‘:’);
    string input1 = tokens[1];
    string input2 = tokens[2];
    string operation = tokens[3];
...

O utilitário de teste envia dois tipos de mensagens. Caso de teste de entrada de dados começa com dados de “ ” enquanto uma solicitação de estado do aplicativo é apenas “ resposta ”. Uso o método StartsWith para determinar se a mensagem recebida pelo aplicativo de entrada do caso de teste. Nesse caso, uso o método Split para analisar a entrada em variáveis com nomes descritivos.

Agora a instrumentação usa o caso de teste para simular ações do usuário de entrada:

textBox1.Text = input1;
textBox2.Text = input2;
if (operation == "Multiply")
  radioButton1.IsChecked = true;
else if (operation == "Divide")
  radioButton2.IsChecked = true;
...

Em geral, modificar propriedades de controles, como as propriedades Text e IsChecked neste exemplo simular a entrada do usuário é simples. No entanto, a simulação de eventos, como cliques de botão exige uma abordagem diferente:

button1.Dispatcher.BeginInvoke(
  delegate { button1_Click(null,null); });

A classe Dispatcher é parte do namespace Windows.Threading para que eu adicionei um usando afirmativa fazendo referência a essa classe para o aplicativo. O método BeginInvoke permite chamar um método assíncrona no thread da interface de usuário do Silverlight. BeginInvoke aceita um delegado, que é um wrapper em torno de um método. Aqui eu usar o recurso delegado anônimo para simplificar a minha chamada. BeginInvoke retorna um objeto DispatcherOperation, mas nesse caso, pode ignorar com segurança esse valor.

A classe Dispatcher também tem um método CheckAccess que você pode usar para determinar se BeginIvoke é necessário (quando CheckAccess retorna false) ou se você pode apenas modificar uma propriedade (CheckAccess retorna true).

Concluo meu instrumentação por lidar com a mensagem do equipamento de teste que solicita o estado do aplicativo:

...
  }
  else if (message == "response") {
    string actual = textBox3.Text;
    lms.SendAsync(actual);
  }
} // AppMessageReceivedHandler()

Se a mensagem recebida é apenas a seqüência de “ resposta ”, eu pegar o valor no controle textBox3 e envie-o novamente para a estrutura de teste.

O sistema de teste descrito neste artigo é apenas uma das várias abordagens que você pode usar e é mais adequado para 4-4-4 superleve automação de teste. Por isso quer dizer um equipamento que tem uma vida esperada de 4 semanas ou menos, consiste em quatro páginas ou menos código e requer 4 horas ou menos para criar.

A principal vantagem de teste usando mensagens em comparação comparadas outros métodos é que a técnica é muito simples. A principal desvantagem é que o aplicativo em teste deve ser fortemente instrumentado, que pode não ser viável.

Duas alternativas importantes para a técnica que apresentei aqui estão usando a ponte HTML com JavaScript e usando a biblioteca de automação da interface do usuário da Microsoft. Como sempre, eu Lembre-se que ninguém determinado teste abordagem é melhor para todas as situações, mas a abordagem baseada em mensagens que apresentei aqui pode ser uma técnica eficiente e eficaz em vários cenários de desenvolvimento de software.

Dr. James McCaffrey* trabalha para a Volt Information Sciences Inc., onde gerencia o treinamento técnico para engenheiros de software que trabalham com a Microsoft Redmond, Wash., campus. Ele trabalhou em vários produtos da Microsoft, incluindo o Internet Explorer e o MSN Busca. Dr. McCaffrey é autor de “ .NET Test Automation Recipes ” (Apress, 2006). Ele pode ser contatado em jammc@microsoft.com .*

Graças aos seguintes especialistas técnicos para revisar este artigo: Karl Erickson e Nitya Ravi