• Autora

    Pós-Graduando em Especialização em Informática – Ênfase Análise de Sistemas pela UFMG, Bacharel em Sistemas de Informação (2006) pela Faculdades Pitágoras (Campus Fadom), técnica em Informática (2002) e em Contabilidade (1998). Atualmente Analista de Suporte Júnior III.

  • Direitos Autorais

    Alguns dos materiais (artigos, pdf’s, link’s) disponíveis ou utilizados na edição desse Blog, foram retirados de páginas da internet. Se acaso, algum desses itens for protegido por direitos autorais, queira o detentor do mesmo, me comunicar por email e o material será imediatamente retirado ou darei os devidos créditos!
  • Categorias

  • Arquivos

  • Análise de Sistemas

    • 14,326 hits

Teste de Sw Orientado a Objetos

Algumas facilidades em relação:

• interfaces de classes e métodos bem definidas e explícitas;

• número reduzido de parâmetros implica um número menor de casos de teste para sua cobertura;

• a herança sugere uma maneira natural de reutilizar casos de teste.

Desvantagens:

• encapsulamento de informações dificulta a avaliação da correção da classe;

• múltiplos pontos de entrada (métodos) de uma classe dificultam o gerenciamento do teste;

• polimorfismo e a ligação dinâmica expandem as possíveis interações entre objetos.

No teste de software OO, com à explícita separação entre especificação

e implementação da classe, casos de teste funcional podem ser gerados separadamente de casos de teste que requeiram conhecimento

do código da aplicação (teste estrutural).

Todas as classes podem ser testadas, mas não todos os objetos. O gerenciamento de mensagens entre objetos é similar ao de chamadas de rotinas, porém, a troca de mensagens ocorre mais freqüentemente. Algumas definições e declarações são reutilizadas em vários níveis da árvore de

herança, interagindo com novas definições e declarações.

Através da especificação, deve-se escrever um plano de teste.

Este deve especificar a extensão do teste como:

Ferramentas a serem utilizadas,

Critérios de teste,

Estimativa do tempo necessário para o teste,

Descrição dos casos de teste e dados de teste associados.

Seqüência de seleção proposta para a obtenção dos casos de teste:

• desenvolvimento de um conjunto de teste funcional que cubra a

especificação completa da classe;

• desenvolvimento de casos de teste baseados em estados até que

todas as transições no modelo dinâmico sejam cobertas;

• utilização de uma ferramenta de cobertura de teste;

• desenvolvimento de casos de teste estruturais adicionais para a

cobertura de cada linha de código;

• desenvolvimento de casos de teste para testar as interações entre

métodos de uma mesma classe;

• desenvolvimento de casos de teste para a cobertura das interações

entre objetos da classe sendo testada e de outras classes.

Testes de Estado

O comportamento de uma classe é definido por determinado conjunto de valores encapsulados, que a classe possui em determinado momento. O comportamento da classe é controlado por valores encapsulados, seqüências de mensagens, ou ambos.

Objetivo:

Testar o sistema OO sem tentar todas as combinações possíveis. Sendo que este teste deve ser suficientemente confiável a fim de selecionar combinações que testem comportamentos representativos do conjunto original.

A estratégia de teste FREE (Flattened Regular Expression) é baseada

no modelo dinâmico (máquina de estados finitos) apresentado pelo Diagrama de Estados da UML.

Conhecido também como um teste de cobertura por pares de função.

Estado definido como sendo um subconjunto do conjunto de todas as

combinações possíveis dos valores de atributos da classe.

Para as atividades de projeto e de teste, pode-se definir um estado como um subconjunto de valores que podem ser combinados, e que compartilham

alguma propriedade de interesse.

Exemplo: o saldo de uma conta-corrente pode ser considerado como um atributo base para a realização do teste de estados. Caso qualquer variação no saldo seja considerada uma mudança de estado, a máquina de estados terá um tamanho tal que será praticamente impossível monitorar e analisar

qualquer caminho executado.

Para reduzir tal complexidade, e tornar a representação de máquina de estados mais adequada ao teste, neste exemplo, poderiam ser selecionados apenas os estados “conta negativa” (caso o saldo seja menor do que zero), “conta zerada” (caso o saldo seja igual a zero) e “conta positiva” (caso o saldo seja maior do que zero). Ou seja, a semântica da aplicação deve ser considerada, o que consiste em uma das maiores dificuldades do teste

baseado em estados.

Os estados podem ser definidos por expressões booleanas. Por exemplo,

o estado “conta positiva” pode ser definido como: saldo >0.

As expressões de pré-condições e de pós-condições definem o

contrato da classe.

As classes servidor (as que recebem as mensagens) devem definir pré-condições para que uma mensagem seja aceita.

As classes cliente (as que enviam as mensagens) devem definir pós-condições para definir os resultados.

Uma pós-condição também define o estado obtido pela ativação do

método. Existindo, no mínimo, um estado para cada pós-condição de uma

classe. Se houver n operadores lógicos ou na expressão de pós-condição,

então o método pode computar n+1 estados.

A partir do diagrama de estados, é gerada uma árvore de

transição. O estado inicial da máquina transforma na raiz da árvore.

Para cada transição, um arco é desenhado do nodo origem da transição para o nodo que representa o estado resultante.

Este procedimento é repetido para cada nodo de estado resultante,

até que o estado resultante já apareça na árvore como um nodo anterior

ou o nodo resultante é um estado final.

Em seguida transcrever as seqüências de teste de transições a partir da árvore.

Um caso de teste consiste em cada arco ou cada seqüência de arcos orientada em uma mesma direção.

O plano de teste é completado identificando-se valores de parâmetros

de métodos, estados esperados e exceções.

Execução do teste inicia-se o objeto com o estado inicial, aplicando a seqüência e comparando o estado resultante com o estado esperado.

Erros encontrados: transições perdidas, transições incorretas, ações de saída incorretas e estados incorretos.

Este método de teste pode ser mais bem testado com ferramentas de teste que permitam a utilização de assertivas no meio do código, que podem representar pré e pós-condições, verificadas durante a execução do código instrumentado.

