Buscar

Monografia de Teste de Software

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 29 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 29 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 29 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

FACULDADE DE TECNOLOGIA DE SÃO JOSÉ DOS CAMPOS
FATEC PROFESSOR Jessen Vidal
fabiana rodrigues rolim de oliveira
MONOGRAFIA DE TESTE DE SOFTWARE
São José dos Campos
2014 
fabiana rodrigues rolim de oliveira
MONOGRAFIA DE TESTE DE SOFTWARE
Trabalho de Pesquisa apresentado à Faculdade de Tecnologia São José dos Campos, como parte de avaliação para a Disciplina Teste de Software do curso Análise e Desenvolvimento de Sistemas.
Orientador: Prof. ME. Ronaldo 
Emerick Moreira
São José dos Campos
2014 
INTRODUÇÃO
	A Engenharia de Software cresceu bastante ao longo do tempo procurando assegurar critérios, técnicas, métodos e ferramentas para a produção de um bom software, em consequência disso, o aumento da utilização de sistemas baseados em computação em praticamente todas as áreas da atividade humana, o que provoca crescente demanda por produtividade e qualidade, tanto do ponto de vista dos produtos gerados como do ponto de vista do processo de produção.
A Engenharia de Software pode ser conceituada então como uma disciplina que aplica os princípios de engenharia com o objetivo de produzir software de alta qualidade e de baixo custo e através de um conjunto de etapas que envolvem o desenvolvimento e aplicação de métodos, técnicas e ferramentas, oferece meios para que tais objetivos possam ser alcançados.
O processo do desenvolvimento de um software envolve uma série de exercícios nas quais, apesar dos métodos, das técnicas e ferramentas empregadas, erros no produto ainda podem existir. As práticas associadas sob o nome de Garantia de Qualidade de Software têm sido introduzidas ao longo de todo processo de desenvolvimento, entre elas destacamos atividades de Verificação, Validação e Teste, que tem por objetivo minimizar a ocorrência de erros e riscos associados ao produto.
Dentro dessas técnicas de verificação e validação, existe a atividade de teste, é uma das mais utilizadas e importantes, constituindo-se em um dos elementos para fornecer evidências da confiabilidade do software complementando outros requisitos, por exemplo, o uso de revisões e de técnicas formais e rigorosas de especificação e de verificação.
A Prática de teste consiste em uma análise dinâmica do produto e é uma atividade de grande importância para a identificação e eliminação de problemas que persistem. Do ponto de vista de qualidade do processo, o teste sistemático é uma prática fundamental para o crescimento para o Nível Três do Modelo CMM do Software Engineering Institute. Ainda, o conjunto de informação oriundo da prática de teste é significativo para as atividades de depuração, manutenção e de confiabilidade de um Software. Reforça-se que a atividade de teste tem sido apontada como uma das mais onerosas no desenvolvimento de software, porém é de extrema importância para garantia de um software de qualidade.
1 – Tipos de Teste
Testes de software são divididos em alguns tipos de acordo com seu objetivo particular, segue aqui os principais tipos de teste e o que eles abordam resumidamente:
Teste de caixa branca e caixa preta: basicamente teste de caixa branca envolve o código e o de caixa-preta, não.
Teste de Instalação: Consiste em testar se o software instala como planejado em diferentes hardwares e em diferentes condições como pouco espaço de memória, interrupções de rede, interrupções na instalação, etc.
Teste de Configuração: Testa se o software funciona no hardware que ele será instalado.
Teste de Integridade: Testa a resistência do software a falhas, ou seja, a robustez.
Teste Funcional: Testa os requisitos funcionais, funções e os casos de uso (A aplicação faz o que deveria fazer?).
Teste de Integração: Testa se um ou mais componentes combinados funcionam de maneira adequada. Pode-se dizer que o teste de integração é composto por vários testes de unidade.
Teste de Segurança: Testa se o sistema e os dados são acessados de maneira segura apenas pelo usuário autorizado das ações.
Teste de Volume: Testa o comportamento do sistema operando com o volume “normal” de dados e transações envolvendo o banco de dados durante um longo período de tempo.
Teste de Unidade: testa um componente isolado ou classe do sistema.
Teste de Desempenho (Performance): Se divide em 3 tipos: Teste de carga, testa o software sob condições normais de uso, exemplo é o tempo de resposta, número de transações por minuto, usuários simultâneos; Teste de stress, testa o software sob condições extremas de uso. Grande volume de transações e usuários simultâneos. Picos excessivos de carga em curtos períodos de tempo e Teste de estabilidade testa se o sistema se mantém funcionando de maneira adequada após um período de uso.
Teste de Usabilidade: É um teste focado na experiência do usuário, consistência da interface, layout, acesso às funcionalidades, etc.
Teste de Regressão: É um reteste de um sistema ou componente para verificar se alguma modificação recente causou algum efeito indesejado e para certificar que o sistema ainda atende aos requisitos.
Teste de Manutenção: Testa a mudança de ambiente se não interferiu no funcionamento do sistema. Nesta monografia, abordaremos alguns dos principais testes.
2 – Técnica Funcional
Técnica funcional é conhecido também como teste de caixa preta pelo fato de tratar o software como se fosse uma caixa, cujo conteúdo é totalmente desconhecido e da qual só é possível visualizar o lado de fora, ou seja, os dados da entrada fornecidos e as respostas produzidas como saída. Nessa técnica é verificada funções do sistema sem se preocupar com os detalhes de sua implementação. 
O teste funcional envolve dois passos principais: Identificação e criação. O teste de identificação deve identificar as funções que o software deve realizar. O teste de criação consiste na criação de casos de testes capazes de verificar se essas funções estão sendo realizadas pelo software. As funções que o software deve possuir são identificadas a partir de sua especificação, assim uma especificação bem elaborada e de acordo com os requisitos solicitados pelo usuário é essencial para esse tipo de teste.
2.1- Exemplos de critérios para Teste Funcional
Particionamento em Classes de Equivalência: A partir dos dados de entrada identificadas na especificação, divide-se o domínio de entrada de um programa em classes de equivalência válidas e inválidas. Seleciona-se o menor número possível de casos de testes, baseando na conjectura que um elemento de uma dada classe seria uma representação da classe toda, sendo que para cada uma das classes inválidas deve ser gerado um caso de teste diferente. O uso de particionamento permite examinar os requisitos mais sistematicamente e restringir o número de casos de teste existentes. Alguns autores também consideram o domínio de saída do programa para estabelecer as classes de equivalência.
 Análise do Valor Limite: Faz um complemento ao Particionamento em Classes de Equivalência, os limites associados às condições da entrada são realizados de forma mais rigorosa, ao invés de selecionar qualquer elemento de uma classe, os casos de teste são escolhidos nas fronteiras das classes, pois nesses pontos se concentra um grande número de erros. O espaço de saída do programa também é particionado e são exigidos casos de teste que produzam resultados nos limites dessas classes de saída.
 Grafo de Causa-Efeito: Este critério estabelece requisitos de teste baseados nas possíveis combinações das condições de entrada. São levantadas, primeiramente, as possíveis condições de entrada que seriam as causas e as possíveis ações no caso os efeitos do programa, logo em seguida são construídos um grafo relacionando as causas e efeitos, levantados esse grafo é convertido em uma tabela de decisão a partir da qual são derivados os casos de teste.
