Compartilhar via


Desenvolver testes por meio de um modelo

Você pode usar os requisitos e os modelos de arquitetura para ajudá-lo a organizar os testes de seu sistema e seus componentes. Essa prática ajuda a garantir que você teste os requisitos importantes para os usuários e outros stakeholders e ajuda a atualizar os testes rapidamente quando os requisitos são alterados. Se você usar o Microsoft Test Manager, também poderá manter links entre os modelos e os testes.

Para saber quais versões do Visual Studio dão suporte a esses recursos, consulte o suporte de versão para ferramentas de arquitetura e modelagem.

Teste de sistema e subsistema

O teste de sistema, também conhecido como teste de aceitação, significa testar se as necessidades dos usuários estão sendo atendidas. Esses testes preocupam-se com o comportamento externamente ao visível do sistema em vez do projeto interno.

Os testes do sistema são muito valiosos ao estender ou redesenhar um sistema. Eles ajudam a evitar a introdução de bugs quando se altera o código.

Quando você planeja qualquer alteração ou extensão para um sistema, é útil começar com um conjunto de testes do sistema executados no sistema existente. Em seguida, você pode estender ou ajustar os testes para testar os novos requisitos, fazer as alterações no código e executar novamente o conjunto completo de testes.

Ao desenvolver um novo sistema, você pode começar a criar testes assim que o desenvolvimento começar. Ao definir testes antes de desenvolver cada recurso, você pode capturar as discussões de requisitos de uma maneira muito específica.

O teste de subsistema aplica os mesmos princípios aos principais componentes de um sistema. Cada componente é testado separadamente de outros componentes. Os testes de subsistema se concentram no comportamento visível nas interfaces de usuário ou na API do componente.

Derivar testes do sistema de um modelo de requisitos

Você pode criar e manter uma relação entre testes do sistema e um modelo de requisitos. Para estabelecer essa relação, você escreve testes que correspondem aos principais elementos do modelo de requisitos. O Visual Studio ajuda a manter essa relação, permitindo que se crie conexões entre os testes e partes do modelo. Para saber mais sobre modelos de requisitos, confira Modelo de requisitos de usuário.

Escrever testes para cada caso de uso

Se você usar o Microsoft Test Manager, poderá criar um grupo de testes para cada caso de uso definido em seu modelo de requisitos. Por exemplo, se você tiver um caso de uso Order a Meal (Pedir uma refeição), que inclui Create Order (Criar pedido) e Add Item to Order (Adicionar item ao pedido), você poderá criar testes tanto para o geral e o mais detalhado desses casos de uso.

Essas diretrizes podem ser úteis:

  • Cada caso de uso deve ter vários testes, para os principais caminhos e resultados excepcionais.

  • Quando você descreve um caso de uso no modelo de requisitos, é mais importante definir sua pós-condição, ou seja, a meta que é alcançada, do que descrever detalhadamente os procedimentos que o usuário segue para atingir a meta. Por exemplo, a pós-condição de Pedir uma Refeição pode ser que um Restaurante esteja preparando uma refeição para um Cliente e que o Cliente já tenha pago. A pós-condição é o critério que seus testes devem verificar.

  • Basear testes separados nas cláusulas separadas da pós-condição. Por exemplo, crie testes separados para notificar o restaurante do pedido e para receber o pagamento do cliente. Essa separação tem estas vantagens:

    • Alterações em diferentes aspectos dos requisitos ocorrem com frequência independentemente. Ao separar os testes em diferentes aspectos dessa maneira, você facilita a atualização dos testes quando os requisitos são alterados.

    • Se o plano de desenvolvimento implementar um aspecto do caso de uso antes do outro, você poderá habilitar os testes separadamente à medida que o desenvolvimento progride.

  • Ao projetar os testes, separe a escolha dos dados de teste do código ou script que determina se a pós-condição foi obtida. Por exemplo, um teste de uma função aritmética simples pode ser: Entrada 4; verifique se a saída é 2. Em vez disso, projete o script como: Escolher uma entrada; multiplique a saída por si só e verifique se o resultado é a entrada original. Esse estilo permite que você varie as entradas de teste sem alterar o corpo principal do teste.

Vinculando testes para casos de uso