Testes de Integração Aplicados a Software Orientado a

Objetos

Ordem dos testes

Perguntar: qual é a classe que, se testada inicialmente, facilitará o teste de outras classes?

Uma série de heurísticas propostas em Lima e Travassos (2004) podem ser utilizadas para criar critérios de precedência:

• Quanto à Herança

a subclasse somente será testada após as superclasses terem sido

testadas.

• Quanto à assinatura dos métodos de uma classe testa-se primeiramente a classe servidora e depois a classe cliente.

• Quanto à agregação

a classe parte na agregação terá precedência para teste de integração

sobre a classe que representa o todo.

• Quanto à navegabilidade

será utilizada a navegabilidade para definir critério de precedência

quando a ligação entre as duas classes ocorrer através da associação.

• Quanto à classes de Associação

as classes que deram origem à classe de associação terão precedência

de teste de integração sobre a classe derivada.

• Quanto à Dependência

a classe cliente terá precedência para ser testada.

Fator de Influência (FI)

Para aplicar estas heurísticas podemos utilizar um dispositivo para

calcular o chamado “Fator de Influência” de uma classe, calcular

um índice que indique de que forma uma classe influencia ou é influenciada por outras classes.

Assim, pára o exemplo abaixo, podemos criar a seguinte tabela, definindo

o Fator de Influência de uma classe como sendo o Número de classes que podem se integrar à ela, depois que ela for testada.

Anúncios

Revisão de Software

Uma forma efetiva para melhorar a Qualidade de Software. Devendo ser aplicadas em vários pontos durante o desenvolvimento do software. Pode ser vista como uma maneira de usar a diversidade de um grupo de pessoas para:

  • Apontar melhorias necessárias ao produto;
  • Confirmar as partes de um produto em que uma melhoria não é desejada ou não é necessária;
  • Realizar um trabalho técnico com uma qualidade mais uniforme de forma a tornar este trabalho técnico mais administrável.

Tipos de Revisões

Podemos identificar diversos tipos de revisão (Rodrigues, 2001; Paula Filho, 2003):

• Discussão de um problema técnico na hora do café. Informal, mas às vezes efetivo;

• Apresentação do projeto de software para uma audiência de clientes, administradores e pessoal técnico.

•Revisão de Apresentação (walktrought). O autor apresenta o material em ordem lógica, sem limite de tempo a um grupo que verifica o material na medida em que ele vai sendo apresentado.

.• Revisões Técnicas (thecnical review). Inclui avaliações técnicas de artefatos específicos, realizadas em pequenos grupos, para verificar se eles estão conformes com padrões e especificações e se, eventuais modificações nos artefatos foram efetuados de maneira correta.

•Inspeção ou Revisão Técnica Formal (Formal technical review). Técnica mais formal que a revisão técnica, com objetivo principal a identificação e a remoção de defeitos. Origatório: geração de uma lista de defeitos com classificação e a requisição de ações de correção.

Inspeções

Atividade de Garantia de Qualidade de Software e tem por objetivo:

1) Descobrir erros de função, lógica ou implementação em qualquer representação do software.

2) Verificar se o software que se encontra em revisão atende a seus requisitos.

3) Garantir que o software tenha sido representado de acordo com padrões pré-definidos.

4) Obter um software que seja desenvolvido uniformemente.

5) Tornar os projetos mais administráveis.

6) espaço de treinamento possibilitando que os engenheiros juniores observem diferentes abordagens a análise, projeto e implementação de software.

7) promover backup e continuidade. Várias pessoas se familiarizam com partes do software que de outro modo poderiam não conhecer.

Uma Revisão Técnica Formal é conduzida em uma reunião e será bem sucedida se for planejada, controlada e cuidada. Independentemente do formato de Revisão Técnica, toda Reunião de Revisão deve estar de acordo com:

1) Envolver de 3 a 5 pessoas na revisão.

2) Deve haver uma preparação para a reunião (essa preparação não deve exigir mais de 2 horas de trabalho de cada pessoa).

3) A Reunião de Revisão deve durar menos de 2 horas. A Inspeção focaliza uma parte específica (pequena) do software – aquela com maior probabilidade de descoberta de erros.

Sucesso na Inspeção

Muitos defeitos diferentes podem ser descobertos numa simples inspeção. Sendo que no teste, um defeito, pode mascarar outro e, portanto várias execuções são necessárias. O domínio do reuso e os conhecimentos de programação permitem aos revisores já terem visto os tipos de erros que normalmente aparecem.

Inspeções de programas

Podemos usar um enfoque formalizado de revisão de documentos ou de programas. O propósito explícito deve ser o da DETEÇÃO (não a correção). Defeitos podem ser erros lógicos, isto é, anomalias no código que podem indicar uma condição errônea (ex. variável não instanciada) ou a não aderência a padrões.

Checklist de erros comuns devem ser usadas para dirigir a inspeção e deve ser adequado à linguagem de programação utilizada. Quanto mais ‘fraca’ a checagem de tipo, maior o checklist. Exemplos: Inicialização, Nomeação de constantes, termino de loop, li­mites de arranjos, etc.

Processo de Inspeção

Plano Visão Geral Preparação Individual Reunião de Inspeção Revisão Acompanhamento

reunião da revisão de sw

Microsoft Word – NotasDeAula5Novo.doc

Diretrizes da revisão

As diretrizes devem ser estabelecidas antecipadamente, distribuídas a todos os revisores, ter a concordância de todos e então ser encaminhada.

Conjunto mínimo de diretrizes para as revisões técnicas formais:

1) Revise o produto, não o produtor.

2) Fixe e mantenha uma agenda.

3) Limite o debate e a refutação (razão que vai contra uma premissa, lema ou conclusão).

4) Enuncie as áreas problemáticas, mas não tente resolver cada problema anotado.

5) Faça anotações por escrito.

6) Limite o número de participantes e insista numa preparação antecipada.

7) Desenvolva uma lista de conferência (checklist) para cada produto que provavelmente será revisto.