Um dos problemas relacionado aos critérios funcionais é que muitas vezes a especificação do programa é feita de modo descritivo enão formal. Dessa maneira, os requisitos de teste derivados de tais especificações são também, de certa forma, imprecisos e informais. Como consequência, tem-se dificuldade em automatizar a aplicação de tais critérios, que ficam, em geral, restritos à aplicação manual. Por outro lado, para a aplicação desses critérios é essencial apenas que se identifiquem as entradas, a função a ser computada e a saída do programa, o que os tornam aplicáveis praticamente em todas fases de teste (unidade, integração e sistema). Quanto mais rigoroso o critério utilizado e se falhas não forem reveladas, maior a confiança no produto em desenvolvimento.
Em seguida temos um exemplo de Grafo de Causa-Efeito:
Figura 1.
3- Testes Baseados em Modelos
O teste baseado em modelos também é uma técnica de caixa-preta, pois os testes são baseados em um modelo e não no código fonte em si. Um modelo é uma especificação do sistema que descreve o que o sistema irá fazer. 
Essa modelagem permite que o conhecimento sobre o sistema seja capturado e reutilizado durante diversas partes do desenvolvimento e como grande parte da atividade de teste trata-se de buscar identificar o que o sistema deveria fazer, a modelagem pode ser de grande valor, pois depende também da forma como a descrição (a modelagem) é realizada, sendo necessário que ela seja rigorosa, clara e fiel ao sistema a ser desenvolvido.
A grande vantagem é o grande potencial de automação que a técnica agrega. Como o modelo é processado formalmente de acordo com sua especificação, onde temos as entradas e saídas esperadas e assim podemos gerar os casos de teste mecanicamente.
Muitos testadores usam um modelo, formulam mesmo que apenas em sua cabeça a forma como sabem ou acreditam saber que o sistema deve funcionar, mas usar somente esse tipo de modelo informal não é uma boa prática, pois dificulta a automatização dos testes, o ideal é que o testador conheça passo a passo da utilização do sistema. Um modelo é um instrumento muito valioso para a prática de teste de software, pois pode ser entendido como um oráculo que separa o comportamento esperado do comportamento errôneo e serve como base para a geração dos scripts e cenários de teste. A grande questão deste tipo de teste é saber o quanto podemos confiar no modelo, como ter certeza que ele está correto? Isso nos leva a ter que testar também o próprio modelo tanto quanto o sistema, para aumentar a confiabilidade de que ele está correto.
	O uso desse tipo de modelo para a geração de casos de teste ainda é uma área a ser muito explorada. As tarefas fundamentais em Testes baseados em Modelos são: entendimento do sistema sendo testada, escolha do modelo construção do modelo, geração dos testes, execução dos testes, coleta dos resultados dos testes e uso dos resultados dos testes.