Se você estiver usando o Test Manager para projetar e executar seus testes, poderá organizar seus testes sob requisitos, casos de uso ou itens de trabalho da história do usuário. Você pode vincular esses itens de trabalho para usar casos em seu modelo. Isso permite rastrear rapidamente as alterações de requisitos nos testes e ajuda a acompanhar o progresso de cada caso de uso.

  1. No Test Manager, crie um requisito e baseie um conjunto de testes nele.

    O requisito que você cria é um item de trabalho no Team Foundation Server. Pode ser uma história de usuário, um requisito ou um item de trabalho de Caso de Uso, dependendo do modelo de processo que seu projeto usa com o Team Foundation. Para mais informações, consulte Sobre as ferramentas Agile e o gerenciamento de projetos Agile.

  2. Vincule o item de trabalho de requisito a um ou mais casos de uso em seu modelo.

    Em um diagrama de caso de uso, clique com o botão direito do mouse em um caso de uso e clique em Vincular ao Item de Trabalho.

  3. Adicione ao conjunto de testes, casos de teste que verificam os casos de uso.

    Normalmente, cada artigo de usuário ou item de trabalho de requisito será vinculado a vários casos de uso em seu modelo, e cada caso de uso será vinculado a várias histórias ou requisitos de usuário. Isso ocorre porque cada história ou requisito do usuário abrange um conjunto de tarefas que desenvolvem vários casos de uso. Por exemplo, em uma iteração inicial do seu projeto, você pode desenvolver a história de usuário básica na qual um cliente pode escolher itens de um catálogo e entregá-los. Em uma iteração posterior, a história pode ser que o usuário pague ao concluir o pedido, e o fornecedor recebe o dinheiro depois de enviar a mercadoria. Cada história adiciona uma cláusula à pós-condição do caso de uso de Bens de Ordem.

    Você pode criar links separados dos requisitos para as cláusulas da pós-condição escrevendo essas cláusulas em comentários separados no diagrama de caso de uso. Você pode vincular cada comentário a um item de trabalho de requisito e vincular o comentário ao caso de uso no diagrama.

Testes base nos tipos de requisitos

Os tipos, ou seja, as classes, interfaces e enumerações, de um modelo de requisitos descrevem os conceitos e relações em termos de como os usuários pensam e se comunicam sobre seus negócios. Ele exclui os tipos relacionados somente ao projeto interno do sistema.

Crie seus testes em termos desses tipos de requisitos. Essa prática ajuda você a garantir que, quando as alterações nos requisitos são discutidas, é fácil relacionar as alterações às alterações necessárias nos testes. Isso possibilita discutir os testes e seus resultados pretendidos diretamente com usuários finais e outros stakeholders. Isso significa que as necessidades dos usuários podem ser mantidas fora do processo de desenvolvimento e evita o projeto inadvertido dos testes em torno de possíveis falhas no modelo.

Para testes manuais, essa prática envolve aderir ao vocabulário do modelo de requisitos nos scripts de teste. Para testes automatizados, essa prática envolve o uso dos diagramas de classe de requisitos como base para o código de teste e a criação de funções de acessador e atualizador para vincular o modelo de requisito ao código.

Por exemplo, um modelo de requisitos pode incluir os tipos Menu, Item de Menu, Pedido e associações entre eles. Esse modelo representa as informações armazenadas e tratadas pelo sistema de pedidos de refeição, mas não representa as complexidades de sua implementação. No sistema de trabalho, pode haver várias realizações diferentes de cada tipo, em bancos de dados, em interfaces de usuário e em APIs. Em um sistema distribuído, pode haver várias variantes de cada instância armazenadas em diferentes partes do sistema ao mesmo tempo.

Para testar um caso de uso, como Adicionar Item à Ordem, um método de teste pode incluir um código semelhante a este:

Order order = ... ; // set up an order
// Store prior state:
int countBefore = order.MenuItems.Count;
// Perform use case:
MenuItem chosenItem = ...; // choose an item
AddItemToOrder (chosenItem, order);
// Verify part of postcondition:
int countAfter = order.MenuItems.Count;
Assert (countAfter == countBefore = 1);

Observe que esse método de teste usa as classes do modelo de requisitos. Associações e atributos são realizados como propriedades do .NET.

Para que isso funcione, as propriedades das classes devem ser definidas como funções somente leitura ou acessadores, que acessam o sistema para recuperar informações sobre seu estado atual. Métodos que simulam casos de uso, como AddItemToOrder, devem conduzir o sistema por meio de sua API ou por meio de uma camada abaixo de sua interface do usuário. Os construtores de objetos de teste, como Pedido e MenuItem, também devem conduzir o sistema para criar itens correspondentes dentro do sistema.

Muitos dos acessadores e atualizadores já estarão disponíveis por meio da API normal do aplicativo. Mas algumas funções adicionais podem precisar ser gravadas para habilitar os testes. Esses acessadores e atualizadores adicionais às vezes são conhecidos como "instrumentação de teste". Como eles dependem do projeto interno do sistema, é responsabilidade dos desenvolvedores do sistema fornecê-los, enquanto os testadores gravam o código dos testes em termos do modelo de requisitos.

Ao escrever testes automatizados, você pode usar Testes Genéricos para encapsular os acessadores e atualizadores.

Testes para Business Rules