8) Atribua recursos e uma programação de tempo para as Revisões Técnicas                  Formais.

9) Realize um treinamento significativo para todos os revisores.

10) Reveja suas antigas revisões.

Sistema de Controle de Versão

Software com a finalidade de controlar diferentes versões de um documento, isto é o

histórico e o desenvolvimento de códigos fontes ou qualquer outro tipo de documentação.

É sistema que está se tornando cada vez mais presente em em­presas e instituições de tecnologia e desenvolvimento de software. Também muito utilizado no desenvolvimento de software livre, onde os fontes mais atuais podem ser obtidos diretamente destes sistemas. 

Alguns Sw proprietários:

Visual SourceSafe (VSS) produto da Microsoft para controle de ver­são, integrado a muitas IDEs da Microsoft.

Rational ClearCase produto da IBM para controle de versão. Tem um plugin para o Eclipse.

Sw livres:

Concurrent Version System (CVS) software livre clássico e bem tes­tado.

Subversion (SVN) está substituindo o CVS aos poucos; é uma alterna­tiva também livre e mais eficiente. Muitas fundações não­ governamentais sem fins lucrativos ligadas ao desenvolvimento de software como a Apache Foundation já adotaram o Subversion como padrão.

MediaWiki software livre que combina Wiki com um sistema inte­grado de controle de versões. Sites com os projetos da Wikimedia, tal como a Wikipédia mantém o sistema Media Wiki para o controle das versões dos documentos. Este sistema permite o trabalho simultâneo de milhares de voluntários.

Funcionamento Básico

Cada sistema tem sua particularidade, embora a maioria deles compartilhe os conceitos básicos descritos a seguir:

Repositório – Tais informações como todo o histórico ficam guardadas num repositório (repository em inglês), num servidor qualquer. Geralmente o acesso é feito por um cliente pela rede (via socket) e pode ser feito localmente quando o cliente está na mesma máquina do servidor.

O repositório armazena a informação um conjunto de documentos de modo persistente num sistema de arquivos ou num banco de dados qualquer. É possível que o armazenamento seja feito em outros dispositivos capazes de “eternizar” e resgatar facilmente a informação.

Cada servidor pode ter vários sistemas de controle de versão e cada sistema pode ter diversos repositórios, limitando se na capacidade de gerenciamento do software e também no limite físico do hardware. Geralmente um repositório possui um endereço lógico que permite a conexão do cliente. Esse endereço pode ser um conjunto IP/porta, uma URL, um caminho do sistema de arquivos etc.

Cada desenvolvedor possui em sua máquina uma cópia local (working copy em inglês) somente da última versão de cada documento. Essa cópia local geralmente é feita num sistema de arquivos simples. Sendo que a cada alteração relevante do desenvolvedor é necessário “atualizar” as informações do servidor submetendo (commit em inglês) as alterações. O servidor então guarda a nova alteração junto com todo o histórico mais antigo. Se o desenvolvedor quer atualizar sua cópia local é necessário atualizar as informações locais, e para isso é necessário fazer baixar novidades do servidor (update em inglês).

Envio e Resgate de versões

A principal função do sistema de controle de versão:

Armazenar todo o histórico de desenvolvimento do documento, desde o primeiro envio até sua última versão. Permitindo que seja possível resgatar uma determinada versão de qualquer data mais antiga, evitando desperdício de tempo no desenvolvimento para desfazer alterações quando se toma algum rumo equivocado.

Tais envios das alterações, quando se deseja minimizar conflitos de versões, facilitarem no desfazer de alterações e também no controle do histórico, recomenda se que uma alteração seja enviada cada vez que o software estiver minimamente estável, i. e., cada vez que uma parte/seção/função nova (ou mudança) esteja funcionando corretamente. Assim sendo não é recomendável o envio quando o documento como um todo possa causar alguma dificuldade no desenvolvimento de outro colaborador, como um código não compilando ou com algum bug que comprometa todo o funcionamento, por exemplo.

Cada “envio” é na maioria dos sistemas chamado de “commit”, ou seja, submeter e efetivar as alterações no repositório, mas em alguns é conhecido como chekin, assim como o processo de desfazer chekout e a atualização das versões como um todo Get last verson.

Cada envio produz uma nova versão no repositório e é armazenado como “uma fotografia” do momento. Muitas vezes é possível acrescentar comentários no envio das alterações, o que facilita também numa possível análise do histórico.

Em sistemas no estilo do CVS (Concurrent Version System (Sistema de Versões Concorrentes), o controle de versão é feito por cada documento individualmente. Assim, para pegar uma “fotografia” de determinado momento, elas não ficam “alinhadas” em função da versão.

Microsoft Word – NotasDeAula5Novo.doc

Num sistema mais moderno, como o SVN, o controle de versão é feito por cada envio ao servidor. Ou seja, há uma versão global para todos os documentos.

Trabalho em Equipe

O sistema também é bastante útil quando se trabalha com vários desenvolvedores de modo simultâneo, resolvendo de modo muito satisfatório conflitos de versões. As maiorias dos sistemas possuem diversos recursos como mesclagem e divisão de ramo do desenvolvimento para auxiliar nessas tarefas.

Passos no controle de versões

1°) passo: atualizando

2°) passo: desenvolvendo

3°) passo: submetendo

4°) passo: necessita atualização

5°) 5°passo: baixando atualização e mesclando

6°) e último passo: submetendo a versão final

Sem sistemas de controle de versão

Quando se compartilha o mesmo projeto numa rede diretamente num sistema de arquivos simples, sem um sistema de controle de versão, a chance de haver conflito aumenta muito. Alguns arquivos ficam bloqueados para escrita enquanto está sendo usado, o fluxo de informação pela rede é alto porque a cada vez é necessário reenviar o documento todo e a chance de corromper arquivos também aumenta; isto não acontece com um sistema de controle de versão, pois cada desenvolvedor possui uma cópia local do projeto, trabalhando localmente, baixando as atualizações e enviando as alterações.

Mesclagem e comparação de versões