3.1- Tipos de Modelos
Tabelas e ou Árvores de decisão: Apresentam conjuntos de condições de entrada e as ações resultantes.
Máquina de Estados Finitos: Mostram o comportamento do sistema em termos de estados e transições entre estados.
Exemplo de Máquina de Estados Finitos:
Figura 2.
Diagramas de casos de uso: Descrevem as funções realizadas por diferentes atores do sistema.
Diagramas de Atividades: Mostram as atividades que o sistema pode realizar e a relação de ordem entre elas.
Gramáticas: Descrevem a sintaxe de entrada. 
Statecharts (Gráficos do Estado): É uma extensão das Máquinas de Estados Finitos contendo hierarquia, concorrência, entre outros.
O modelo deve atender aos objetivos dos testes e de acordo com o Plano de Testes, o modelo deve ter uma sintaxe e sentido precisos, ou seja, modelo testável e tratável por ferramentas, modelo de comportamento formado por estados, transições e ações, o estado armazena informações sobre o passado, as transições indicam mudanças de estado e as ações representam atividades que podem ser realizadas em um determinado momento.
Figura 3.
4- Programação Concorrente
A grande maioria dos programas escritos são programas sequenciais, ou seja, para serem executados em um único computador com uma única CPU, o problema é dividido em uma série de instruções que são executadas uma após a outra, uma única instrução pode executar em um determinado instante de tempo. Existe apenas um fluxo de controle: fluxo de execução, linha de execução, thread no programa. Isso permite, por exemplo, que o programador realize uma execução imaginária de seu programa apontando com o dedo, a cada instante, o comando que está sendo executada naquele momento.
Já um programa concorrente, concurrent programming, onde concurrent significa "acontecendo ao mesmo tempo", pode ser visto como se tivesse vários fluxos de execução, para o programador realizar agora uma "execução imaginária", ele vai necessitar de vários dedos, um para cada fluxo de controle.
Em programação concorrente é definido o uso simultâneo de múltiplos recursos computacionais para resolver uma situação ou problema.
	Para ser executado, o problema é dividido em partes que podem ser executadas concorrentemente cada uma destas partes que é representada por uma série de instruções, sendo que as instruções de cada parte são executadas concorrentemente em diferentes CPUs.
É usado o termo programação paralela, pois vários programas/processos independentes executando em paralelo pelo computador. Um programa é considerado concorrente quando ele (o próprio programa, durante a sua execução) origina diferentes processos que irão interagir entre si para realizar alguma tarefa, ou seja, vários processos que cooperam para a realização de uma tarefa.
Em programação concorrente usa-se o que chamamos de Thread, uma forma de um processo dividir a si mesmo em duas ou mais tarefas que podem ser executadas concorrencialmente. O suporte a thread é fornecido pelo próprio sistema operacional, no caso da linha de execução ao nível do núcleo Kernel-Level Thread, ou implementada através de uma biblioteca de uma determinada linguagem. Um exemplo simples seria um jogo, que pode ser modelado com linhas de execução diferentes, sendo uma para desenho de imagem e outra para áudio. Neste caso, há um thread para tratar rotinas de desenho e outro thread para tratar áudio, no ponto de vista do usuário, a imagem é desenhada ao mesmo tempo em que o áudio é emitido pelos alto-falantes, porém, para sistemas com uma única CPU, cada linha de execução é processada por vez.
Trecho de um código usando Threads para programação concorrente:
Figura 4.
4.1- Ferramentas de Teste para Programas Concorrentes
Existem diversas ferramentas que automatizam a aplicação de técnicas e critérios em teste de programas sequenciais, também há para programação concorrente, são diversas ferramentas que apoiam, de alguma forma, o teste de programas concorrente de um modo geral. Algumas dessas ferramentas são brevemente descritas a seguir:
X-window Analysis and deBugging: Permite o monitoramento de programas PVM (Parallel Virtual Machine), por meio de instrumentação. Possui uma interface gráfica para o usuário (BEGUELIN,1993).
Visualize it: Permite também depuração e analise de desempenho de programas PVM (Parallel Virtual Machine). (ILMBERGER; THURMEL; WEIDEMANN, 1993).
XPVM: Adiciona uma interface gráfica ao console de comandos do Parallel Virtual Machine, permitindo o usuário interagir com a execução do programa, atua na tarefa de depurar e analisar desempenho (KOHL; GEIST; 1996).
Message passing Debugger: Realiza execução controlada e a depuração de programas Parallel Virtual Machine, porém principal objetivo é detectar condição de disputa nesse tipo de programa (DAMODARAN-KAMAL; FRANCIONI, 1994).
ParaGraph: Permite visualizar programas Message Passing Interface a fim de observar problemas relacionados a desempenho(HEATH, ETHERIDGE, 1991).
Umpire: Realiza a depuração e o monitoramento de programas Message Passing Interface (VETTER; SUPINSKI, 2000).
TDC Ada: Apoia a depuração de programas na linguagem Ada, usando a execução determinística (TAI; CARVER; OBAID, 1991).
Concurrency Analyser:Gera drivers para teste de unidade em classes de programas concorrentes escritos na linguagem Java. Utiliza um relógio externo para execução determinística (LONG, HOFFMAN, STROOPER, 2003).
XMPI: É uma API que fornece funcionalidade para registrar a execução de programas Message Passing Interface (trace), implementado especificamente para a distribuição LA-MPI, permite a visualização e monitoramento durante ou após a execução desses programas (OHIO,1997).
CHESS: Ferramenta que revela e reproduz defeitos do tipo Heisenbugs em programas concorrentes (MUSUVATHI; QADEERR; BALL, 2007). O termo Heisenbugs surgiu do “Principio da Incerteza de Heisenbug” (Física Quântica). Esses bugs são aqueles que desaparecem ou mudam de comportamento quando se tenta analisá-los. A ferramenta repetitivamente executa o programa garantindo que cada execução terá uma sequencia de sincronização diferente. Para isso faz uso de técnicas de verificação de modelos. Quando revela um defeito, a ferramenta pode reproduzir a sequencia de sincronização para ajudar na depuração.
Vyrd+: Faz o teste de unidade de programas Java buscando revelar bugs relacionados à concorrência. Para isso a ferramenta produz programas que testam as possíveis sobreposições de chamadas de métodos públicos da unidade (classe) em questão, possui módulos para instrumentação, annotation e monitor em tempo de execução (ELMAS; TASIRAN; QADDER, 2005).
Bandera: É um conjunto de ferramentas para analisar, transformar e visualizar programas Java. Tem como entrada o código fonte Java e um requisito de software formalizado em uma linguagem de especificação temporal própria, já na saída produz uma especificação e um modelo do programa no padrão de outras ferramentas (Spin, SMV E JPF) para executar a verificação de modelo (MOREIRA et al., 2004).
DELaware PArallel Software Aid: Uma das primeiras ferramentas de teste para análise de caminhos em programas concorrentes com memória compartilhada, possui um analisador estático que gera os possíveis caminhos para cobrir associações entre variáveis envolvidas na sincronização de tarefas (YANG; SOUTER; POLLOCK; 1998). 
ConTest: Ferramenta de teste para programas concorrentes implementados na linguagem Java utilizando o recurso de threads. O principal objetivo é revelar defeitos relativos à concorrência, além de dar suporte a critérios baseados em fluxo de controle e fluxo de dados. Suporta execução determinística parcial ou total. Todo processo de analise estática e instrumentação do programa é feito em nível de bytecode, portanto, não é necessário possuir o código fonte para testar um programa. Por fim, a ferramenta é capaz de gerar alguns relatórios, durante e após o teste, permitindo um acompanhamento mais próximo por parte do testador (EDELSTEIN et al., 2003).
RichTest: Ferramenta que implementa a proposta de teste de alcançabilidade proposto por Lei e Carver (2006). Foi implementada em Java e não requer nenhuma modificação na JVM para funcionar. O objetivo é cobrir todos os possíveis, e somente os possíveis caminhos e sequencias de sincronização de um programa multithread.
ValiPar: Ferramenta de teste para programas concorrentes com passagem de mensagem que suporta a aplicação dos critérios de teste definidos por Vergilio et al.,(2005). Dada a importância dessa ferramenta para esse trabalho ela será abordada em detalhes na subseção seguinte (SOUZA et al., 2005). 
STEPS: Permite o monitoramento através da analise simbólica de cenários de teste e execução controlada em programas paralelos implementados em Parallel Virtual Machine. Também dá suporte a um critério de teste estrutural baseado em fluxo de controle com base nas sincronizações, semelhante ao critério Todas-Arestas-S (KRAWCZYK et al., 1998).
Figura 5.
5- Teste de Integração
	O teste de integração é uma extensão lógica dos testes de unidade. Na sua forma mais simples, duas unidades que já tenham sido testados são combinadas em um componente e a interface entre eles é testada. Num cenário realístico, muitas unidades são combinadas em componentes, que são por sua vez agregados em partes cada vez maiores do programa.