Alguns requisitos não estão diretamente relacionados a nenhum caso de uso. Por exemplo, a empresa DinnerNow permite que os clientes escolham entre muitos Menus, mas exige que, em cada Pedido, todos os Itens escolhidos sejam de um único Menu. Essa regra de negócios pode ser expressa como invariável sobre as associações entre Pedidos, Menus e Itens no modelo de classe de requisitos.

Uma regra invariável desse tipo rege não apenas todos os casos de uso definidos no momento, mas também quaisquer outros casos de uso que serão definidos posteriormente. Portanto, é útil gravá-lo separadamente de qualquer caso de uso e testá-lo separadamente dos casos de uso.

Derivando testes de subsistema de modelos

No projeto de alto nível de um sistema grande, você pode identificar componentes ou subsistemas. Elas representam partes que podem ser projetadas separadamente ou estão localizadas em computadores diferentes ou são módulos reutilizáveis que podem ser recombinados de várias maneiras.

Você pode aplicar a cada componente principal os mesmos princípios usados para o sistema completo. Em um projeto grande, cada componente pode ter seu próprio modelo de requisitos. Em projetos menores, um modelo de arquitetura ou projeto de alto nível pode ser criado para mostrar os principais componentes e suas interações. Para mais informações, consulte Modelar a arquitetura do aplicativo.

Em ambos os casos, você pode estabelecer uma relação entre os elementos do modelo e os testes de subsistema da mesma maneira que faria entre o modelo de requisitos e os testes do sistema.

Isolar componentes com interfaces fornecidas e necessárias

É útil identificar todas as dependências que um componente tem em outras partes do sistema ou serviços externos e representá-las como Interfaces exigidas. Esse exercício geralmente leva a algum redesenho que deixa o componente muito mais desacoplado e facilmente separado do restante do seu modelo.

Uma vantagem dessa desacoplamento é que o componente pode ser executado para teste substituindo por objetos fictícios os serviços que ele geralmente usa. Esses são componentes que são configurados para fins de teste. Um componente fictício fornece a interface necessária para o componente, respondendo a consultas com dados simulados. Os componentes fictícios fazem parte de um arreio de teste completo que você pode conectar a todas as interfaces do componente.

Um benefício do teste simulado é que você pode desenvolver seu componente enquanto os outros componentes cujos serviços ele usará ainda estão em desenvolvimento.

Manter as Relações entre testes e modelo

Em um projeto típico que executa uma iteração a cada poucas semanas, uma revisão de requisitos é realizada perto do início de cada iteração. A reunião discute os recursos que serão entregues na próxima iteração. Um modelo de requisitos pode ser usado para ajudar a discutir os conceitos, cenários e sequências de ações que serão desenvolvidas. Os stakeholders empresariais definem prioridades, os desenvolvedores fazem estimativas e os testadores garantem que o comportamento esperado de cada recurso seja capturado corretamente.

Escrever testes é a maneira mais eficaz de definir um requisito e também é uma maneira eficaz de garantir que uma pessoa tenha uma compreensão clara do que é necessário. No entanto, enquanto a gravação de testes leva muito tempo para ser feita durante um workshop de especificação, a criação de modelos pode ser feita muito mais rapidamente.

Do ponto de vista do teste, um modelo de requisitos pode ser visto como uma abreviação para os testes. Portanto, é importante manter a relação entre testes e modelos em todo o projeto.

Anexando casos de teste a elementos de modelo

Se o projeto usar o Test Manager, você poderá vincular testes aos elementos em seu modelo. Isso permite que você localize rapidamente os testes afetados por uma alteração nos requisitos e ajuda a acompanhar até que ponto um requisito foi realizado.

Você pode vincular testes a todos os tipos de elemento. Estes são alguns exemplos:

  • Vincule um caso de uso aos testes que o exercem.

  • Escreva as cláusulas de uma pós-condição de caso de uso ou meta em comentários vinculados ao caso de uso e vincule testes a cada comentário.

  • Escreva as regras invariáveis em comentários sobre diagramas de classe ou de atividade e vincule-as a testes.

  • Vincule testes a um diagrama de atividade ou a atividades individuais.

  • Vincule um pacote de testes ao componente ou subsistema que ele testa.

  1. No Test Manager, crie um requisito e baseie um conjunto de testes nele.

    O requisito que você cria é um item de trabalho no Team Foundation Server. Pode ser uma história de usuário, um requisito ou um item de trabalho de Caso de Uso, dependendo do modelo de processo que seu projeto usa com o Team Foundation. Para mais informações, consulte Sobre as ferramentas Agile e o gerenciamento de projetos Agile.

  2. Vincule o item de trabalho de requisito a um ou mais elementos em seu modelo.

    Em um diagrama de modelagem, clique com o botão direito do mouse em um elemento, comentário ou relação e clique em Vincular ao Item de Trabalho.

  3. Adicione ao conjunto de testes, casos de teste que verificam o requisito expresso no elemento de modelo.