Quando se utiliza um sistema de controle de versões cada desenvolvedor pode trabalhar tranquilamente em sua cópia local e o sistema fica encarregado de mesclar o que for necessário de acordo com as mudanças simultâneas.

A mesclagem (ou merge em inglês) consiste na aglutinação automática de versões através da comparação entre elas. Esta pode ser feita também manualmente quando o conflito é direto, ou seja, quando há alterações simultâneas no mesmo ponto do documento. Sendo possível também comparar quaisquer versões entre si, enviadas a qualquer tempo. Saber exatamente o que foi acrescentado, modificado ou excluído em qualquer ponto dos documentos. Permitindo a análise minuciosa das alterações desde a criação do projeto até seu estado atual.

Obs.: Alguns sistemas não possuem o sistema de “mesclagem”, portanto quando há conflito é necessário resolvêlo manualmente como descreve a subseção seguinte.

Resolução de Conflitos

Quando dois ou mais desenvolvedores modificam uma mesma região num documento aí é necessário resolver o conflito “manualmente”. O software de Cliente fará uma cópia de segurança da sua alteração para que não haja chance de você perdê-la e depois mostrará o local de conflito. O software geralmente mostra os conflitos na tela e o desenvolvedor escolhe qual versão manter. Em regra quando acontece esse tipo de coisa é porque houve falha na organização de divisão do trabalho e provavelmente uma alteração semelhante foi produzida na mesma região.

Ramificações e Marcações

Em sistema moderno de controle de versões é possível quebrar a linha do desenvolvimento em mais de um caminho, sendo chamado de ramificação (ramo), braços ou em inglês branches. Isso é muito útil quando se conquista uma versão estável dos documentos (ou software) ou quando se quer fazer uma tentativa “não convencional” fora do ramo principal.

Otimização de Espaço e Velocidade

Um sistema assim mantém armazenado apenas a primeira versão e as diferenças entre elas, até formar a última, com o principal objetivo de economizar espaço. É claro que também existem outras otimizações que guardam a versão final ou versões recentes para que algumas operações possam ser feitas de modo mais rápido (utilizando uma espécie de cache). Assim, dependendo do sistema e da configuração, é possível compactar algumas partes do repositório muito antigas que não estão sendo utilizadas de modo a salvar espaço.

Tais sistemas são otimizados para trabalhar com arquivos texto e muitas vezes não se dão muito bem com arquivos binários. Os sistemas mais modernos trabalham melhor com esse segundo tipo de arquivo, mas ainda assim de forma pouco satisfatória: tanto pelo alto consumo de espaço quanto pela dificuldade de se fazer comparação entre uma versão e outra.

Principais Vantagens

De se manter um sistema de controle de versão como bases num desenvolvimento de software ou no desenvolvimento de um documento de texto qualquer são:

• Controle do histórico: fácil fazer, fácil desfazer. Fácil também analisar o histórico do desenvolvimento de documentos, como também fácil resgatarem versões antigas. É possível analisar cada mínima alteração, desde a primeira versão até a última.

•Trabalho em equipe: um sistema de controle de versão permite que centenas de pessoas trabalhem sobre os mesmos documentos ao mesmo tempo e minimiza muito os possíveis conflitos de edições. Quanto mais documentos e menos pessoas, menos chances de conflitos. Quanto mais envios ao sistema, as chances de conflitos também diminuem.

•Controle de versões estáveis: é possível marcar onde é que o documento estava com uma versão estável, podendo ser facilmente resgatado.

Vocabulário

Veja o vocabulário típico da maioria dos sistemas de controle de versão:

Repositório / Repository local no Sistema onde fica armazenado todas as versões, desde a primeira até a última. Cada Sistema pode possuir de 0 a N repositórios.

Cópia local / Working copy É geralmente uma pasta no sistema operacional do desenvolvedor (do lado Cliente) que mantém a cópia da última versão do projeto. É através da cópia local que o Cliente compara com a última versão do Servidor e sabe exatamente o que foi modificado.

Baixar / CheckOut Quando não existe cópia local e é necessário baixar todo o projeto do Servidor.

Submeter / Commit Enviar as alterações da cópia local ao Servidor através do Cliente.

Modificação, diferença ou mudança (Change ou diff) Representa a diferença entre uma versão e outra de um mesmo documento.

Atualização / Update Atualiza na cópia local as novidades do Servidor, provavelmente as mudanças enviadas por outro desenvolvedor.

Versão desatualizada / Uptodate Acontece quando alguém submete um documento que você está trabalhando antes de você. Nesse caso é necessário fazer uma atualização para que o Cliente tente mesclar as alterações que, na prática e na grande maioria das vezes são bem sucedidas.

Mesclagem / Merge ou Integration Permite que mais de um utilizador modifique um mesmo documento ao mesmo tempo, comparando as diferenças e mesclando mantendo as duas alterações (se possível). A mesclagem geralmente é feita localmente (lado Cliente) na atualização de um documento quando há uma versão no Servidor mais recente que a sua.

Revisão ou Versão / Revision ou Version Representa um determinado “momento” (uma “fotografia”) de um repositório ou documento.

Conflito / Conflict Acontece geralmente quando não há planejamento nas alterações dos documentos e mais de um desenvolvedor modifica simultaneamente o mesmo local de um mesmo documento. Quando um desenvolvedor envia e atualiza poucas vezes sua cópia local, as chances dos conflitos ocorrerem a dificuldade de resolvê-los aumentam significativamente.

Resolução de conflito / Conflict resolve ou Solve Quando os desenvolvedores precisam analisar o que entrou em conflito e escolher qual alteração fará parte da versão final.

Ramificação ou braço / Branche Quando a linha de desenvolvimento precisa ser dividida em duas ou mais.

Marcação / Tag É dar um nome a um determinado “momento” do repositório, ou seja, é como uma “fotografia” de determinada data.

Travar / Lock Em alguns sistemas é possível bloquear um arquivo e ninguém pode alterá-lo nesse momento. Isso é muito pouco usado, mas é útil com arquivos binários e/ou difíceis de serem mesclados.