Pode ter mais que um nível de teste de integração, que pode ser utilizado em objetos de teste de tamanho variado, por exemplo, teste de integração de componente testa interações entre componentes de software e é realizado após o teste de componente e teste de integração de sistemas, testando a interação entre diferentes sistemas e pode ser realizado após o teste de sistema. Neste caso a área de desenvolvimento pode controlar apenas um lado da interface, de forma que mudanças podem causar instabilidades. Processos de negócios implementados como fluxogramas podem envolver uma série de sistemas e problemas relacionados a múltiplas plataformas podem ser significativos. Quanto maior a estrutura da integração, maior a dificuldade de isolar falhas para sistemas específicos ou componentes, fato que pode representar um aumento de risco. Estratégias sistemáticas de integração podem ser baseadas na arquitetura do sistema que são: top-down e bottom-up, funções, sequências de processamento de transações, entre outros aspectos do sistema ou componente. Visando reduzir o risco de encontrar defeitos tardiamente, a integração deve ser de preferência incremental e não “big bang”. 
O teste de integração então é uma atividade sistemática aplicada durante a integração da estrutura do programa visando a descobrir erros associados às interfaces entre os módulos; o objetivo é, a partir dos módulos testados no nível de unidade, construir a estrutura de programa que foi determinada pelo projeto. O teste de sistema, realizado após a integração do sistema, visa a identificar erros de funções e características de desempenho que não estejam de acordo com sua especificação.
5.1- Exemplo de Teste de Integração
	Aqui será mostrado como é feito um teste de integração num sistema de administração de medicamentos. O que vamos testar aqui basicamente é a inserção de um paciente e sua exclusão. O importante nesta exemplificação não é se ate aos detalhes do que está dentro da classe PacienteRN ou o que está na classe DadosPaciente mas sim como é feita a sequência dos testes e porque ela foi realizada desta forma.
Inicialmente no teste acima inserimos um paciente no sistema, primeiramente recebe os dados do paciente através do método “inclui” que já recebe uma classe com gets e sets com os dados do paciente já previamente configurado e armazena no banco de dados o paciente que é feita pela camada de acesso a dados depois que o método inclui() chamá-la. Começando os testes passando dados pela camada de negócio, no entanto, isso poderia ser feito ainda uma camada anterior, como na camada de Bean de Interface, passando dados para essa camada que chamaria a camada de negócio que, por sua vez, chamaria a camada de Banco de dados.
No código exemplificado testa-se se o paciente realmente foi inserido no Banco de Dados. Uma asserção é realizada para verificar se a inclusão do paciente foi realizada com sucesso. É feita uma inclusão e espera-se que nenhum erro mais complexo tenha ocorrido, como um null pointer ou alguma quebra de integridade ou qualquer falha que impeça a inclusão. Porém, se a consulta não resultar nos dados esperados, ocorre um erro em que não foi encontrado este paciente no Banco de Dados, portanto não foi incluído corretamente por algum motivo não aparente na qual devido alguma situação não retornou uma falha.
Veja no código abaixo:
Figura 6.
6- Teste de Classe
	Visto o que é um teste de integração, o teste de classe propõe testar a integração de métodos e atributos de uma classe. Um Aspecto importante a verificar é se restrições na ordem de instanciar suas operações muitas vezes implícitas estão sendo satisfatórias.
