33 Pages • 2,218 Words • PDF • 143.4 KB
Uploaded at 2021-09-24 13:36
This document was submitted by our user and they confirm that they have the consent to share it. Assuming that you are writer or own the copyright of this document, report to us by using this DMCA report button.
Teste Funcional © Prof. Raul Sidnei Wazlawick UFSC-CTC-INE 2010
Necessidade do Teste Funcional • O teste estrutural é adequado quando se pretende verificar a estrutura de um programa. • Mas em várias situações a necessidade consiste em verificar a funcionalidade de um programa independentemente de sua estrutura interna. • Um programa pode ter uma especificação, ou comportamento esperado, usualmente elaborado em um contrato de operação e o que se deseja saber é se ele efetivamente cumpre este contrato.
• Em orientação a objetos, o teste de unidade realizado como estrutural é adequado para a verificação dos elementos mais básicos do software, em especial, as operações básicas que criam e destroem instâncias, adicionam ou removem associações ou alteram o valor de atributos. • Tais testes também são adequados para as consultas básicas que retornam o valor de atributos reais ou derivados, bem como de associações reais ou derivadas (Wazlawick, 2010).
• Porém, em um nível mais alto de operações tal verificação estrutural pode ser difícil de realizar, pois operações podem chamar outras operações delegando responsabilidades de um objeto a outro. • Assim, no nível de integração de funções mais básicas ao software pode ser mais interessante realizar testes funcionais, que avaliam o comportamento de uma operação mais abrangente do que as operações elementares.
Testes de Integração • Recomenda-se que os testes de integração sejam realizados sobre as operações de sistema, isto é, aquelas operações implementadas na classe controladora de sistema (que implementa as operações que devem ser executadas em resposta a eventos de interface). • Essas operações, usualmente terão contratos bem definidos com parâmetros tipados, pré-condições, póscondições e exceções. • O teste funcional então consistirá em verificar se em situação de normalidade (pré-condições atendidas) as póscondições desejadas são realmente obtidas e, se em situações de anormalidade, as exceções são efetivamente levantadas.
Particionamento de Equivalência • Um dos princípios do teste funcional é a identificação de situações equivalentes. • Por exemplo, se um programa aceita um conjunto de dados e rejeita outro conjunto então se pode dizer que existem duas classes de equivalência para os dados de entrada do programa: – a classe dos aceitos e – a dos rejeitados.
• Pode ser impossível testar todos os elementos de cada classe, até porque esses conjuntos podem ser infinitos. • Então, o particionamento de equivalência vai determinar que pelo menos um elemento de cada classe seja testado.
Classes (Myers, Sandler, Badgett, & Thomas, 2004): • Se a entrada é especificada como um intervalo de valores, então é definida uma classe válida e duas inválidas (antes e depois do intervalo). • Se a entrada é especificada como uma quantidade de valores, então é definida uma classe válida e duas inválidas (acima e abaixo da quantidade especificada). • Se a entrada é especificada como um conjunto de valores que podem ser tratados de forma diferente, então é definida uma classe válida para cada uma das formas de tratamento e uma classe inválida para outros valores quaisquer. • Se a entrada é especificada por uma condição do tipo “deve ser de tal forma”, então deve ser definida uma classe válida e uma inválida.
Partição sobre resultados • As classes de partição devem ser definidas não só em termos de restrições sobre as entradas, mas também em função dos resultados a serem produzidos.
Exemplo • Considere um contrato de operação de sistema “adicionaLivro(idLivro,IdCompra,quant)” que toma da interface três valores: – um identificador de livro (idLivro), – um identificador de uma compra (idCompra) e – uma quantidade (quant).
• O objetivo da operação consiste em adicionar na compra indicada um item que associe o livro indicado e uma quantidade.
• A Figura apresenta o modelo conceitual de referência para este exemplo. • Apenas os atributos relevantes para o exemplo foram usados, embora as classes originais pudessem ter vários outros.
adicionaLivro(idLivro,IdCompra,quant)
Em função das entradas, as seguintes classes de equivalência podem ser definidas: • Para idLivro: – válido se existe um livro com este id, – inválido se tal livro não existe.
• Para idCompra: – válido se existe uma compra com este id e está aberta, – inválido caso a compra não exista e – inválido se a compra já está fechada.
• Para quantidade: – válido se for um valor maior ou igual a 1, – inválido para zero.
• Em relação aos resultados, pode-se ainda considerar que se o livro já consta na compra, então ao invés de criar um novo item, deve-se somar a quantidade solicitada com a quantidade que já consta na compra. • Neste caso, pode-se subdividir a classe válida relacionada com idLivro em duas classes válidas: – quando o idLivro não consta na compra e – quando o idLivro consta na compra.
Classes resultantes • Para idLivro: – válido se existe um livro com este id que consta na compra, – válido se existe um livro com este id que não consta na compra e – inválido se não existe livro com este id.
• Para idCompra: – válido se existe uma compra com este id e está aberta, – inválido caso a compra não exista e – inválido se a compra já está fechada.
• Para quantidade: – válido se for um valor maior ou igual a 1, – inválido para zero.
Casos de teste
• Usualmente nem todas as combinações das classes de equivalência são testadas. • Normalmente testa-se todas as combinações de classes válidas, como nas duas primeiras linhas da tabela anterior, e acrescenta-se uma possível classe inválida de cada vez, correspondendo às demais linhas da tabela. • Desta forma, uma das limitações da técnica consiste em não testar condições de erro que ocorrem combinadas, ou seja, duas ou mais condições de erro de cada vez. • Isso ocorre porque a combinação de todas as classes de equivalência cresce exponencialmente em relação à quantidade delas. • Ou seja, condição com duas ou mais classes multiplica o número de testes necessários.
No exemplo, a condição (a) tem 3 classes, a condição (b) tem também 3 classes e a condição (c) duas classes, resultando portanto em 3x3x2=12 combinações possíveis.
• Então, embora não se testem todas as combinações, é necessário testar todas as combinações válidas e pelo menos uma das classes inválidas. • Se o analista de teste julgar necessário testar combinações de classes inválidas, pode, porém, introduzir o caso de teste, sem problema algum.
Análise de Valor Limite • Um dos ditados em teste de software é que os bugs (insetos, em inglês) costumam se esconder nas frestas. • Em função dessa realidade, a técnica de partição de equivalência normalmente é usada em conjunto com o critério de análise de valor limite. • A análise de valor limite consiste em considerar não apenas um valor qualquer para teste dentro de uma classe de equivalência, mas um ou mais valores fronteiriços com outras classes de equivalência quando isso puder ser determinado.
• Em domínios ordenados (números inteiros, por exemplo), esse critério pode ser aplicado. • Por exemplo, se um programa exige uma entrada que para ser válida deve estar no intervalo [n..m], então existem três classes de equivalência: – Inválida para qualquer x < n. – Válida para qualquer x >= n e x m.
• Então a análise de valor limite sugere que possíveis erros de lógica do programa possam estar não em qualquer ponto dentro das classes, mas nos pontos onde uma classe se encontra com outra. Então: – Para a primeira classe inválida, deve-se testar para o valor n-1. – Para a classe válida, deve-se testar os valores n e m. – Para a segunda classe inválida, deve-se testar para o valor m+1.
• Assim, se existir um erro no programa para alguma dessas classes é muito mais provável que ele seja capturado dessa forma do que se fosse selecionado um valor qualquer dentro de cada um destes três intervalos.
Outros Tipos de Testes • Até aqui foi discutido o teste estrutural e sua aplicação para testar os componentes mais elementares do sistema (algoritmos), e o teste funcional, com sua aplicação para testar a integração destes componentes em operações de mais alto nível, em geral, no nível de operação de sistema, ou seja, uma operação que é executada por um sistema em resposta a um evento de interface. • Existem, porém outros tipos de testes que são identificados e utilizados. • Usualmente esses testes podem se basear na técnica funcional, mas como os objetivos podem ser distintos, eles também podem ter outras características.
Teste de Sistema • O teste de integração tem como objetivo verificar se as funcionalidades básicas foram adequadamente integradas ao sistema, verificando se as operações de sistema individualmente funcionam conforme sua especificação (contrato). • O teste de sistema, por outro lado, visa verificar o encadeamento destas operações do ponto de vista de um usuário que executa uma série de operações de sistema em uma interface (não necessariamente gráfica) e sendo capaz de obter os resultados esperados.
• O teste de sistema pode ser encarado então como o teste de execução dos fluxos de um caso de uso expandido. • Se cada uma das operações de sistema (passos do caso de uso) estiverem já testadas e integradas corretamente, então deve-se verificar se o fluxo principal do caso de uso pode ser executado corretamente obtendo os resultados desejados, bem como os fluxos alternativos (Wazlawick, 2010). • É possível programar tais testes automaticamente, utilizando um módulo de programa que faz as chamadas diretamente na controladora de sistema e testa, desta forma, todas as condições de sucesso e fracasso dos passos do caso de uso, ou ainda utilizar a interface do sistema para executar tais operações manualmente.
Teste de Interface com Usuário • O teste de interface com usuário tem como objetivo verificar se a interface permite realizar as atividades previstas nos casos de uso de forma eficaz e eficiente. • Mesmo que as funções estejam corretamente implementadas, isso não quer dizer que a interface esteja. • Então, em geral, é necessário testá-la de forma objetiva e específica. • O teste de interface com usuário pode ainda verificar a conformidade das interfaces com normas ergonômicas que se apliquem.
Teste de Aceitação • O teste de aceitação é usualmente realizado pelo usuário, sobre a interface final do sistema. • Pode ser elaborado exatamente como o teste de sistema, mas a diferença é que é realizado pelo usuário final ou cliente e não pela equipe de desenvolvimento.
Teste de Ciclo de Negócio • O teste de ciclo de negócio é uma abordagem possível tanto ao teste de sistema quanto ao teste de aceitação e consiste em organizar uma sequência de testes de caso de uso que corresponda a um ciclo possível de negócio da empresa. • Assim, ao invés de testar os casos de uso isoladamente, o analista ou cliente vai testá-los no contexto de um ciclo de negócio. • Por exemplo, pode-se testar a sequência de compra de um item do fornecedor, seu registro de chegada em estoque, sua venda, entrega e respectivo pagamento. • São vários casos de uso relacionados no tempo, pois representam o ciclo de vida em um item em relação à empresa.
Teste de Performance, Stress e Carga • Tenha o sistema requisitos de desempenho ou não, o teste de performance pode ser importante, especialmente nas operações que serão realizadas com muita frequência ou de forma iterativa. • O teste consiste em executar a operação e mensurar seu tempo, avaliando se está dentro dos padrões definidos. • O teste de performance pode ainda ser levado a casos limite, quando então é identificado como teste de stress ou teste de carga.
• O teste de stress consiste em testar o sistema em uma condição limite de processamento ou quantidade de dados, para ver como o sistema se comporta. • Pode-se verificar também, no caso de sistemas concorrentes, o que acontece quando um número de usuários próximo ou acima do máximo gerenciável tenta utilizar o sistema. • Algumas vezes, efeitos colaterais indesejados podem surgir nessas situações, pelo que tais testes são considerados altamente desejáveis.
Testes de Segurança • Basicamente os três tipos de segurança devem ser testados: – Segurança de quem tem direito à informação de obte-la. – Segurança de que quem não tem direito à informação não possa obte-la. – Segurança contra a perda dos dados.
Teste de Recuperação de Falha • Quando um sistema tem requisitos suplementares referentes a tolerância ou recuperação de falhas, estes devem ser testados separadamente. • Basicamente, busca-se verificar se o sistema de fato atende aos requisitos especificados relacionados a esta questão. • Normalmente trata-se de situações referentes a: – – – –
Queda de energia no cliente ou no servidor. Discos corrompidos. Problemas de comunicação. Quaisquer outras condições que provoquem a terminação anormal do programa.
Teste de Configuração e Instalação • Basicamente busca-se nos testes de configuração e instalação verificar se o software não entra em conflito com outros sistemas eventualmente instalados em uma máquina, bem como se todas as informações e produtos para instalação estão disponíveis para os usuários instaladores.
Bibliografia • Myers, G. J., Sandler, C., Badgett, T., & Thomas, T. M. (2004). The Art of Software Testing. (2, Ed.) New Jersey: John Wiley & Sons. • Wazlawick, R. S. (2010). Análise e Projeto de Sistemas de Informação Orientados a Objetos (2 ed.). Rio de Janeiro, RJ, Brasil: Elsevier.