Abaixo os endereços na WEB dos principais sistemas de controle de versão:

Concurrent Version System (CVS): http://savannah.nongnu.org/projects/cvs/

Subversion (SVN): http://subversion.tigris.org/

VisualSourceSafe(VSS):http://msdn.microsoft.com/vstudio/products/vssafe/default.aspx

Rational ClearCase:http://www306.ibm.com/software/awdtools/clearcase/

MediaWiki: http://www.mediawiki.org/wiki/MediaWiki

GNU CSSC: http://cssc.sourceforge.net/

Revision Control System (RCS):http://www.gnu.org/software/rcs/rcs.html

Testes Estratégicos

Teste em Espiral

O processo de engenharia de software pode ser visto como em uma espiral. Boehm*(1988).

Teste de Unidade => Código => Teste de Integração => Projeto => Teste de Validação => Requisitos => Teste de Sistema => Engenharia de Sistemas.

Podemos visualizar este processo como:

Um caminho de ida (entrando na espiral): Engenharia de Sistemas, seguindo pelo Levantamento e Análise de Requisitos, pelo projeto (design) do Sistema e finalmente pela Codificação dos componentes.

Um caminho de volta (saindo da espiral): Teste de Unidade (teste de componentes), passamos para o teste de Integração dos Componentes, pelo teste de Validação do Sistema junto ao usuário e, finalmente, pelo Teste do Sistema no ambiente e no contexto definitivos.

Assim cada fase no caminho de ida corresponde um teste no caminho de volta.

espiral

Uma outra forma de ver este processo associado com o enfoque de Orientação para Objetos pode ser visto no diagrama a seguir proposto por como proposto por Aßmann (2005).

diagrama_teste

Teste de Unidade – (Teste de unidade, Teste unitário ou teste de componentes)

Teste individual de cada um dos componentes (programas ou módulos), procurando garantir que funcionem adequadamente (ROUILLER et Al., 2003). Em sistemas orientados para objetos estas unidades são tipicamente métodos e classes.

unidades de teste

Filosofias de Teste

Existem duas filosofias de teste de componentes:

Caixa preta é testado pela sua funcionalidade declarada (seus objetivos e assinatura, lógica do programa).

Caixa de vidro/caixa branca o código interno é inspecionado.

Teste Caixa Preta Lógica do Programa
Teste Caixa Branca Código Interno

Teste caixa preta

Também chamada de abordagem funcional concentra-se nas interfaces do software e visa mostrar que se as entradas são válidas e podem ser aceitas então as saídas são as esperadas e, além disso, a integridade dos dados é mantida. Aplicado, principalmente, aos testes de validação, sistemas e aceitação, mas também são usados nos testes unitários. Neste teste, é preciso conhecer a função específica do componente, e o teste deve ser executado para demonstrar a sua operação correta, baseada unicamente em sua especificação sem considerar a sua lógica interna.

Casos de Teste

O teste de caixa preta nos remete à questão sobre que casos de teste devem escolher para testar o componente. Como é impossível o teste exaustivo precisamos escolher dados que sejam bons representantes de conjuntos típicos e atípicos de dados.

Partições em classes de equivalência

Particione as entradas e saídas do sistema em “conjuntos de equivalência”. Por exemplo, se seu componente recebe uma entrada um inteiro de cinco dígitos entre 10.000 e 99.000, faça partições que envolvam valores típicos dentro do intervalo e nas extremidades, isto são casos na vizinhança dos conjuntos. Considere também valores atípicos, para os quais o componente deve dar uma resposta plausível, isto é, rejeitando-os ou modificando-os.

Teste da caixa branca

Abordagem estrutural e procura mostrar que os componentes internos do software (programas) realmente funcionam. Pretendem garantir que todas as estruturas, comandos e todos os possíveis caminhos do programa sejam testados. Aplica-se, principalmente, aos testes unitários e de integração. Sendo que na prática, mesmo para pequenos programas, é geralmente impossível testar todas as possibilidades, o que exige alguma estratégia de teste baseada em alguma heurística.

Teste da caixa cinza

Esta é uma recente abordagem de teste de software. Seria um ponto de equilíbrio virtual entre o teste de caixa-branca e o de caixa-preta. Neste tipo de teste o desenvolvedor dos testes não tem acesso ao código fonte da aplicação, porém tem conhecimento dos algoritmos que foram implementados, como também pode efetuar manipulações em arquivos de entrada e saída do tipo XML ou mesmo acessos ao banco de dados da aplicação para simples conferência de dados ou alteração de parâmetros considerados nos casos de teste (Wikipedia, 2006).

Asserções

Uma das formalizações para a verificação da correção de programas é com o conceito de asserções.

Embora tenham sido propostas como um mecanismo para a correção matemática de programas, a estratégia pode ser útil no processo de inspeção do código de um programa.

Uma asserção estabelece relações lógicas entre as variáveis de um programa

que devem ser satisfeitas em determinados pontos de execução do programa.

Para um comando (ou conjunto de comandos) em uma linguagem de programação, podemos estabelecer uma asserção de entrada e uma de saída.

A asserção de entrada – expressão lógica que indica as condições que são válidas antes da execução do comando (ou conjunto de comandos).

A asserção de saída indica as condições que passam a ser válidas depois da execução do comando (ou conjunto de comandos).

{AE} Verdadeira antes

Comando

{AS} Verdadeira depois

Se inicialmente a asserção AE é válida, após a execução do comando, vale a asserção AS.

Por que somente o teste caixa preta não é suficiente?

Por que precisaríamos inspecionar o código de um programa para criar casos de teste que levem em conta sua lógica interna.

Estratégias para o Teste Caixa Brancas

Veja algumas estratégias:

a) Cobertura de instruções

Na cobertura de instruções são gerados casos de teste para executar, pelo menos uma vez, todas as instruções do programa.

b) Cobertura de arestas

Geramos casos de teste para seguir, pelo menos uma vez, todas as arestas de transferência de controle no programa.

c) Cobertura de decisões