Segundo Pressman, sequência mínima para um teste é aquele que exercita o histórico de vida comportamental mínima de um objeto da classe. Além da sequência mínima, há muitas combinações possíveis de invocação de operações.
A técnicade caixa branca, chamada também de teste estrutural ou orientado à lógica avalia o comportamento interno do componente de software e trabalha diretamente sobre o código fonte do componente de software para avaliar aspectos tais como: teste de condição, teste de fluxo de dados, teste de ciclos, teste de caminhos lógicos, códigos nunca executados.
Os aspectos avaliados nesta técnica de teste dependem da complexidade e da tecnologia que determinam a construção do componente de software, cabendo, portanto avaliação de mais aspectos que os citados anteriormente. O testador tem acesso ao código fonte da aplicação e pode construir códigos para efetuar a ligação de bibliotecas e de componentes. Este tipo de teste é desenvolvido analisando o código fonte e elaborando casos de teste que cubram todas as possibilidades do componente de software. Dessa maneira, todas as variações relevantes originadas por estruturas de condições são testadas.
Um bom exemplo desta técnica é o uso da ferramenta livre chamada JUnit para desenvolvimento de classes de testes, com o objetivo de testar métodos desenvolvidos ou classes de teste em Linguagem Java. Enquadram-se também nessa técnica testes manuais ou testes efetuados com apoio de ferramentas para verificação de aderência a boas práticas de codificação reconhecidas pelo mercado de Software. Aderindo a padrões e boas práticas visam-se principalmente à diminuição da possibilidade de erros de codificação e a busca de utilização de comandos que gerem o melhor desempenho de execução.
Apesar de vários desenvolvedores alegarem que não há muitos ganhos perceptíveis com essa técnica de teste aplicada sobre unidades de software, deve-se lembrar de que, no ambiente produtivo, cada programa pode vir a ser executados milhões de vezes em intervalos de tempo curtos, é na realidade de produção que a soma dos aparentes pequenos tempos de execução e consumo de memória de cada programa poderá levar o software a deixar de atender aos objetivos esperados.
O teste de caixa branca é recomendado para as fases de teste de unidade e teste de integração, cuja responsabilidade principal fica a cargo dos desenvolvedores do software, que por sua vez conhecem bem o código fonte produzido.
6.1-Exemplo de Teste de Classe
Figura 8.
Qual a sequência de testes mínimos a ser feita? Que outros casos de teste são possíveis?
Sequência Mínima: Abrir – Estabelecer Limite – Depositar – Retirar – Encerrar.
Outros casos de teste possíveis: Infinitos.
Sequências Válidas:
Abrir → Estabelecer Limite →Depositar →(Obter Limite | Estabelecer Limite | Depositar | Retirar | Obter Saldo | Obter Extrato) n →Retirar →Encerrar.
Sequências Inválidas:
Estabelecer Limite → Depositar → Retirar → Encerrar.
Abrir → Depositar → Retirar → Encerrar.
Abrir → Estabelecer Limite → Retirar → Encerrar.
Abrir → Estabelecer Limite → Depositar → Encerrar.
Abrir → Estabelecer Limite → Depositar → Retirar → Encerrar → Depositar.
Necessidade de reduzir o número de casos de teste
Teste Aleatório ou Randômico
Casos de teste para diferentes sequências (normalmente válidas) de operações são gerados aleatoriamente.
Teste de Partição no Nível de Classe
Análogo ao critério Particionamento de Equivalência.
Casos de teste são projetados para exercitar cada categoria (válida ou inválida).
Alguns critérios:
Partição Baseada em Estado
Partição Baseada em Atributo
Partição Baseada em Categoria
7- Mutações e Efeitos Colaterais em Teste de Software
Umas das ideias principais do teste de mutação foi proposta por volta de 1978 por DeMillo que propôs uma técnica chamada de Hipótese do programador competente (Competent programmer hipothesis), sendo que o critério analise de mutante surgiu em meados da década de 70 na Yale University e Georgia Institute of technology baseado em pesquisas de métodos clássicos de detecção de erros lógicos em circuitos digitais. 
Baseado nessa premissa de Hipótese do programador competente assume-se que programadores experientes escrevem códigos fontes corretos e/ou muito próximos do que é correto, permitindo assim que pequenas alterações no código sejam realizadas para que apesar de não houver erro na sintaxe alteram a sentido do programa. 
7.1- Teste de Mutação
O Teste de Mutação é usado, frequentemente, como modelo de defeitos, permitindo avaliar a eficácia em detectar defeitos de conjuntos de teste gerados por outros critérios de teste (Andrews et al. 2005), ou seja, como é uma técnica baseada em defeitos, cuja vantagem diante das técnicas de teste funcional e estrutural é a possibilidade de se estabelecer uma relação direta entre um subdomínio e a possibilidade de se encontrar defeitos. Apesar dessa relação direta, ainda podem existir casos de testes correspondentes que levem ou não o programa a falhar, como consequência, um defeito pode não ser revelado. Com o uso dessa técnica utilizam-se os defeitos típicos do processo de desenvolvimento cometidos por desenvolvedores, onde o objetivo é injetar defeitos e verificar se os casos de teste são capazes de descobri-los. Uma das abordagens é a aplicação do teste de mutação.
O teste de mutação necessita de criação de vários programas (no caso mutante) derivados a partir de um programa original teoricamente correto. Segundo Howden, a definição de correção pode ser dada por: "Um programa P é correto em relação a uma função F se P computa F". Para provar a correção é criado então um conjunto de casos de testes confiável, sendo da seguinte forma: "Um conjunto de teste T confiável para um programa P e uma função F, dada a existência coincidente de P e F em T e se P computa F, caso contrário, deve haver um ponto t tal que F(t) seja ≠ P(t)".
Os passos para execução podem ser divididos em:
Execução de um conjunto de testes T no programa original P, se ocorrer uma falha o teste termina.
São gerados os programas mutantes com operadores de mutação a partir de um P correto. Os mutantes são executados com o mesmo conjunto de testes T.
Através de uma análise, é possível quantificar os mutantes vivos, mortos, equivalentes e reveladores dos defeitos.
Os mutantes mortos possuem os resultados dos testes diferentes de P e os vivos devem ser equivalentes a P, se não forem, podem ajudar a expor a fraqueza dos casos de teste. Se para algum caso de teste t tal que P(t) ≠ M(t), pode-se concluir que P(t) não está de acordo com a especificação, neste caso a presença de um defeito pode ter sido revelada. Uma forma de medir a adequação de T em relação ao teste de mutação é o escore de mutação:
Figura 9.
DM(P,T) - Número de mutantes mortos por T; M(P) – Total de mutantes gerados; EM(P) – Número de mutantes equivalentes a P;
A principal desvantagem da análise de mutantes é que são gerados muitos mutantes, consequentemente, estes precisam ser compilados e executados, assim há também a necessidade de se conhecer o código-fonte do programa. Apesar das desvantagens, é um dos critérios mais eficazes para se encontrar defeitos.
Figura 10.
7.2- Efeitos Colaterais em Teste de Software
	Um dos efeitos colaterais da automatização de teste foi à aproximação da área de Teste com a área de desenvolvimento onde ela ocorreu fisicamente com os testadores sentando mais próximos dos desenvolvedores, para facilitar a comunicação quando é preciso tirar dúvidas sobre códigos, teste, em geral programação. Mas ela ocorreu mais ainda na formação do Tester, uma vez que programar não é mais uma arte usada apenas para construir, ela também é usada para “quebrar”, pra verificar e pra dá segurança para mudar. Com isso dois contextos que de forma errada muitas vezes eram separados, hoje estão mais próximos. Afinal, desenvolvimento e testes sempre existiram pelo mesmo propósito, entregar software de qualidade.