Procura-se gerar casos de teste para gerar todos os resultados de decisões elementares e combinações de decisões elementares do programa.

d) Cobertura de caminhos

Procura-se gerar casos de teste para percorrer, pelo uma vez, todos os caminhos  existentes na estrutura do programa.

É a única que se mostra mais completa e viável quando desejamos utilizar o menor número de casos de teste.

Dado um programa podemos transformá-lo em um grafo para encontrar os ciclos e em seguida calcular o número de casos de teste necessários para testar o programa pela cobertura de caminhos.

Convenções

a) Seqüência

Um conjunto de onde não haja mudança do fluxo podem ser agrupados e representados por um círculo ou um retângulo com os cantos arredondados. Um programa será então representado por uma seqüência destes símbolos.

sequencia

b) Alternativa
O fluxo pode seguir por dois caminhos alternativos.

sec) Repetição com teste no início
A repetição de um conjunto de instruções com um teste de permanência no início (enquanto) pode ser representado assim:

enquanto

d) ) Repetição com teste no final
A repetição de um conjunto de instruções com um teste de permanência no final (repita-até) pode ser representado por:

repita atée) Multiplas alternativas
A mudança de fluxo por diversos caminhos diferentes pode ser representado por:

caso

Número Ideal de Casos de teste

Como encontrar o número de casos de teste ideal para testar um programa como este?

a) Calcule o número de nós

nos

b) Calcule o número de arestas

arestas

c) Calcule o úmero de áreas (regiões) criadas no grafo

regioes

Complexidade Ciclomática

Métrica de software que fornece uma medida quantitativa da complexidade lógica de um programa.

É calculada por

V(G) = E – N + 2

Onde E = número de arestas (Edges) e N = número de nós

No nosso exemplo:

V(G) = 11 – 9 + 2 = 4

V(G) nos dá um limite superior para o número de caminhos independentes que formam o conjunto base. É fácil ver também que V(G) coincide com o número de regiões criadas no grafo. No nosso exemplo, V(G) = 4 e são quatro as regiões que descobrimos no grafo.

complexidade ciclomática

complexidade ciclomática1complexidade ciclomática2

Teste de Sw

Processo de Depuração e Teste

Teste de Sw

Importância

Ao teste de SW não se deve está enfatizado sua importância em relação a qualidade de Sw, mas sim sua importância no processo de desenvolvimento.

Uma vez que o código fonte foi gerado, o software deve ser testado para permitir que os erros sejam identificados e removidos antes da entrega ao cliente. Não é possível remover todos os erros em um pacote grande de software, dessa forma o objetivo do Engenheiro de Software deve ser o de remover o erro o mais cedo possível, no ciclo de desenvolvimento do software (Wasserman, 1996).Teste pode apenas encontrar erros, ele não pode provar que um programa é livre de erros.

Para (Pressman,2002), o teste deve ser planejado e projetado.

As revisões técnicas formais (walkthrough), por si só, não permitem encontrar defeitos do software, dados de teste devem também ser usados. Em se tratando em projetos grandes de software, as equipes separadas de teste devem ser usadas para desenvolver e executar o conjunto de casos de teste usados processo de teste.

Objetivos

Testar é um processo de executar um programa com a intenção de encontrar erros. Um bom caso de teste é o que tem alta probabilidade de encontrar um erro ainda não descoberto.

Testar x Depurar

Como foi falado em post anterior,

Depurar não é uma atividade de teste. A depuração mostra a natureza da falha e a corrige. [Myers]

O teste apenas indica que há uma falha.

Os testes devem ser verificados em relação às exigências do cliente. Estes devem ser planejados bem antes de se começar a testar. Seu planejamento faz parte do processo de teste.

O princípio de Pareto

(80% de todos os erros será encontrado provavelmente em 20% do código) aplica-se ao teste de software.

O teste deve começar no pequeno e ir progressivamente ao grande. Testar exaustivamente não é possível. Para ser mais eficaz, o teste deve ser conduzido por um terceiro de forma independente.

Checklist da testabilidade de software

Item

O que é

Status (S-Sim/N-Não)

Operabilidade Quanto melhor o software funciona, melhor ele pode

ser testado.

Observabilidade O que você vê é o que você testa.
Controlabilidade Quanto mais o software pode ser controlado, mais o teste pode ser automatizado e otimizado);
Decomponibilidade Controlando o escopo do teste, mais rapidamente

os problemas podem ser isolados e re-examinados inteligentemente.

Simplicidade Quanto menos há para testar, mais rapidamente o teste pode ser feito.
Estabilidade Quanto menor o número de mudanças, menor a

descontinuidade do teste).

Compreensibilidade Quanto mais informação, mais fácil de testar.

Atributos de um bom Teste

Um teste bom tem uma alta probabilidade de encontrar um erro, não é redundante, não deve ser nem demasiado simples nem demasiado complexo. Um caso de teste deve ser o melhor de um conjunto de testes possíveis. Um programa pode passar com sucesso em muitos testes, mas basta falhar em um teste para dizermos que ele está incorreto.

Tipos de Teste

Tipo

Descrição

Caixa Preta – sem lógica Envolve apenas as entradas e saídas de um componente de software. É um teste comportamental. Sabendo-se a função específica de um produto, o teste deve ser executado para demonstrar a operação correta, baseada unicamente em sua especificação sem considerar a sua lógica interna.
Caixa Branca – Lógica Procura exercitar a lógica interna de um

componente de software. No teste caixa-branca (ou caixa de vidro como às vezes é chamado), conhecendo-se o funcionamento interno de um produto, os testes são executados para verificar o funcionamento de todos os trajetos lógicos independentes.

É preciso tomar muito cuidado para não Corrigir o erro errado, o que é muito comum, devido a “fatores psicológicos”, quando o programador “Vê o que espera ver” e não o que realmente está registrado.

“O processo de testes é normalmente prejudicado pela universal relutância humana em admitir falhas “ [Gries]

É preciso cuidado também para não ter pressa em corrigir o erro, não documentar o erro ou não documentar a correção do erro. É preciso Testar o programa após a correção, por menor que ela seja. Uma vez testado o programa e verificado que ele tem erro, devemos partir para o processo de depuração, vistos nos quatro passos a seguir.

Processo para Depuração (1 Debug)

Passo

Processo

Descrição

Entendimento do problema Tentar entender o problema. Os dados disponíveis são  uficientes para

o entendimento? Se não, obtenha mais dados.

Planejamento Entendidos os sintomas do erro, tente criar “teorias sobre a sua

origem”, escolha a melhor teoria e desenvolva um plano para provar

sua teoria.

Aplicação do Plano Aplique o plano com critério. Verifique se e a teoria foi provada, isto é,

o erro foi detectado ou se será necessário usar outro plano. Mesmo que

o erro tenha sido localizado e explicado, tome cuidado. Pode ser que o plano não foi aplicado com o rigor necessário. Reveja o plano e sua implementação.

Rever as correções Se os planos foram aplicados com critério Faça as correções no

programa, reveja com cuidado as correções feitas e termine o processo de depuração. Teste o programa novamente.

Nota: 1) A palavra debug (vem de de-bug) significa, em inglês, retirar um bug e vem da época

dos primeiros computadores que deixavam de funcionar devido ao fato de insetos (bugs) comerem as capas dos fios e provocarem defeitos na máquina.

Esta tarefa deve ser feita com muito cuidado para não introduzir novos erros no componente que está sendo depurado.

Heurística

O processo de teste de software deve ser conduzido usando uma série de heurísticas:

• Um bom caso de teste é o que tem alta probabilidade de detectar um erro.

• Um dos pontos difíceis do processo de teste é saber quando parar.

• É muito difícil para um programador testar seu próprio programa.

• É necessário escrever os resultados esperados de um caso de teste.

• Evite testes não reproduzíveis, ou projetados sem critério, sem documentação, que não permitam sua reprodução.

• Os programadores mais criativos devem ser escalados para o teste de programas.

• Nunca altere o programa para facilitar o teste.

• O teste deve começar com os objetivos.

• Escreva casos de teste tanto para as condições válidas quanto inválidas.

A medida que cresce o número de erros detectados, a probabilidade de serem encontrados mais erros aumenta.

Níveis de correção de um componente de software

Podemos estabelecer uma escala de qualidade de um componente de software em relação a sua qualidade em responder corretamente, quando executados:

1.Sem erros de sintaxe (compilação).

2.Sem operações inválidas.

3.Existem conjuntos de dados de casos de teste para os quais há resposta correta.

4.Para conjuntos típicos de casos de teste ( razoáveis ou aleatórios) há resposta correta.

5.Para conjunto de dados deliberadamente difíceis há resposta correta.

6.Para todos os conjuntos de dados (possíveis) que são válidos com relação à especificação há resposta correta.

7. Para todos os possíveis conjuntos de dados e igualmente, para condições de entrada erradas, a resposta é correta ou razoável.

É claro que atingir os níveis 6 e 7 não é tarefa fácil.

O Teste na prática

O teste caixa-preta de um componente de software pode ser melhor entendido com uma analogia com o hardware. Quando compramos uma lâmpada em um supermercado, fazemos o teste da lâmpada, colocando-a em um bocal devidamente alimentado com a corrente elétrica. Se ela acender, passou no teste. Se não acender falhou no teste.

Análogamente um módulo de programa pode ser testado se tivermos um driver para acioná-lo, entregar os dados que ele precisa e receber a(s) resposta(s) produzida(s). Na figura abaixo vemos uma analogia do teste da lâmpada com o teste do módulo função ABS.

O módulo retorna o valor absoluto de um número real fornecido.

Assim , ABS(-5) retorna 5 e ABS de (5) também retorna 5.

Podemos planejar os casos de teste deste módulo, indicando casos típicos e atípicos para verificar a consistência do módulo de programa e a sua robustez.

códigocasos de teste

É importante definir, com antecedência, antes de rodar o programa, quais são os resultados esperados, para depois confrontá-los com os resultados obtidos.

No “driver” escrito para testar o programa podemos fazer as chamadas dos casos de teste e, adicionalmente deixar o próprio programa driver testar os resultados.

Engenharia de Software

O uso do processo para chegar a um produto

Conceitos

Em nosso contexto definimos:

Processo –  sentido de seguimento de curso, maneira de operar e método.

Produto – resultado ou coisa produzida.

Segundo o Wikipédia Engenharia de Software pode ser entendido como as tecnologias e práticas usadas para criar software para computadores melhorando a produtividade e qualidade.

Em seu contexto Engenharia envolve a criação, construção, análise, desenvolvimento e manutenção.

Assim temos: Engenharia de Software é a “criação e a utilização de sólidos princípios de engenharia a fim de obter software de maneira econômica, que seja confiável e que trabalhe eficientemente em máquinas reais.“[Fritz Bauer].

Sendo um conjunto de: linguagens de programação, bases de dados, ferramentas, plataformas, bibliotecas, padrões e processos.

Evolução da Engenharia de Sw

Wasserman (1996) cita uma série de fatores que têm influenciado a

disciplina de Engenharia de Software (ES) desde a década de 70:

• Produtos comerciais vêm exigindo a entrega de produtos em um

tempo cada vez mais crítico;

• As mudanças na economia da computação (redução dos custos

de hardware e aumento nos custos de desenvolvimento e

manutenção);

• Disponibilidade computação em desktops e computação móvel;

• Aumento das redes locais e remotas;

• Disponibilidade e adoção da tecnologia orientada a objetos;

• Uso de interfaces gráficas;

• Imprevisibilidade do modelo de desenvolvimento de software em

• cascata.

Tudo isso fez com que a ES se adaptasse para acompanhar tais mudanças.

A Engenharia de Sw é uma disciplina que envolve:

• Abstração

• Métodos e notações de análise e projeto

• Protótipo da interface com o usuário

• Arquitetura de software

• Processo de software

• Reuso

• Medição