Independente da metodologia de desenvolvimento, um dos problemas mais recorrentes no desenvolvimento de software é a alta incidência de defeitos. Softwares defeituosos podem causar:
Lentidão no Desenvolvimento: Quando é relatada uma falha/problema,o desenvolvedor gasta muito tempo depurando (debugging) o código para descobrir onde está o defeito e depois para corrigi-lo. Além disso, nem sempre o desenvolvedor que escreveu a funcionalidade é responsável pela correção dos seus defeitos. E para piorar, muitas vezes as empresas atribuem desenvolvedores inexperientes para corrigir os defeitos.
Efeitos Colaterais: A correção de um defeito insere como efeito colateral outros defeitos. Isso acontece em função de diversos fatores, como por exemplo, a falta de experiência do desenvolvedor, falta de arquitetura no software, falta de organização nos processos de trabalho da empresa, prazos muito apertados, falta de atenção do desenvolvedor em função de exaustão por ter que trabalhar muitas noites e finais de semana seguidos, entre outros.
Custos altos: Defeitos encontrados em produção tem um custo de correção cem vezes ou até mesmo mil vezes mais alto do que os defeitos encontrados durante o ciclo de desenvolvimento, isso sem contar os custos associados à insatisfação dos clientes.
Teste de software é mais do que uma simples tarefa, na verdade, é a base de sustentação que permite a implementação de muitos princípios de desenvolvimento ágil, como por exemplo: a entrega contínua de software de valor, os testes é a única forma de demonstrar se o software atende as necessidades do cliente (software de valor); aceitar mudanças, testes dão confiança ao time para realizar mudanças sem medo de causar efeitos colaterais e instabilidade no software; envolvimento de pessoas relacionadas a negócios e desenvolvimento, testes são descritos em uma linguagem comum a todos os membros do time. Dessa forma, todo o time compartilha o mesmo entendimento do que deve ser feito, as restrições e as definições de "Pronto"; software funcional é a medida de progresso, os testes executados frequentemente demonstram o progresso no desenvolvimento de novas funcionalidades, assim como, se o software ainda funciona (não foram introduzidos defeitos); excelência técnica, bom design e simplicidade, os testes escritos antes do código induzem o desenvolvedor a pensar com mais profundidade na implementação da funcionalidade, tornando dessa forma, o código mais simples e com melhor design; times motivados e confiantes, testes executados com sucesso aumentam a motivação (estamos realizando nosso trabalho corretamente) e confiança do time (estamos tomando as decisões certas); o time reflete em como ficarem mais efetivo, testes demonstram falhas tanto no código quando no processo de trabalho (e atitudes do time), com base nas lições aprendidas durante a correção da falha, o time ajusta e aperfeiçoa seu comportamento de acordo.
7.3- Testes sob a perspectiva do desenvolvedor
O desenvolvedor apenas escreve código nos métodos tradicionais, já nos métodos ágeis, por exemplo, o desenvolvedor também é responsável pelos testes, no entanto, os testes do desenvolvedor tem o objetivo de prevenir e detectar os defeitos na perspectiva do código, ou seja, o desenvolvedor deve garantir a qualidade de cada unidade do código individualmente. 
Uma unidade deve ser entendida como o pequeno trecho de código possível de um software que pode ser testado, podendo ser uma função ou procedimento em linguagens de programação procedurais ou métodos de classes em linguagens orientadas a objetos.
Para demonstrar se uma unidade atende os seus requisitos, o desenvolvedor escreve testes unitários (Unit Tests). Para tal tarefa, o desenvolvedor escreve fragmentos de código com o único objetivo de executar isoladamente uma unidade e observar o seu comportamento e os resultados produzidos.
Esses testes unitários são normalmente escritos usando o mesmo ambiente e a mesma linguagem de programação utilizada para a implementação da unidade que está sendo testada. Em linhas gerais, os desenvolvedores escrevem testes unitários usando bibliotecas especializadas que fornecem um ambiente padronizado, mecanismos para apresentar os resultados da execução dos testes, etc. Dentre as bibliotecas mais conhecidas, podemos destacar:
JUnit: (http://www.junit.org/);
NUnit: (http://www.nunit.org/);
DUnit: (http://dunit.sourceforge.net/);
CPPTest: (http://cpptest.sourceforge.net/);
Embora os testes unitários não impeçam a ocorrência de defeitos, eles representam um mecanismo muito eficiente para detectá-los rapidamente, o que reduz o tempo gasto em depuração e correção. A adoção de testes unitários traz vários benefícios, como por exemplo:
Os testes unitários revelam os defeitos tão logo eles são introduzidos no software, o que evita a replicação do defeito em outras áreas do software;
Testes unitários apontam onde e como ocorre um defeito, reduzindo o tempo gasto em depuração;
Testes unitários são uma rede de segurança que dá confiança ao desenvolvedor realizar modificações e otimizações no software (Refactoring) sem medo de efeitos colaterais;
Testes unitários, ao contrário da documentação escrita, não perde o sincronismo com o código e é considerada uma forma mais leve de documentação, entre outros.
Representação do Esquema para detecção de defeito:
 
Figura 11.
8- Programação Orientada a Teste
Programação Orientada a Testes ou Test-Driven Development (TDD) é uma maneira diferente de escrever um software. A evolução do código é aos poucos, conforme o programador vai explorando o problema com o uso de testes automatizados escritos antes da solução sequer existir. Algumas vantagens desta abordagem são:
Simplicidade: Como a solução vai surgindo aos poucos, a tendência é que não se perca tempo com aquilo que não tem certeza que será usado em seguida.
Confiabilidade no código: O sistema funciona de uma determinada maneira porque existem testes que foram utilizados durante sua criação e validam o que foi criado e se ainda assim algum erro surgir, um novo teste é gerado para reproduzi-lo e garantir que depois de solucionado ele não irá se repetir.
Auxilia na documentação: Os testes quando bem definidos são mais simples de ler que o código e, embora nem sempre sirvam como uma especificação para o usuário final, eles são uma fonte eficiente para entender o que o software faz, além disso, esta documentação sempre estará atualizada com a aplicação.
Facilita os Refactorings: Quanto mais testes existirem no sistema, maior é a segurança para fazer refactorings. Um erro causado por algum refactoring dificilmente vai passar despercebido quando um ou mais testes falharem após a mudança.
Em programação orientado a teste, um teste é um pedaço de software, a diferença entre teste e o código que está sendo produzido é que os testes têm 2 funções principais:
De especificação, ou seja, definir uma regra que seu software deve obedecer.
De validação, ou seja, verificar que a regra é obedecida pelo software.
Geralmente os testes são criados com algum framework do tipo xUnit, jUnit, nUnit Test::Unit etc., mas também podem ser feitos num nível de funcionalidades. Estas ferramentas servem basicamente para organizar os testes e facilitar na criação das verificações.
O processo de criação de programação orientado a testes é simples, primeiramente: Elabore um teste com o propósito de que ele falhe, pense no que o código deve fazer, descreva o contexto e defina quais são as verificações que precisam ser feitas. Não há um limite no número de testes, então quanto menos coisa cada teste descrever ou verificar, melhor. No início também não é preciso se preocupar se a classe ou método ainda não exista. Devemos pensar primeiro no teste e só depois que este estiver pronto crie o esqueleto de código necessário para que ele compile e falhe ao rodar.
Faça o teste passar. Chegamos a um ponto importante: escreva o mínimo de código para que o teste passe e faça apenas o teste passar, mesmo que tenha certeza que o código deve fazer mais coisas, fazer os testes passarem deve ser a única preocupação nesse estágio.
Refatore, uma vez que o teste passou, verifique o que no código pode ser melhorado. Geralmente para um teste passar é preciso inserirduplicação através de constantes (técnica conhecida como Fake It). Agora é a hora de melhorar o código e remover as duplicações, lembrando que os testes devem continuar passando.
Estes três passos são repetidos até que não se consiga pensar em novos testes, o que indica que a funcionalidade está pronta.
9- Aplicação de teste de software em Agile
	Metodologias ágeis existem há alguns anos, desde a década de 80 mais precisamente, mas algumas informações passam por distorções, fato que dificultou no início a utilização dessas metodologias. Em consequência, desenvolvedores passaram a entender a metodologia ágil como algo que tudo se pode, ou seja, podemos desenvolver sem documentação, sem padrão e sem cuidado. Isto não é verdade, as metodologias ágeis podem trazer sucesso ao projeto, e são utilizadas inclusive na indústria. Como exemplo temos o modelo de produção enxuta da Toyota, que é uma forma ágil de produção e que evita o desperdício. Apesar das metodologias já existirem, foi em 2001 que um grupo formado por Kent Beck e mais dezesseis renomados desenvolvedores assinou o chamado Manifesto para o desenvolvimento ágil de software e o grupo foi batizado de aliança dos ágeis.
Devido a grande preocupação das empresas é como ser ágil sem interferir na qualidade final do produto. Entregar rápido, com valor e ao mesmo tempo de forma que os produtos atendam as necessidades do cliente e não apresentem problemas no ambiente de produção.
Glenford Myers em seu livro “The Art of Software Testing”, dizia que quanto mais cedo descobrimos e corrigimos o erro, menor é o seu custo para o projeto. Em meio a esse contexto de agilidade fica a pergunta: como ser ágil e ao mesmo tempo testar?
Já que teste demanda tempo e custo e de início parece atrasar entregas e superficialmente parece ir contra tudo que se conhece de Agile.
O Agile Testing é a resposta esperada para essa preocupação. Com todas essas mudanças de mercado, o conceito de ser “tester” e a forma de testar os produtos tem sido “refatorada”.
O Agile Testing segue todos os princípios ágeis, inclusive a multidisciplinaridade da equipe tendo um agile tester para cada equipe de desenvolvimento, ressaltando sempre que a colaboração deve prevalecer e que o fato de o time ter um tester não significa que a responsabilidade sobre a qualidade dos produtos é somente dele, todo time deve colaborar.
Figura 12.
Figura 13.
CONCLUSÃO
	Neste presente trabalho abordou alguns dos principais tipos de teste que são estudados na Disciplina de Teste de Software, ressaltando suas principais peculiaridades e exemplos para explicar o funcionamento de cada uma das técnicas em questão.
	O teste de software não é algo novo, mas, mesmo assim, empresas preferem ainda desenvolver sistemas sem uma metodologia com base em qualidade, podemos exemplificar da seguinte maneira: quando é fabricado um brinquedo, este também passa por testes, para saber que a tinta não é prejudicial às crianças, que alguma peça não vá sair na boca de uma criança e assim por diante, pois todos nós queremos produtos de qualidade, então, por que isso não se aplicaria um Software?
	O problema na verdade de não se testar o software, é que custa caro, mas Pressman já apresentou em seu Livro de Engenharia de Software que o custo do defeito é progressivo, ou seja, encontrar o defeito na fase de engenharia de requisitos custa um enquanto encontrar o defeito durante a fase de uso custa cem vezes mais, então utilizar o recurso de teste, reduz custo e não o contrario.
Portanto, a atividade de teste é fundamental no processo de desenvolvimento de um bom software, pois é possível detectar falhas, erros e defeitos antes da entrega do produto, garantindo ao usuário mais confiança, ou seja, o sistema é resistente a falhas durante a execução, garantia de uma boa funcionalidade: o sistema se comporta conforme o esperado e definido em seus requisitos (requisitos do usuário) e garantia de desempenho: o sistema tem um tempo de resposta adequado e aceitável, mas acima de tudo é garantia de um software de qualidade.
Referências
BARBOSA, ELLEN. Introdução a Teste de Software. Universidade de São Paulo — ICMC/USP. Disponível em: www.les.inf.puc-rio.br/wiki/images/a/a8/Testes.pdf Acesso em: 07/11/2014.
CRISTIANO, CAETANO. Testes Ágeis. Disponível em: http://www.qualister.com.br/blog/testes-ageis Acesso em: 28/10/2014.
COMISSÃO INTERNACIONAL PARA QUALIFICAÇÃO DE TESTE DE SOFTWARE. Base de Conhecimento para Certificação em Teste. Versão 2005 Disponível em: https://www.passeidireto.com/arquivo/979629/livro-base-de-conhecimento-em-teste-de-software Acesso em 06/11/2014.
IGNATOWICZ, EDER. Desenvolvimento Ágil Orientado a Teste. Disponível em: http://pt.slideshare.net/ederig/desenvolvimento-agil-orientado-a-testes-10466106 Acesso em: 29/10/2014.
MELNIK, GRIGORI. MESZAROS, GERARD. BACH, JON. Acceptance Test Engineering Guide, Volume I: Thinking. How to Decide IF Software is Ready for You and Your Costumers. Disponível em: http://testingguidance.codeplex.com/releases/view/35058 Acesso em: 03/11/2014.
PALMA, FERNANDO. Teste de software. Disponível em: http://testesdesoftware.blogspot.com.br/ Acesso em: 27/10/2014.
PERES, PAULO. Testes de Software, uma visão Geral. Disponível em: http://pt.slideshare.net/pauloperes2009/testes-de-software-uma-viso-geral Acesso em: 29/10/2014.
SILVA, JAGUARACI. Estudo, pesquisa e inovação. Disponível em: http://jaguaracisilva.blogspot.com.br/2013/08/teste-de-mutacao.html
Acesso em: 28/10/2014.

Continue navegando