• Ferramentas e ambientes integrados

Destacamos aqui Arquitetura de software, o processo de software e as ferramentas e ambientes integrados.

Veremos também:

• Processos de software

• Requisitos do processo

• Desenho do processo

• Implementação do processo

• Utilização do processo

Processo – conjunto de passos parcialmente ordenados, sendo: atividades, métodos, práticas e transformações, usadas para atingir uma meta que vem a ser um ou mais resultados concretos finais: os produtos do processo.

Um processo bem definido tem uma documentação que a detalha:

• o que é feito (produto);

• quando (passos);

• por quem (agentes);

• as coisas que usa (insumos);

• as coisas que produz (resultados).

Processo Unificado

Como exemplo de um processo bem definido é o Processo Unificado (Unified

Process-UP) proposto pelos autores da UML ( Guedes, 2004 ). Ele tem uma estrutura matricial que relaciona fases e fluxos e tem como características centrais segundo seus autores:

• dirigido por casos de uso;

• centrado na arquitetura;

• iterativo e incremental;

• referência industrial de fato;

• plataforma abstrata de processos

Exemplos de Processos Unificados

RUP/EUP

O UP tem pelo menos duas concretizações mais conhecidas: O Rational

Unified Process (RUP) e o Enterprise Unified process ( EUP). O processo

Unificado define quatro fases no projeto:

• Concepção

• Elaboração

• Construção

• Transiição

Já o EUP adiciona duas fases adicionais

• Produção

• Cancelamento

PRAXIS

O é um processo para Aplicativos Extensíveis Interativos (Paula Filho, 2009). O PRAXIS é um processo de desenvolvimento de software com foco educacional e orientado a objetos, baseado em paradigmas de grande difusão: UML,

CMM, XP e IEEE software standards. O Praxis adota uma nomeclatura comum em toda a proposta:

Fase Divisão maior de um processo, para fins gerenciais, que corresponde aos pontos principais de aceitação por parte do cliente.
Iteração Passo constituinte de uma fase, no qual se atinge um conjunto bem definido de metas parciais de um projeto.
Script Conjunto de instruções que define como uma iteração deve ser executada.
Fluxo Subprocesso caracterizado por um tema técnico ou gerencial.
Subfluxo Conjunto de atividades mais estreitamente correlatas, que faz parte de um fluxo maior.
Atividade Passo constituinte de um fluxo.
Técnica Método ou prática aplicável à execução de um fluxo.
Artefato = produto Os artefatos podem ser documentos ou modelos, conforme seus consumidores primários sejam humanos ou ferramentas.

Um modelo é um artefato de uma ferramenta técnica específica

(como uma ferramenta CASE, por exemplo), produzido e usado nas atividades de um dos fluxos do processo. Já um documento é um artefato produzido por um editor de

textos, de relatórios ou de hipertexto, que pode ser consultado on-line ou em forma impressa, para fins de referência ou revisão. Um artefato é em essência um produto.

Elementos do Praxis

Processo – conjunto ordenado de fases que é composto de um conjunto ordenado de iterações.

Também constituído por um conjunto de fluxos que, por sua vez, é constituído de um conjunto parcialmente ordenado de atividades. Um fluxo pode ser constituído de um conjunto de sub-fluxos.

Elementos do Praxis

Script conjunto de atividades que devem ser executadas para se produzir um ou mais artefatos, bem como um conjunto de critérios para serem usados na validação do(s) artefato(s).

Elementos do Script do Praxi

JUnit

O Framework JUnit é uma ferramenta para teste regressivo.

Teste de classes e componentes.

Veja na integra: www.junit.org

Suporta teste de regressão permanentemente no desenvolvimento.

Um fato interessante é que todos os casos de teste são colecionados e podem ser repetidos.

Qualidade

Qualidade para a Wikipédia “é um conceito subjetivo que está relacionado diretamente às percepções de cada indivíduo. Diversos fatores como cultura, modelos mentais, tipo de produto ou serviço prestado, necessidades e expectativas influenciam diretamente nesta definição.”

Ou seja, o que tem qualidade para mim não necessariamente terá qualidade para outro individuo.

Abordaremos aqui:

A qualidade de um produto ou serviço, estes podem ser olhados de duas ópticas: a do produtor e a do cliente. Do ponto de vista do produtor, a qualidade se associa à concepção e produção de um produto que vá ao encontro das necessidades do cliente. Do ponto de vista do cliente, a qualidade está associada ao valor e à utilidades reconhecidas ao produto, estando em alguns casos ligada ao preço.

Terminologia padrão de acordo com o IEEE Standard 729

Erro: erro humano.

Defeito: resultado do erro evidenciado em algum desenvolvimento ou

manutenção do produto.

Falha: divergência entre o comportamento requerido para o sistema e o

comportamento real.

Como o erro causa uma falha?

Erro humano => Defeito => Falha

A falha é sempre causada pelo erro humano.

Falha (o que causou) => Um defeito (o que causou o defeito) => erro humano.

Abordagens

• Teste

• Depuração

• Automação do teste

• Facilitação da manutenibilidade

Algumas perguntas???

• Qual é a diferença entre Teste e Depuração?

• Quais são as filosofias de teste?

• Por que um teste não pode ser usado para mostrar a  ausência de erros?

• Como projetar casos de teste?

• Quais são os tipos de teste?

O teste do programa pode ser usado para descobrir a presença de erros, mas não para mostrar a sua ausência. [Djkistra]

TESTE é o processo de executar um programa com a finalidade de encontrar erros. [Myers]

Assim podemos dizer: Erro no programa => Sucesso no teste.

DEPURAÇÃO (Debug) mostra a natureza do erro e o corrige.

[Myers]

Teste – Mostra que existe umerro. Depuração – Mostra a natureza doerro e o corrige.

Correção do Erro Errado

Fatores Psicológicos – fazer revisões, ser cético.

Filosofias de Teste

Caixa Preta – ver a lógica do programa.

Planejamento de Teste

Casos de Teste Entradas Resultados Esperados ResultadosObtidos
1 A A B