Qualidade sistemas legados

1.346 visualizações

Publicada em

Trabalho de conclusão de curso sobre como melhorar a qualidade em sistemas legados.

Publicada em: Software
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
1.346
No SlideShare
0
A partir de incorporações
0
Número de incorporações
15
Ações
Compartilhamentos
0
Downloads
12
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Qualidade sistemas legados

  1. 1. CENTRO UNIVERSITARIO SENAC Reinaldo Coelho Sartorelli Proposta de Processo para Automação de Testes em Sistemas Legados São Paulo 2007
  2. 2. REINALDO COELHO SARTORELLI Proposta de Processo para Automação de Testes em Sistemas Legados Trabalho de conclusão de curso apresentado ao Centro Universitário Senac – Campus Tito, como exigência parcial para obtenção do grau de Pós Graduado em Técnicas de Construção de Software Orientado a Objetos. Orientador: Prof. Dr. Ivanir Costa São Paulo 2007
  3. 3. RESUMO Sistemas de software legados são sistemas que, apesar do tempo de vida, continuam em produção e se mantém em uso. Os sistemas legados podem apresentar problemas de qualidade por diversos fatores, dentre eles podem ser citados, a baixa experiência do profissional que desenvolveu, o uso de uma metodologia considerada antiquada, entre outros problemas que podem impedir sua evolução ou até gerar erros graves após uma simples manutenção. Normalmente os sistemas legados não podem ser substituídos por diversas razões e que os tornam caros quanto à manutenção e trazem muitos riscos no momento de sua evolução. Devido a estes problemas torna-se necessário melhorar a qualidade desses sistemas legados podendo ser uma forma interessante de mantê-los ativos, tornando-os mais uma vez produtivos e permitindo que melhorias e evoluções sejam efetuadas com menos riscos. Conseqüentemente é gerado uma maior confiabilidade e segurança a cada evolução que se faça necessária. O incremento de novas funcionalidades nos sistemas legados com maior qualidade permite que que a empresa tenha vantagens competitivas sem grandes investimentos de novos desenvolvimentos, gerando lucros, permitindo também a integração com novos sistemas. O objetivo deste trabalho é apresentar uma proposta teórica de um processo de automação de testes que possa ser vinculado a qualquer processo de manutenção de sistemas legados, visando melhorar a qualidade do sistema legado de forma evolutiva, garantindo segurança no processo de implementação e evitando prejuízos consideráveis a empresa. Espera-se ao final desse trabalho uma contribuição com a proposta de um processo automatizado de testes para sistemas legados, formado por passos em uma seqüencia bem definida e simples e bem organizada.
  4. 4. Palavras-Chave: Sistemas Legados, Automação de Testes, Qualidade de Software Legado, Melhoria de Sistemas de Software, Processo de Automação de Testes, Processo de Desenvolvimento de Software.
  5. 5. ABSTRACT Legacy computer system is the term that is commonly used to describe software that is considered obsolete but is still being used in an organization. It usually represents software that is difficult to maintain or created with technology that is no longer supported by the vendor, software that is difficult to evolve due to a bad design or the use of obsolete development methods and the cost of maintenance is too high. These are some reasons for which the software is still used by the company although the development and improvement were discontinued. Other factors include de risk as it can consist of a core application for the company and the cost does not justify the change, as replacing it can lead to profit loss. Therefore, improving the quality of a legacy system can be an interesting way of keeping it active and more productive, allowing improvements and new features to be added with less risk, and also adding more confiability and security to a legacy system. To improve the quality and reliability as means to evolve legacy systems can add value and new ways of reusing the software without being a burden to the company, even allowing it to be a profitable system again, and integrating it with other new systems. The main goal of this work is to present a theoretical proposal of tests automation that can be linked to any software development process. The automation of a systems' test routines leads to significant quality mprovements of legacy systems, and a guarantee of reliability in the process of implementing new features and avoiding losses due to the continued use of a legacy software in a company or organization. Finally, this paper intends to contribute with a proposal of a process of test automation consisted of well-defined steps described in an organized and clear way, to be applied in legacy systems in order to improve their quality overall. Keywords: Legacy Systems, Test Automation, Legacy Quality Software, Improve System Quality, Test Automation Process, Software Development Process.
  6. 6. LISTA DE ILUSTRAÇÕES Figura 1: Estrutura do trabalho.............................................................................................12 Figura 2: Modelo de Ciclo de Vida Codifica-Remenda....................................................... 16 Figura 3: Ciclo de Vida Clássico ou Cascata........................................................................18 Figura 4: Ciclo de Vida Cascata do Tipo Sashimi................................................................19 Figura 5: Ciclo de Vida em Espiral...................................................................................... 20 Figura 6: Arquitetura Mista - Fase Cliente-Servidor............................................................22 Figura 7: Arquitetura Mista - Fase Final.............................................................................. 23 Figura 8: Exemplo de Modelo Cliente-Servidor Distribuído...............................................25 Figura 9: Exemplo de Modelo Cliente-Servidor de Banco de Dados Remoto....................26 Figura 10: Arquitetura Três Camadas numa aplicação baseada em Web.............................27 Figura 11: Representação de um esquema Básico SOA...................................................... 30 Figura 12: O relacionamento entre Classe, SubClasse e SuperClasse................................. 35 Figura 13: Definição parcial de uma classe java..................................................................35 Figura 14: Relacionamento entre os padrões ISO/IEC 9126 e ISO/IEC 14598...................40 Figura 15: Escopo das Três Métricas de Qualidade............................................................. 45 Figura 16: Exemplo de Rede de Pesca como Analogia as Estratégias de Teste...................51 Figura 17: Ambiente de teste de unidade............................................................................. 56 Figura 18: Exemplo de Grafo de Fluxo de Controle............................................................70 Figura 19: Exemplo de Matriz de Grafo.............................................................................. 71 Figura 20: Aumento do tempo gasto com testes manuais.................................................... 80 Figura 21: Custo de testes manuais e automáticos ao longo do tempo................................ 80 Figura 22: Resultados de uma boa automação de testes...................................................... 82 Figura 23: Proposta de Processo de Automação de Testes em Sistemas Legados.............105
  7. 7. LISTA DE ABREVIATURAS IEEE SGBD TI SOA XML ISO IEC PUM RNF RUP MTTR AVL GUI CLI API Instituto de Engenharia Eletro-Eletrônica Sistema Gerenciador de Banco de Dados Tecnologia da Informação Service Oriented Architecture(Arquitetura Orientada a Serviço) eXtensible Markup Language(Linguagem de Marcação Extensível) International Organization for Standardization(Organização Internacional para padronização) International Eletrotechinical Comission(Comissão Eletrotecnica Internacional) Problems per User Mounth(Problemas por usuário mês) Requisitos não Funcionais Rational Unified Process(Processo Unificado Rational) Mean-Time-To-Repair(Tempo médio para reparo) Analise de Valor Limite Graphical User Interface(Interface gráfica de usuário) Command Line Interface(Interface de linha de comando) Application Programming Interface(Interface de programação de aplicação)
  8. 8. SUMÁRIO 1 INTRODUÇÃO.................................................................................................................10 Objetivos..........................................................................................................................11 Metodologia de Trabalho.................................................................................................11 2 SISTEMAS DE SOFTWARE........................................................................................... 13 2.1 Processos de Desenvolvimento de Software............................................................. 13 2.1.1 Ciclo de Vida Codifica-Remenda ou Ad-Hoc....................................................15 2.1.2 Ciclo de Vida Cascata ou Clássico.....................................................................17 2.1.3 Ciclo de Vida em Espiral................................................................................... 19 2.2 Arquitetura de Software.............................................................................................21 2.2.1 Arquitetura Cliente Servidor..............................................................................24 2.2.2 Arquitetura Três Camadas..................................................................................27 2.2.3 Arquitetura Orientada a Serviços.......................................................................28 2.3 Paradigmas de Desenvolvimento de Software.......................................................... 30 2.3.1 Paradigma Orientado a Objetos......................................................................... 33 3 QUALIDADE................................................................................................................... 38 3.1 Qualidade de Software...............................................................................................38 3.1.1 Atributos de Qualidade de Software.................................................................. 41 3.2 Métricas de qualidade de software............................................................................ 44 3.2.1 Métrica de Defeito............................................................................................. 45 3.2.2 Métrica de Problemas do Cliente.......................................................................46 3.2.3 Métrica de Satisfação do Cliente....................................................................... 48 3.3 Estratégias de Teste de Software............................................................................... 50 3.3.1 Teste de Unidade................................................................................................53 3.3.2 Teste de Integração.............................................................................................56 3.3.3 Teste de Sistema.................................................................................................60 3.3.4 Teste de Aceitação..............................................................................................64 3.3.5 Teste de Regressão.............................................................................................65 3.4 Técnicas de Teste de Software...................................................................................66 3.4.1 Teste de Caixa-Branca....................................................................................... 67 3.4.2 Teste de Caixa-Preta...........................................................................................73
  9. 9. 3.5 Automação de Teste de Software...............................................................................79 3.5.1 Automação de testes de unidade........................................................................ 84 3.5.2 Automação de testes de integração.................................................................... 86 3.5.3 Automação de testes de sistema.........................................................................88 4 SISTEMAS DE SOFTWARES LEGADOS..................................................................... 93 4.1 A qualidade do software legado.................................................................................95 4.2 Transformação de sistema legado............................................................................100 5 PROPOSTA DE AUTOMAÇÃO DE TESTES EM SISTEMAS LEGADOS................104 5.1 Identificar pontos de necessidade de automação.....................................................107 5.2 Planejar os testes a serem efetuados........................................................................109 5.3 Definir as ferramentas para a automação.................................................................111 5.4 Incluir a automação no processo de desenvolvimento.............................................113 5.5 Acompanhamento e análise dos resultados..............................................................115 6 CONCLUSÃO.................................................................................................................117 REFERÊNCIAS................................................................................................................. 119
  10. 10. 10 1 INTRODUÇÃO Os autores de Engenharia de Software têm afirmado que nos últimos 40 anos as empresas vêm investido em Sistemas de Software para automatizar diversos tipos de processos de trabalho, focando nas principais atividades do seu ramo de negócio, visando melhorar a produtividade e aumentar o controle sobre o andamento do negócio. Desta forma na atualidade grande parte do trabalho relacionado a desenvolvimento de sistemas consiste em manter e evoluir estes sistemas criados ao longo do tempo. A estes sistemas que foram criados à algum tempo, dá-se o nome de Sistemas Legados1 . Alguns destes sistemas legados foram desenvolvidos com outros paradigmas de desenvolvimento apropriados a época, alguns dos quais definidos atualmente como de baixa produtividade e alto custo. As empresas continuam a manter estes sistemas legados devido a complexidade de sua substituição e sua importância muitas vezes vital para o negócio. Isto faz com que as empresas invistam muito dinheiro para poder manter e evoluir um destes sistemas legados, influindo diretamente no custo que este sistema representa. Devido as técnicas utilizadas para criar estes sistemas legados, muitas vezes a qualidade deles em comparação aos sistemas construídos na atualidade é muitas vezes menor, o que aumenta também o risco de se fazer uma manutenção ou evolução nos mesmos. 1 Sistemas Legados serão melhor explicados no item 4.
  11. 11. 11 Objetivos O objetivo principal deste trabalho é apresentar uma proposta de processo para a automação de testes nestes sistemas legados, gerando um material inicial que poderá ser utilizado para novas pesquisas nesta linha de trabalho. A proposta apresentada devido a sua dificuldade de realização não permitiu um estudo de caso que poderia gerar um resultado prático e não somente uma proposta teórica. O objetivo secundário é apresentar um material que possa ser utilizado como apoio à outros pesquisadores que precisem trabalhar com automação de testes em sistemas legados, fornecendo caminhos e referências que podem ser exploradas para a implantação desta proposta de processo. Metodologia de Trabalho Para a confecção deste trabalho, foram realizadas pesquisas bibliográficas em diversos materiais, livros e documentos encontrados em bibliotecas e na Internet. Também foram utilizados todos os materiais distribuídos ao longo das disciplinas do curso e a partir desse referencial teórico foi então desenvolvida a proposta tema desse trabalho de conclusão de curso. A figura 1 apresenta de forma gráfica e simples a estrutura do trabalho. A partir da figura é possível compreender a organização estrutural na qual o trabalho foi construído.
  12. 12. 12 Figura 1: Estrutura do trabalho
  13. 13. 13 2 SISTEMAS DE SOFTWARE Durante toda a história do desenvolvimento de sistemas de software foram utilizados diversos processos, arquiteturas e paradigmas para a construção de sistemas de software. Desta forma encontram-se atualmente sistemas de software desenvolvidos de diversas maneiras, com objetivos e fins específicos, tendo assim diversos sistemas com estruturas diferenciadas em funcionamento. Não é necessário que se domine todas estas características com profundidade, desta forma, neste capítulo será abordado um pouco sobre Processos de Desenvolvimento de Software, Arquiteturas de Software e Paradigmas de Desenvolvimento de Software. Por tratar de assuntos muito complexos, serão apresentados apenas algumas das estruturas mais comuns destas divisões dos sistemas de software. 2.1 Processos de Desenvolvimento de Software De acordo com Ian Sommerville processo de software é “um conjunto de atividades e resultados associados que produzem um produto de software”, (SOMMERVILLE, 1995). Já Roger Pressman define processo de software como “um arcabouço para as tarefas que são necessárias para construir softwares de alta qualidade”, (PRESSMAN, 2006, p.16). Desta forma, conclui-se que processo de software é um conjunto de atividades bem organizadas que geram como resultado um sistema de software de qualidade. Um processo de software apresenta uma receita para se construir um sistema de software. Esta receita pode conter atividades que trabalham em paralelo, otimizando o tempo para a construção deste software. A Engenharia de Software
  14. 14. 14 define processos para atividades como: ● Comunicação - Esta atividade envolve muita comunicação e colaboração com o cliente e outras partes interessadas2 . Esta atividade abrange todo o levantamento das necessidades do cliente entre outros. ● Planejamento - Esta atividade envolve todo o plano de trabalho que será realizado no projeto, que inclui levantar a quantidade de recursos necessários, estimar total de horas que serão gastas na realização do projeto, levantamento das atividades técnicas a serem realizadas no projeto entre outras. ● Modelagem - Esta atividade inclui a geração de modelos que expliquem tanto a equipe do projeto quanto ao cliente quais são os requisitos de software que serão atendidos com a realização do projeto. ● Construção - Esta atividade descreve o processo de desenvolvimento do código do sistema, assim como a realização dos testes que devem garantir sua funcionalidade. ● Implantação - Esta atividade define uma entrega do software ou parte dele ao cliente. A entrega pode ser de um sistema completo ou a adição de uma nova funcionalidade num sistema já existente. Quando se desenvolve um software e o mesmo é mantido, estamos de qualquer maneira trabalhando num Ciclo de Vida de Software. Na Engenharia de Software temos diversos tipos de ciclos de vida, e apesar de cada um deles ter suas características, existe um pequeno grupo que é mais difundido no mercado. A definição de Ciclo de Vida de Software segundo o Instituto de Engenharia 2 Partes Interessadas são todas as pessoas que tem um interesse na realização do projeto. Em Informática, estas pessoas são chamadas StakeHolders. Por exemplo: Gerente, Cliente e etc.
  15. 15. 15 Eletro-Eletrônica (IEEE)3 é "O período de tempo entre o software ser idealizado e o seu fim, quando o software não está mais disponível para uso", (IEEE, 1990). Com isto pode-se entender que o Ciclo de Vida é o período ao qual um software está em evolução, ou seja, ainda existem modificações sendo ou a serem feitas e ainda existe utilidade para este software no mercado. Abordaremos a seguir as variações mais comuns de Ciclo de Vida de Software, quais são as vantagens e desvantagens de cada um e daremos alguns exemplos de Ciclo de Vida em uso no mercado atualmente. Existem três ciclos de vida primários de onde surgiram quase todos os ciclos de vida existentes na atualidade. Muitos destes novos ciclos de vida foram formados a partir da mistura de três ciclos básicos: ● Ciclo de Vida Codifica-Remenda; ● Ciclo de Vida Cascata ou Clássico; ● Ciclo de Vida Iterativo. 2.1.1 Ciclo de Vida Codifica-Remenda ou Ad-Hoc O primeiro modelo de ciclo de vida e provavelmente o mais caótico deles é o normalmente chamado de "codifica-remenda" apresentado na figura 2, onde parte-se de uma especificação, quando esta existe, em muitos casos o ponto de partida é apenas um escopo definido através de uma comunicação verbal com o cliente e parte-se diretamente para a implementação, corrigindo o código a partir dos erros que vão sendo descobertos durante o desenvolvimento. Este modelo de ciclo de vida já foi e ainda é muito utilizado, devido a algumas de suas características, o que implica em muitas vezes se encontrar no mercado sistemas legados que em sua criação e/ou evolução utilizam este tipo de ciclo de 3 Institute of Electrical and Electronics Engineers será apresentado como IEEE a partir de agora.
  16. 16. 16 vida. Uma das características deste ciclo de vida que o torna tão utilizado é o prazo de entrega proporcionado por ele, como não há nenhuma exigência de planejamento, documentação ou qualidade comprovada (testes documentados, automáticos e etc...), o tempo gasto entre a concepção e a entrega é proporcionalmente menor. Este modelo de ciclo de vida entretanto ainda tem sua valia quando utilizado em algumas entregas muito pontuais, como por exemplo customizações de sistemas, adaptações emergenciais entre outras. Vantagens deste ciclo de Vida: 1. Desenvolvimento extremamente rápido; 2. Exige pouca experiência do desenvolvedor; 3. Baixo custo para entrega. Desvantagens deste ciclo de Vida: 1. Extremamente complexo para manutenção, devido a pouca documentação; 2. Probabilidade de entrega com defeitos é alta, devido a não comprovação da qualidade; Fonte: (PADUA, 2000) Figura 2: Modelo de Ciclo de Vida Codifica-Remenda
  17. 17. 17 3. A chance de haver uma falha não prevista durante a produção do sistema é alta. 2.1.2 Ciclo de Vida Cascata ou Clássico O modelo de ciclo de vida em Cascata ou Clássico que é representado pela figura 3, também é conhecido como abordagem Top-Down4 contém uma seqüência de atividades que devem ser executadas em ordem, o que permite ter pontos de controle5 entre estas atividades, o que teóricamente deixa o processo confiável e aplicável a projetos de qualquer escala. Na prática este ciclo de vida apresenta alguns problemas, como quando é aplicado ao processo, todo o sistema é planejado e documentado antes que se comece a implementar o sistema, e o cliente somente vê o resultado do trabalho após todo o sistema estar implementado e implantado. Este sistema de entrega única causa problemas pois sempre que é encontrada alguma falha em qualquer parte do ciclo, o ciclo de trabalho recomeça e os prazos de entrega do sistema são alterados, muitas vezes com a necessidade de reajustes no escopo do projeto. Outro problema é o fato do cliente apenas ver o resultado do trabalho após o término do desenvolvimento, o que muitas vezes leva a desentendimentos sobre o que foi solicitado pelo cliente e o que foi entregue no produto. 4 Top-Down que em português quer dizer "De cima para Baixo", assim como o nome "Cascata" refere-se a seqüencia como este ciclo de vida é trabalhado, sempre numa ordem única, não possibilitando mudança nesta ordem. 5 Pontos de Controle são intervalos entre entregas onde é possível avaliar possíveis informações sobre a entrega desta parte do projeto, como lições aprendidas, riscos entre outros.
  18. 18. 18 Vantagens deste ciclo de Vida: 1. Possui um tempo de planejamento reduzido; 2. Gera uma documentação detalhada do sistema; 3. Permite o trabalho com grandes equipes de desenvolvimento; 4. O processo é rastreável, o que significa que é possível saber em que momento do processo estamos. Desvantagens deste ciclo de Vida: 1. Dependência entre as fases da cascata, uma não pode começar sem que a anterior tenha terminado; 2. Gera uma grande chance de erro no planejamento já que toda a análise e documentação do sistema é gerado antes do começo da implementação; 3. Sempre que um erro é descoberto, o sistema retorna para alguma fase anterior, e o prazo de entrega deve ser reajustado, causando atrasos; 4. O cliente somente visualiza o resultado do trabalho ao final, o que normalmente gera desconforto ou desacordos na entrega do sistema. Nas fases do modelo em cascata é necessário permitir, que em fases posteriores haja revisão e alteração das fases anteriores. Uma variante que permite este tipo de alteração é o modelo Sashimi representado na figura 4, que apesar de ser um Fonte: (PADUA, 2000) Figura 3: Ciclo de Vida Clássico ou Cascata
  19. 19. 19 processo mais seguro e confiável do que o modelo Cascata puro, tende a deixar muito complexo o Gerenciamento de Projetos, (PADUA, 2000, p.24). 2.1.3 Ciclo de Vida em Espiral Um modelo de ciclo de vida que utiliza uma abordagem completamente diferente é o modelo em espiral apresentado na figura 5, este modelo é Iterativo e Incremental, e faz com que a cada Iteração, seja dada uma volta no espiral. Cada volta ao espiral envolve diversas atividades com o intuito de completar uma parte do trabalho, isto gera diversas entregas ao longo do desenvolvimento do sistema, que promovem validações a cada iteração, que por sua vez geram informações sobre o andamento do projeto e necessidades de mudanças. Uma das grandes vantagens deste processo iterativo é a possibilidade de um acompanhamento mais rígido, podendo identificar problemas logo após o sistema ter começado a ser desenvolvido, além das entregas parciais, que possibilitam ao cliente deste projeto ter a possibilidade de acompanhar a evolução e fazer criticas e sugestões de melhoria antes do custo do projeto tornar-se muito alto. O principal problema do modelo em espiral é que ele requer uma gestão muito Fonte: (PADUA, 2000) Figura 4: Ciclo de Vida Cascata do Tipo Sashimi
  20. 20. 20 sofisticada para que seja previsível e confiável. Vantagens deste ciclo de Vida: 1. Como os ciclos são curtos, a chance de encontrar um erro nos ciclos iniciais é maior, diminuindo o risco de falhas; 2. O Modelo é adaptável, permitindo que cada iteração seja customizada para a necessidade específica da mesma; 3. O cliente pode acompanhar a evolução do sistema, recebendo entregáveis; 4. Permite um maior controle de todo o processo, disponibilizando informações mais exatas da evolução do software. Desvantagens deste ciclo de Vida: 1. Por ser muito flexível, necessita de pessoas experientes para liderar o projeto; 2. Exige um controle rigoroso para que não cometam erros nas iterações; 3. Possui um tempo de planejamento considerável. Fonte: (WIKIPEDIA, 2007) Figura 5: Ciclo de Vida em Espiral
  21. 21. 21 2.2 Arquitetura de Software Conforme Dr. Rick Kazman, Dr. Paul Clements e Len Bass arquitetura de software “é a estrutura ou estruturas do sistema que abrange os componentes de software, as propriedades externamente visíveis desses componentes e as relações entre eles”, (BASS, 2003, p.21). Baseado nisto Roger Pressman complementa que “a arquitetura não é o software operacional. Ao contrário, é a representação que permite ao engenheiro de software analisar a efetividade do projeto em satisfazer a seus requisitos declarados, considerar alternativas arquiteturais em um estagio em que fazer modificações de projeto é ainda relativamente fácil, e reduzir os riscos associados à construção do software”, (PRESSMAN, 2006, 208). Os Sistemas de Software geralmente são desenvolvidos utilizando-se de uma arquitetura de software conhecida, desta forma aproveitamos as experiências existentes obtendo-se as vantagens geradas por cada uma das arquiteturas. Não existe uma melhor ou pior arquitetura, cada uma apresenta vantagens e desvantagens, e cabe a cada um escolher a que mais se adapta ao negócio que será suportado pelo sistema. Para tanto é necessário ter um conhecimento prévio dos tipos de arquitetura existentes e uma visão geral sobre como cada uma pode auxiliar numa determinada necessidade. Existem casos entretanto onde pode-se encontrar um sistema desenvolvido sob uma arquitetura mista, desta forma parte do sistema é desenvolvido numa determinada arquitetura, aproveitando assim todos os benefícios gerados por ela, e se comunica com outra parte do sistema desenvolvida numa outra arquitetura atendendo assim a necessidades específicas. Como exemplo de uma arquitetura mista, é possível imaginar um sistema para Atendimento ao Consumidor6 , que foi desenvolvido sobre a arquitetura cliente- 6 SAC – Sistema de Atendimento ao Consumidor é um sistema desenvolvido para que a
  22. 22. 22 servidor7 num primeiro estágio, onde contempla apenas as estações de atendimento gravando dados no servidor. Como apresentado na figura 6. Supondo porém, que houve uma evolução do produto e a empresa resolveu disponibilizar para seus clientes as informações de seus atendimentos na Internet. Quando a empresa verificou as premissas para a evolução, percebeu que não poderia utilizar a mesma arquitetura cliente-servidor para disponibilizar estas informações devido a problemas de segurança. Para corrigir este problema a empresa desenvolveu esta segunda parte do sistema numa outra arquitetura conhecida como arquitetura Três Camadas8 (Como apresentado na figura 7). Desta forma o sistema passou a apresentar uma solução de arquitetura mista. empresa atenda o consumidor através de um telefone fornecido. 7 Este tipo de arquitetura será melhor explicado no item 2.2.1. 8 A arquitetura Três Camadas será melhor explicada no item 2.2.2. Figura 6: Arquitetura Mista - Fase Cliente-Servidor.
  23. 23. 23 Alguns dos tipos de arquitetura existentes são: ● BlackBoard – Arquitetura baseada em multi-agentes que visa auxiliar em problemas que possuam soluções não determinísticas, (CRAIG, 1995). ● Cliente-Servidor ou Duas Camadas – Arquitetura onde a parte Servidora é basicamente um sistema gerenciador de Banco de Dados, e onde o cliente é um sistema que utiliza este Servidor, (ROMAN, 2002). ● SOA - Orientada a Serviço9 – Arquitetura voltada a serviços e é baseada em quatro chaves de abstração: FrontEnd da Aplicação, Serviço, Repositório de Serviço e Barramento de Serviço, (BLANKE, 2004). ● P2P - Pessoa para Pessoa10 - Arquitetura de aplicação distribuída que consiste em instalar dois módulos idênticos do sistema em duas máquinas diferentes, (VERMA, 2004). 9 Software Oriented Architecture é apresentado como SOA deste momento em diante. 10 Peer to Peer Architecture é apresentado como P2P deste momento em diante. Figura 7: Arquitetura Mista - Fase Final
  24. 24. 24 ● Canos e Filtros (Pipes and Filters Architecture) – Arquitetura formada por “canos e filtros”, onde interligamos os canos e o filtro é como se fosse a água passando por dentro. Os comandos UNIX são gerados a partir desta arquitetura, (L.A.S.E, 2007), (HOHPE, 2004). ● Plugin – Permite vincular executáveis a sua arquitetura, contanto que estes sigam um padrão estipulado ao desenvolver a arquitetura. Muito utilizado devido a grande flexibilidade que proporciona, (HENTENRYCK, 2006). ● Três camadas – Arquitetura Três Camadas veio basicamente para corrigir algumas limitações geradas pela arquitetura Duas Camadas, (C.M.Ua, 2007). Veremos a seguir alguns aspectos das arquiteturas mais comuns encontradas no mercado de software e como cada uma delas pode ajudar numa determinada situação. 2.2.1 Arquitetura Cliente Servidor George Schussel nos apresenta que o termo Cliente/Servidor foi utilizado pela primeira vez nos anos 80, em referência aos computadores pessoais em rede e que a atual estrutura Cliente/Servidor ganhou aceitação em meados dos anos 80, ao dar a entender que sua arquitetura possibilitava mais usabilidade, flexibilidade, interoperabilidade e escalabilidade em comparação ao centralizado Mainframe, (SCHUSSEL, 2007). A arquitetura Cliente/Servidor é um tipo de arquitetura Multi-Camadas que tem seu foco em separar a parte servidora da parte cliente, mesmo que estas estejam instaladas na mesma máquina. A parte Servidora neste caso é simplesmente o Sistema Gerenciador de Banco de
  25. 25. 25 Dados(SGBD), que disponibiliza e controla o acesso por parte do Cliente as informações necessárias. Os SGBDs evoluíram com o passar do tempo e passaram a permitir a implementação de regras de negócio diretamente no Banco de Dados através do uso de Funções, Procedures e Triggers, (HARRINGTON, 2002). A parte Cliente é responsável então pela interface disponibilizada para o usuário, validações das informações de entrada e dependendo da forma com que foi projetado o sistema esta camada contém também todas as regras de negócio incluindo as buscas de dados ao SGBD. O esquema básico de sistema Cliente/Servidor não apresenta nada a respeito da distribuição dos componentes, (ROMAN, 2002, Pag. 124). Porém os dois tipos mais comuns desta distribuição são apresentados nas figuras 8 e 9. Fonte: (ROMAN, 2002) Figura 8: Exemplo de Modelo Cliente-Servidor Distribuído
  26. 26. 26 A arquitetura Cliente/Servidor foi a primeira arquitetura de sistemas de informação que suportaram a Internet, (LERNER, 2000, p.115). Em relação a Internet, a arquitetura Cliente/Servidor trabalha fazendo com que a parte Cliente envie requisições11 ao servidor através de Objetos de Internet que são respondidas12 por sua vez pela parte Servidora, (LERNER, 2000, p.115). É possível entender Objetos de Internet como figuras, vídeos, sons e outros objetos que trafegam através das respostas do Servidor. Este sistema funcionou muito bem durante algum tempo, entretanto esta arquitetura passou a gerar problemas de escalabilidade quando a quantidade de requisições e o tamanho dos objetos de Internet cresceram. Para solucionar este problema a arquitetura Cliente/Servidor foi estendida com Proxies que ficam localizados entre a máquina cliente e o servidor. Estes Proxies guardam os objetos que trafegam entre Clientes e Servidores fazendo com que a requisição do cliente não precise chegar ao servidor para ser retornada, diminuindo assim a quantidade de requisições efetuadas entre a parte 11 Estas requisições também são conhecidas como Requests 12 Estas respostas também são conhecidas por Responses Fonte: (ROMAN, 2002) Figura 9: Exemplo de Modelo Cliente-Servidor de Banco de Dados Remoto
  27. 27. 27 Cliente e a parte Servidora. 2.2.2 Arquitetura Três Camadas Esta arquitetura também é um tipo de Arquitetura Muilti-Camadas e muitos a consideram uma evolução da arquitetura Cliente/Servidor. Segundo Hugh E. Williams e David Lane “a base da aplicação é a camada de Banco de Dados, consistindo no SGBD que gerencia o Banco de Dados contendo criação dos usuários de dados, atualização, exclusão e query13 . Construído acima da camada de Banco de Dados, temos uma complexa camada intermediária que contém muito da lógica da aplicação e faz toda a comunicação entre as outras camadas. Acima temos a camada de Cliente, normalmente um Software de Web Browser que interage com a aplicação”, (WILLIAMS, 2002, p.2). Esta mesma divisão apresentada por Hug E. Williams e David Lane pode ser vista na figura 10. 13 Query é a definição dada as consultas efetuadas nos Bancos de Dados através de uma linguagem específica Fonte: (WILLIAMS, 2002) Figura 10: Arquitetura Três Camadas numa aplicação baseada em Web
  28. 28. 28 Com base nas informações acima é possível entender que uma arquitetura três camadas é uma arquitetura onde se divide o sistema em três partes, sendo a primeira a parte do Banco de Dados que deveria conter muito pouca ou nenhuma regra de negócio, sendo responsável apenas pelos dados do sistema, uma segunda camada que contém toda a regra de negócio do sistema e que somente ela efetua acessos a camada de Banco de Dados para efetuar as transações e uma camada final onde se tem uma aplicação Cliente que também deve conter pouca ou nenhuma regra de negócio e que tem como função principal ser a interface da aplicação para o usuário final. É muito comum acreditar que a camada Cliente deve ser obrigatoriamente um Software de Web Browser, o que não é verdade pois se pode ter numa arquitetura Três Camadas qualquer aplicação como cliente, contanto que obedeça a formação das três camadas cada uma com suas responsabilidades definidas como apresentado anteriormente. A arquitetura três camadas é usada efetivamente para suprir deficiências da arquitetura Cliente/Servidor, onde comparado com a arquitetura Cliente/Servidor a arquitetura Três Camadas apresenta uma melhor performance, flexibilidade, manutenabilidade, reusabilidade e escalabilidade, enquanto esconde a complexidade do processamento distribuído do usuário, (C.M.U, 2007). 2.2.3 Arquitetura Orientada a Serviços Segundo Norbert Bieberstein “o maior propósito da arquitetura orientada a serviço é oferecer sinergia entre os negócios e os grupos de TI na organização e oferecer para a organização maior flexibilidade...”, (BIEBERTEIN, 2006, p.35). Desta forma é possível compreender que uma das idéias principais da Arquitetura Orientada a Serviço (SOA) é facilitar a comunicação entre as pessoas de TI e as pessoas de negócio. A maneira proposta para isto é que todas as chamadas ao sistema sejam feitas através de chamadas de negócio, facilitando para que
  29. 29. 29 qualquer pessoa de negócios consiga entender o que está acontecendo naquela interação com o sistema através das chamadas efetuadas. Como complemento a idéia acima, Jeffrey Hasan e Mauricio Duran definem que “Arquitetura Orientada a Serviço(SOA) representa um novo e envolvente modo de construir aplicações distribuídas” e que os serviços são “componentes distribuídos que provem uma interface bem definida dos processos e trafega as mensagens através de XML”, (HASAN, 2006, p.1). Desta forma entendemos que além da comunicação com o sistema ser feita através de chamadas de negócio, toda a informação trafegada entre elas é feita através da linguagem de marcação XML14 . Tecnicamente Jeffrey Hasan e Mauricio Duran explicam que “SOA é como outras arquiteturas distribuídas que permite a você construir aplicações que utilizam componentes em domínios separados. SOA utiliza Web Services como aplicação entre os pontos, que são conceitualmente equivalentes a componentes proxy e stub dos tradicionais sistemas distribuídos baseados em componentes, exceto que a interação entre um provedor Web Service e o cliente é mais fracamente acoplado”, (HASAN, 2006, p.2). Desta forma compreendemos que SOA trabalha com componentes distribuídos, fornecendo como interface de comunicação os serviços de negócio escritos na linguagem XML, e que a comunicação efetuada entre eles é através de Web Services que é uma solução adotada para a integração de sistemas e na comunicação entre aplicações diferentes, o que permite independência de tecnologia entre as aplicações que estão conversando. A figura 11 mostra em detalhes os domínios do SOA. Um segundo grande benefício da arquitetura SOA é a possibilidade de integração entre diferentes tecnologias, diferentes paradigmas de programação e diferentes 14 eXtensible Markup Language(XML) é uma recomendação da W3C para gerar linguagens de marcação para necessidades especiais
  30. 30. 30 estruturas já que toda sua comunicação é feita através de mensagens de texto no formato XML. Para se tornar tão flexível e escalável, o modelo SOA utilizou de recursos avançados que prejudicaram alguns outros pontos. O maior destes pontos foi a performance devido ao uso constante de XML, o que consome bastante recurso do sistema. A escalabilidade disponibilizada pela arquitetura permite que este problema seja distribuído e desta maneira reduzido, porém não elimina o risco de problemas de performance acontecerem dependendo de como for arquitetado o sistema. 2.3 Paradigmas de Desenvolvimento de Software Segundo John Hunt, “um paradigma de programação envolve uma filosofia particular. Estas filosofias normalmente representam uma introspecção a um Figura 11: Representação de um esquema Básico SOA
  31. 31. 31 grupo de novos tipos de melhores práticas. Para uma linguagem de programação suportar um paradigma em particular, ela deve não somente adotar este paradigma (você pode utilizar técnicas de programação orientada a objetos em assembler, mas você gostaria de fazer isso?), ela deve apoiar ativamente a implementação baseada no paradigma. Isto normalmente significa que a linguagem deve suportar construções que criem o desenvolvimento usando um paradigma claro”, (HUNT, 2002, p.3). Conforme apresentado, o paradigma de desenvolvimento é a forma de pensar, planejar e criar um sistema, desta forma eles trabalham como sendo uma série de regras que defendem uma forma de pensar. Assim como diferentes grupos de engenharia de software propõem diferentes metodologias, diferentes linguagens de programação propõem diferentes paradigmas de programação. Algumas das linguagens de programação podem ser implementadas em mais de um paradigma de programação, como exemplo as linguagens C++ e Delphi que podem ter seus códigos implementados tanto no paradigma estruturado como no paradigma orientado a objetos. Entretanto o mais comum é uma linguagem suportar apenas um tipo de paradigma de desenvolvimento. A maioria dos paradigmas de programação que surgiram em ciências da computação são os apresentados abaixo: (HUNT, 2002, p.3) ● Paradigma Funcional – Lisp é um exemplo clássico de linguagem funcional, embora não seja a única. Estas linguagens dão ênfase em aplicar funções (freqüentemente recursivas) para um grupo de um ou mais itens de dados. A função então retorna um valor – o resultado avaliado da função. Se a função mudar os itens de dados, este é um efeito colateral. Há um apoio limitado para soluções algorítmicas que contam com repetição via interação.
  32. 32. 32 ● Paradigma Procedural – Pascal e C exemplificam linguagens procedurais, que tentam trabalhar num nível mais alto anterior a linguagem assember. A ênfase está em soluções algorítmicas e procedimentos que operam em itens de dados. Eles são extremamente efetivos, mas desenvolvedores de software ainda encontram dificuldades. Isto acontece em partes pelo aumento da complexidade ao longo do desenvolvimento de sistemas. Entretanto, linguagens procedurais de alto nível removem a possibilidadereferencia de alguns tipos de erros e aumentam a produtividade, os desenvolvedores podem ainda encontrar problemas por eles mesmos. Por exemplo, as interfaces entre diferentes partes do sistema podem ser incompatíveis e isto pode não ser obvio até a integração do sistema ou seus testes. ● Paradigma Modular – Em linguagens como Modula-2 e Ada, o módulo esconde os dados dos usuários. Os usuários dos módulos podem apenas acessar os dados por interfaces definidas. Estas interfaces são “publicadas” então os usuários sabem as definições encontradas na interface e podem checar se eles estão usando as versões corretas. ● Paradigma Orientado a Objetos – Este é o mais recente paradigma de programação “comercial”. A aproximação da orientação a objetos pode ser vista trazendo mais ainda a modularização. Não somente você tem que explicitar módulos (neste caso objetos), mas estes objetos podem herdar características de outros. Nós podemos é claro perguntar “Porque outro paradigma de programação?”. A resposta para isto está no fracasso de muitos projetos de desenvolvimento de software que erraram ao manter um planejamento, permanecer dentro do prazo e dar aos usuários o que eles querem. É claro, não podemos assumir que a orientação a objetos é a resposta para todos estes problemas, esta é apenas outra ferramenta disponível para os desenvolvedores de software. É detalhado neste caso o paradigma mais atual que compõe a maior parte dos
  33. 33. 33 sistemas que estão sendo desenvolvimento na atualidade, o paradigma orientado a objetos. 2.3.1 Paradigma Orientado a Objetos Segundo Ivan Ricarte “o termo orientação a objetos pressupõe uma organização de software em termos de coleção de objetos discretos incorporando estrutura e comportamento próprios”, (RICARTE, 2007). Desta forma é possível compreender que a orientação a objetos define um grupo de objetos que interagem entre si e onde cada um apresenta um comportamento próprio dentro desta estrutura e organização. “Um objeto é uma entidade do mundo real que tem uma identidade. Objetos podem representar entidades concretas (um arquivo no meu computador, uma bicicleta) ou entidades conceituais (uma estratégia de jogo, uma política de escalonamento em um sistema operacional). Cada objeto ter sua identidade significa que dois objetos são distintos mesmo que eles apresentem exatamente as mesmas características” e “A estrutura de um objeto é representada em termos de atributos. O comportamento de um objeto é representado pelo conjunto de operações que podem ser executadas sobre o objeto”, (RICARTE, 2007). Neste caso é possível entender que um objeto é composto por atributos que apresentam as características do objeto, os comportamentos que são as ações que este objeto pode executar e o estado do objeto que apóia a manter a sua identidade. Existem algumas outras terminologias importantes na orientação a objetos que são importantes de se conhecer: (HUNT, 2002, p.21) ● Classe – A classe defina a combinação de dados e processos que operam estes dados. Instâncias de outras classes somente podem acessar esses dados ou processos por interfaces específicas. A classe não mantém
  34. 34. 34 nenhum dado, mas é específica aos dados mantidos na instância. ● SubClasse – Uma subclasse é uma classe que herda de outra classe. ● SuperClasse – É a classe pai de outra classe. Isto é a classe da qual a classe em questão herda. ● Instância ou Objeto – A instância é o exemplo de uma classe. Todas as instâncias da classe processam variáveis de dados parecidos, mas processam seus próprios dados. Cada instância da classe responde aos mesmos conjuntos de requisições. ● Instância Variável – Este é um nome especial dado aos dados mantidos num objeto. O “estado” de um objeto num momento particular revela os valores atuais mantidos por esta instância de variável. ● Método – O método é um processo definido num objeto. Em versões anteriores do Smalltalk os métodos eram utilizados para pedir ao objeto para fazer algo e retornar algo. Isto tem se tornado mais largamente utilizado; Linguagens como CLOS e Java também utilizam o termo. ● Mensagem – Um objeto manda mensagens para outro objeto solicitando alguma operação ou dado. A mensagem pode ser considerada parecida como uma chamada de processo em outras linguagens. ● This – Uma (pseudo) variável especial, this, é a referência ao objeto do qual o método é chamado. Isto permite enviar mensagens para “this” (o próprio) objeto. ● Herança simples ou múltipla – Herança simples ou múltipla se refere ao número de superclasses de qual a classe pode herdar. Java é um sistema baseado em herança simples, da qual uma classe pode herdar apenas de
  35. 35. 35 uma classe. C++ é um sistema baseado em herança múltipla onde a classe pode herdar de uma ou mais classes. Muitas das definições apresentadas acima estão ilustradas nas figuras 12 e 13, onde é possível visualizar as heranças das classes na figura 12 e as partes que compões uma classe na figura 13. Fonte: Adaptado de (HUNT, 2002, p.22) Figura 12: O relacionamento entre Classe, SubClasse e SuperClasse Fonte: Adaptado de (HUNT, 2002, p.23) Figura 13: Definição parcial de uma classe java
  36. 36. 36 Uma outra característica importante é o conceito de polimorfismo. John Hunt apresenta em outro texto uma definição de polimorfismo como sendo “uma palavra que soa estranho, derivada do grego15 , para um conceito relativamente simples. Isto é essencialmente a habilidade de requisitar que a mesma operação seja respondida de muitas maneiras diferentes. A forma que a requisição é processada depende da coisa que foi passada na solicitação. O desenvolvedor não precisa se preocupar de como a informação é manipulada, ela simplesmente é”, (HUNT, 2002, p.7). Desta forma ele apresenta o conceito de polimorfismo como sendo a habilidade de se trabalhar de diversas formas uma mesma solicitação, e a forma como esta solicitação é processada depende apenas do tipo de parâmetro que foi informado na chamada da operação. Por exemplo, se existe um método “dirigir” para uma classe do tipo veículo, a forma como o veículo será dirigido depende do objeto que será informado como parâmetro, ou seja, se eu informar um objeto do tipo carro para a chamada do método “dirigir” eu estarei dirigindo um carro, no entanto se eu passar um objeto do tipo trator para a chamada do método, eu estarei dirigindo um trator. Além das definições apresentadas, existem mais algumas definições importantes na orientação a objeto, que são: (RICARTE, 2007) ● Encapsulamento - também referido como esconder informação, consiste em separar os aspectos externos de um objeto, os quais são acessíveis a outros objetos, dos detalhes internos de implementação do objeto, os quais permanecem escondidos dos outros objetos. O uso de encapsulamento evita que um programa torne-se tão interdependente que uma pequena mudança tenha grandes efeitos colaterais. ● Ligações e associações - São os mecanismos para estabelecer relacionamentos entre objetos e classes. Uma ligação é uma conexão física ou conceitual entre duas instâncias de objetos. 15 Polymorphos significa “tem muitas formas”.
  37. 37. 37 ● Agregação - É um relacionamento do tipo “uma-parte-de”, nos quais objetos representando os componentes de alguma coisa são associados com objetos representando uma montagem. Por exemplo, o texto de um documento pode ser visto como um conjunto de parágrafos, e cada parágrafo é um conjunto de sentenças. ● Generalização - É o relacionamento entre uma classe e um ou mais versões refinadas (especializadas) desta classe, ou seja, o relacionamento entre uma superclasse e uma classe é que a superclasse é uma generalização da classe.
  38. 38. 38 3 QUALIDADE Stephen H. Kan diz que “o maior problema na engenharia e gerenciamento da qualidade é que o termo qualidade é ambíguo para nós, sendo assim é comumente mau compreendido. A confusão pode ser atribuída a várias razões”, (KAN, 2002). As razões dadas por ele para a confusão com o termo qualidade são as seguintes: 1. Qualidade não é uma idéia simples, mas sim um conceito multi dimensional; 2. Para qualquer um dos conceitos apresentados, existem níveis de abstração; 3. O termo qualidade faz parte do nosso uso diário e seu significado popular e profissional podem ser muito diferentes. Como é possível perceber qualidade é extremamente abrangente, devido a isto este capítulo foca alguns conceitos básicos sobre qualidade de software, testes de software e automação de testes de software. O intuito com isto é ter uma base firme sobre o que é qualidade de software e o que ela abrange, o que são testes de software e como estes podem ser aplicados nos diferentes tipos de software além de como e porque podemos automatizar testes de software. 3.1 Qualidade de Software A norma ISO/IEC 9126 apresenta na introdução de seu texto que os “computadores começaram a ser usados por uma crescente variedade de
  39. 39. 39 aplicações em diversas áreas, e o correto funcionamento destas operações é critica tanto para os negócios quanto para a segurança humana. Desenvolver ou escolher produtos de software de alta qualidade portanto é de suma importância”, (ISO/IEC, 2001). Assim como apresentado, a importância da qualidade do software é muito grande, onde suas falhas podem gerar desde prejuízos financeiros e até mesmo falecimento de uma pessoa dependendo do tipo de atividade que o sistema emprega, porém deve-se lembrar que implementar qualidade de software tem alto custo que pode ser mais ou menos justificado de acordo com o ramo de negócio ao qual o software pertence. Stephen H. Kan nos adverte dizendo que “o mais estreito senso de qualidade de produto está diretamente ligado a um leque de erros no produto. Este é apenas o significado mais básico de conformidade com os requisitos, porque se o software contém muitos defeitos funcionais, o requisito desejado não está sendo atendido”, (KAN, 2002). Desta forma é possível compreender que a qualidade do software está diretamente ligada aos requisitos de sistema que foram definidos para este software e que desta forma o padrão mínimo de qualidade que se espera de um sistema é que ele atenda a todos os requisitos definidos. Ao olhar qualidade de software por uma visão um pouco mais abrangente pode- se perceber que não se deve preocupar somente com o teste do produto de software em si, mas sim com todo o processo de construção do software. Como descrito acima, sabe-se que a qualidade do software depende da qualidade dos requisitos que estão sendo disponibilizados para que o software seja desenvolvido, então deve-se considerar que a qualidade do requisito de software também faz parte da qualidade de software, e desta forma é necessário preocupar-se com o processo de desenvolvimento como um todo ao invés de se
  40. 40. 40 preocupar apenas com a quantidade de Bugs16 encontrados após o desenvolvimento do sistema. Pensando neste problema, John W. Horch aponta em seu livro que os elementos para a qualidade de um sistema de software são: Padrões, Revisões, Testes, Analise dos Defeitos, Gerencia de Configuração, Segurança, Educação, Gerencia de Vendas, Segurança e Gerencia de Riscos e cita ainda algumas adicionais como Manutenção, Documentação, Considerações Organizacionais e a Implementação de um Sistema Total de Qualidade de Software (HORCH, 2003). Baseado nas preocupações acima, e visto que é possível ter um controle de qualidade de software maior do que apenas a validação do produto resultante do processo de desenvolvimento, a ISO/IEC criaram as normas 9126 e 14598 que podem ser encaixadas no processo de desenvolvimento permitindo o acompanhamento desta qualidade de software em diversos momentos da construção do sistema, como apresentado na figura 14. 16 Bugs é o termo apresentado para uma falha ou erro encontrado no sistema Fonte: (ISO/IEC, 2001) Figura 14: Relacionamento entre os padrões ISO/IEC 9126 e ISO/IEC 14598
  41. 41. 41 Stephen H. Kan nos apresenta ainda que a qualidade de software é divida em dois níveis: Qualidade Intrínseca do Produto e Satisfação do Cliente, (KAN, 2002). A qualidade intrínseca do produto é normalmente medida através do número de erros existentes no projeto ou por quanto tempo esse sistema consegue executar antes que seja encontrada uma falha grave no sistema. Já a satisfação do cliente para ser avaliada depende de pesquisa em campo para levantamento e avaliação das informações coletadas. 3.1.1 Atributos de Qualidade de Software Stephen H. Kan nos diz que “Além de satisfação total do cliente com o produto de software, satisfação em direção a atributos específicos também é estimada”, (KAN, 2002). Com o texto acima é apresentado que não basta apenas atender os requisitos de sistema para garantir a satisfação do cliente em relação ao produto de software, mas que se deve atender alguns outros atributos considerados pelos clientes. Ele também complementa dizendo que “estes atributos de qualidade não são sempre do mesmo tipo. Por exemplo, quanto mais alta a complexidade funcional do software, mais difícil torna-se alcançar manutenabilidade. Dependendo do tipo de software e do cliente, diferentes atributos de qualidade serão necessários”, (KAN, 2002). Alfs T. Berztiss diz que “um interesse da engenharia de requisitos é a ordenação destes atributos de qualidade em ordem de importância para o particular software em consideração, lembrando que o mais importante atributo de qualidade é a aceitação do usuário”, (BERZTISS, 1996, p.73). Considerando o texto acima, é possível entender que não existe um padrão de atributos que devem ser respeitados em todos os projetos, mas sim que existem
  42. 42. 42 atributos que deverão ser considerados para um determinado projeto. Apresenta também que existem organizações interessadas em agrupar e organizar esses atributos gerando padrões. Para a organização dos atributos existem pelo menos duas classificações básicas para eles: 1. Funcionais – São aqueles atributos que pertencem a funcionalidade do sistema, normalmente são estes atributos que recebem boa parte da atenção pois eles estão diretamente ligados aos requisitos identificados para o sistema; 2. Não Funcionais – São a grande maioria e que estão implícitos na entrega, algumas vezes eles são solicitados pelo usuários e outras vezes não, porém podemos perder todo o trabalho de desenvolvimento do sistema ao desconsiderar um destes atributos. Exemplo: Performance, Usabilidade, etc. A IBM por exemplo utiliza um grupo destes atributos que recebe o nome de CUPRIMDSO, que atualmente foi atualizado para uma nova versão com o nome de CUPRIMDSAPI que significa: (IPCOM, 2007) ● Capability (Capacidade) – Funcionalidade do sistema, ou seja, atender aos requisitos funcionais; ● Usability (Usabilidade) – Quão intuitivo e fácil é o sistema para o usuário final; ● Performance – Tempo de resposta do sistema para o usuário final; ● Reliability (Confiabilidade) – Livre de Falhas Operacionais, significa o tempo entre as falhas; ● Installability (Instalabilidade) – De fácil instalação e configuração para uso. ● Maintainability (Manutenabilidade) – Facilidade de corrigir problemas e facilidade para criar e aplicar patchs17 de correção. 17 Patch, que significa Remendo em português é um pacote pequeno contendo uma atualização ou mais comumente correções a um sistema de software.
  43. 43. 43 ● Documentation/Information (Documentação/Informação) – Guias e Publicações, Telas de ajuda em tempo real, ou seja, facilidade de encontrar informação relevante na documentação existente e a efetividade destas informações. ● Service (Serviço) – Facilidade na identificação e diagnóstico de problemas. Facilidade para transportar esses problemas de suporte para central de atendimento. ● Availability (Disponibilidade) – Habilidade do produto se manter útil ao passar do tempo, preocupação com os outros atributos ao longo do tempo de uso deste sistema. ● Personas (Imagens) – Preocupação do uso do produto por classes específicas de clientes (Administrador, Operador, Cliente, etc..) ● Interoperability (Interoperabilidade) – Facilidade de integração com outros produtos. Habilidade de receber, processar e transmitir dados para outros sistemas. Já a FURPS que é um modelo para classificar atributos de qualidade de software criado pela HP(Hewlett-Packard) e muito utilizado pelo mercado: ● Functionality (Funcionalidade) – Representa todos os requisitos funcionais; ● Usability (Usabilidade) – Recursos como Ajuda, o sistema ser intuitivo ao usuário, acessibilidade; ● Reliability (Confiabilidade) – Requisitos de confiabilidade como por exemplo capacidade de recuperação após uma falha, tolerância as falhas e etc; ● Performance – Requisitos de desempenho como eficiência, consumo de recursos do equipamento e tempo de resposta por exemplo; ● Supportability (Suportabilidade) – Requisitos de suporte como facilidade de manutenção/configuração, internacionalização, compatibilidade, manutenabilidade e etc.
  44. 44. 44 3.2 Métricas de qualidade de software Stephen H. Kan diz que “métricas de software podem ser classificadas em três categorias: métricas de produto, métricas de processo e métricas de projeto”, (KAN, 2002). E explica dizendo que “Métricas de qualidade de software são um subgrupo de métricas de software com um foco nos aspectos da qualidade do produto, do processo e do projeto. Em geral, métricas de qualidade de software são mais vinculadas as métricas de processos e produtos do que as métricas de projetos”, (KAN, 2002). Dentro dessa divisão: ● As métricas de produto descrevem características do produto como tamanho, complexidade, características de layout, performance e nível de qualidade. ● Métricas de processo podem ser utilizadas para melhorar o desenvolvimento e manutenção. Exemplos incluem a eficácia de remoção de erros durante o desenvolvimento, o padrão de nível de defeito e o tempo de resposta do processo de correção do erro. ● Métricas de projeto descrevem as características e a execução do projeto. Exemplos incluem o número de desenvolvedores de software, custo, agendamento e produtividade. E ele complementa descrevendo que “algumas métricas podem ser aplicadas a múltiplas categorias. Por exemplo a métrica de improcess quality18 de um projeto são ambos métrica de processo quanto métrica de projeto”, (KAN, 2002). Dentro destas métricas de processos, produtos e de projetos, são classificados três grupos de avaliação principal, nos quais estão os Defeitos, Problemas do 18 Não foi possível encontrar um termo adequado para a tradução desta métrica.
  45. 45. 45 Cliente e Satisfação do Cliente. Cada um tem um escopo bem definido, como é apresentado na figura 15. 3.2.1 Métrica de Defeito Segundo Stephen H. Kan, para definir o indicador, primeiro precisa-se gerar o numerador e o denominador e especificar o espaço de tempo, (KAN, 2002). São apresentados abaixo cada uma das variáveis necessárias para que seja gerado o indicador: ● O numerador neste caso é o número de defeitos válidos, ou seja, o número conhecido de erros do sistema. ● O denominador é o tamanho do software, normalmente expressado em milhares de linhas de código ou no número de pontos de função. ● Em termos de espaço de tempo, várias definições podem ser utilizadas contando com o tempo a partir do lançamento do produto ao mercado. Conta-se normalmente dois anos para sistemas de softwares. Fonte: Adaptado de (KAN, 2002) Figura 15: Escopo das Três Métricas de Qualidade
  46. 46. 46 Este indicador é dependente de diversas informações para poder ser calculado e requer um esforço relativo dos técnicos para sua implantação. Para calcular o numerador por exemplo deve-se ter um controle dos defeitos do sistema de forma atualizada e eficiente, para que o indicador resultante dos cálculos sejam válidos e de uso confiável. Entretanto para efetuar o cálculo ideal da quantidade de defeitos do sistema, não se pode apenas confiar na perspectiva do desenvolvedor, a melhor maneira então de gerar o número de defeitos é em relação a perspectiva do cliente, (KAN, 2002). Para calcular o valor do denominador deve-se escolher uma das técnicas existentes, das quais é possível citar como exemplo o cálculo de tamanho do sistema através das linhas de código, que seguem algumas regras específicas para sua geração. Manter esses valores atualizados e confiáveis é tão importante quanto manter um controle exemplar dos defeitos do sistema. Com base no resultado deste indicador, é possível ter um controle real de como anda a “saúde” do software em questão, além de haver a possibilidade de estimar quantos defeitos poderão ser encontrados numa próxima versão do software, utilizando a base histórica dos defeitos por tamanho de software. 3.2.2 Métrica de Problemas do Cliente Esta métrica foca principalmente nos problemas identificados pelo cliente durante o seu uso, ao contrário da métrica de defeito onde apenas alguns tipos de erros encontrados no sistema são selecionados para entrar no cálculo do indicador, na métrica de problemas do cliente todos os problemas devem ser levados em consideração, com algumas exceções. “Problemas que não são considerados defeitos válidos podem ser problemas de
  47. 47. 47 usabilidade, documentação ou informação incorreta, duplicidade de defeitos válidos, e erros do usuário”, (KAN, 2002). Esta métrica é normalmente calculada utilizando-se a fórmula de Problemas por Usuário Mês(PUM)19 , apresentada abaixo: No caso da fórmula acima, tem-se que do total de defeitos reportados pelo cliente no período são considerados apenas os defeitos válidos que se enquadram na citação acima. e onde: “PUM normalmente é calculado durante cada mês depois que o software é liberado ao mercado e também para retirada de médias mensais por ano”, (KAN, 2002). Stephen H. Kan indica também três atividades que auxiliam a diminuir o valor do PUM: (KAN, 2002) 1. Melhore o processo de desenvolvimento e reduza os defeitos do produto. 2. Reduza os problemas não orientados a defeito melhorando todos os aspectos do produto (tal como usabilidade, documentação), educação de cliente, e suporte. 19 Problemas por Usuário Mês foi retirado do termo “Problems per User Mounth”, por isso a sigla original PUM PUM = Total de Defeitos Reportados pelos Clientes num período de tempo + Total de Licenças por Mês referente ao mesmo período Número de Licenças por Mês = Número de Licenças Instaladas do Software X Número de Meses do período de cálculo
  48. 48. 48 3. Aumente a venda (o número de licenças instaladas) do produto. Com a execução dos itens um e dois indicados consegue-se diminuir o valor do indicador PUM, já com o item três o resultado que se obtem é um aumento no denominador de cálculo da fórmula, o que auxilia na confiabilidade do resultado uma vez que por quanto mais clientes o software for utilizado, mais consistente será seu valor. É necessário lembrar que apesar deste indicador poder ser gerado sem o indicador anterior e apresentar algum resultado, são obtidos apenas dados comparativos de interesse real quando se segue a dependência apresentada na Figura 15. Com esta métrica é possível ter uma estimativa aproximada de como a evolução do software está acontecendo numa visão mais macro do que em relação a métrica de defeitos, em compensação o resultado deste indicador é totalmente dependente de ações efetuadas diretamente sobre o produto que podem ser decisões tomadas a partir da análise do resultado da métrica de defeitos. 3.2.3 Métrica de Satisfação do Cliente Esta é uma métrica normalmente baseada em pesquisa de campo, onde a empresa entra em contato com seus clientes e faz perguntas com o objetivo de pontuar a satisfação do cliente numa faixa. “Satisfação do cliente é freqüentemente medida por pesquisas de cliente numa escala de cinco pontos”, (KAN, 2002). Ele apresenta os cinco pontos da escala de satisfação como sendo: ● Very satisfied (Muito Satisfeito) ● Satisfied (Satisfeito)
  49. 49. 49 ● Neutral (Neutro) ● Dissatisfied (Insatisfeito) ● Very dissatisfied (Muito Insatisfeito) Baseado nos dados resultantes desta pesquisa da escala dos cinco pontos, ele sugere também alguns possíveis indicadores a serem retirados e afirma que vários outros podem ser encontrados com os dados da pesquisa. Entretanto ele aponta quatro exemplos de informações obtidas a partir da pesquisa: 1. Porcentagem de Completa Satisfação dos Clientes. 2. Porcentagem de Clientes Satisfeitos (Contém os satisfeitos e os completamente satisfeitos). 3. Porcentagem dos Clientes Insatisfeitos (Insatisfeitos e Complemente Insatisfeitos). 4. Porcentagem de Clientes não Satisfeitos (Neutros, Insatisfeitos e Completamente Insatisfeitos). “Normalmente a segunda métrica, porcentagem de satisfação, é utilizada. Na pratica o foco é em reduzir a porcentagem de insatisfação”, (KAN, 2002). Como apresentado acima, com o resultado obtido nestas pesquisas é possível gerar alguns indicadores que acompanham os apresentados anteriormente. Quando o valor do indicador de problemas do cliente diminuir, e o indicador de defeitos no sistema diminuir, conseqüentemente o indicador de porcentagem de clientes satisfeitos deveria aumentar. A conclusão acima pode parecer obvia, porém pode-se ter a situação onde os primeiros indicadores foram reduzidos e o de porcentagem de clientes satisfeitos
  50. 50. 50 não subiu. Segue alguns casos onde isto poderia ocorrer: 1. A qualidade do Software melhorou, porém requisitos não funcionais20 (RNF) não estão sendo verificados. 2. A qualidade do software melhorou e ele tem atendido aos RNF, porém o cliente está descontente com o manual de ajuda, com o atendimento do suporte técnico ou com o preço do sistema. Assim como os exemplos acima, muitas outras informações podem ser obtidas a partir de análises macro como estas. É devido a estas necessidades que empresas como a IBM e a HP investem no CUPRIMDSAPI e no FURPS como apresentado anteriormente21 . 3.3 Estratégias de Teste de Software Roger Pressman apresenta que “uma estratégia de teste de software integra métodos de projeto de casos de teste em uma série bem planejada de passos, que resultam na construção bem-sucedida de software. A estratégia fornece um roteiro que descreve os passos a ser conduzidos como parte do teste, quando esses passos são planejados e depois executados, e quanto de esforço, tempo e recursos serão necessários. Assim, qualquer estratégia de teste deve incorporar planejamento de teste, projetos de casos de teste, execução de teste e a coleta e avaliação dos dados”, (PRESSMAN, 2006, p.288). Conhecer as estratégias de teste é fundamental para que seja possível compreender o que deverá ser testado no sistema e o que não deverá. Como apresentado anteriormente não é viável implementar uma estratégia de teste sem que haja um planejamento prévio. Desta forma, a estratégia de testes mostra o 20 Requisitos não funcionais (RNF) são requisitos de sistema que não dizem respeito diretamente as funcionalidades, mas que são de extrema importância para o bom funcionamento e para atender as necessidades dos usuários. Como exemplos temos: Performance, Usabilidade, e etc... 21 Detalhes desta informação foram citados no item 3.1.1
  51. 51. 51 que pode ser testado no sistema de software. A definição do RUP (Rational Unified Process) para casos de teste “é a definição (geralmente formal) de um conjunto específico de entradas de teste, condições de execução e resultados esperados, identificados com a finalidade de avaliar um determinado aspecto de um Item de teste-alvo”, (WTHREEX, 2007). Apesar de existir uma forma única documentar o planejamento dos testes (Casos de Teste) independentemente da estratégia adotada, é de extrema importância que cada estratégia de teste tenha seu próprio grupo de casos de teste, escritos e planejados especificamente para aquele determinado tipo de estratégia escolhida. As estratégias de teste podem ser entendidas como diferentes níveis de abstração em que se planeja um teste, onde não existe uma estratégia de teste que garanta a cobertura de uma outra. Elas são complementares. Para fazer uma analogia do que foi apresentado, é possível imaginar que os defeitos do software são como peixes num lago, e que cada estratégia de teste é como uma das malhas que compõe a rede, elas são complementares e quanto mais malhas mais peixes são capturados. A figura 16 ilustra parte desta analogia. Figura 16: Exemplo de Rede de Pesca como Analogia as Estratégias de Teste
  52. 52. 52 Desta forma, não existe uma melhor estratégia ou uma principal pela qual se deve iniciar o trabalho, cabe a cada um conhecendo o seu negócio e seu sistema escolher qual ou quais das estratégias irá gerar maior benefício ao ser implementada. Existem diversas estratégias de teste, dentre as quais são exploradas algumas consideradas de maior utilidade prática. Para fornecer uma lista destas estratégias num agrupamento padrão torna-se difícil devido a cada autor agrupar as estratégias de teste de maneiras diferentes. Abaixo, segue uma lista seguindo o agrupamento das estratégias conforme descrito no livro de Glenford Mayers, (MAYERS, 2004): ● Teste de Unidade; ● Teste de Função; ● Teste de Sistema. ○ Teste de Facilidade ○ Teste de Volume ○ Teste de Estresse ○ Teste de Usabilidade ○ Teste de Segurança ○ Teste de Performance ○ Teste de Armazenamento ○ Teste de Configuração ○ Teste de Compatibilidade/Configuração/Conversão ○ Teste de Instalabilidade ○ Teste de Confiabilidade ○ Teste de Recuperação ○ Teste de Serviçabilidade22 ○ Teste de Documentação ○ Teste de Processo ○ Teste de Aceitação 22 Não foi encontrada uma melhor forma de traduzir “Serviceability Test”.
  53. 53. 53 Apesar de todas as estratégias citadas por Glenford Mayers, são detalhados neste trabalho os testes mais comuns encontrados no mercado de trabalho, com o objetivo de entregar a base mínima necessária para a compreensão do trabalho. 3.3.1 Teste de Unidade Roger Pressman defende que “o teste de unidade focaliza o esforço de verificação na menor unidade de projeto do software”, (PRESSMAN, 2006, p.295). Com isso entende-se que o teste de unidade utiliza a menor parte testável do sistema como seu foco de trabalho. Em teoria, o teste de unidade tem como objetivo testar isoladamente cada pequena parte do sistema que tenha uma responsabilidade, desta forma entende- se que se todas as partes do sistema estão funcionando isoladamente, existe portanto muito menos chance de erro ao se testar o sistema de forma integrada. Entretanto se há alguma destas unidades com problemas, as chances de que o sistema como um todo apresente defeitos é muito alta, desta forma deve-se descobrir e corrigir o defeito encontrado antes de passar para outras estratégias de teste mais macro. Nas linguagens convencionais a menor parte testável do sistema é o módulo, o qual é testado isoladamente dos outros, porém para as linguagens orientadas a objetos lida-se com outro paradigma que gera mais preocupações. Roger Pressman comenta que “quando é considerado o software orientado a objetos, o conceito de unidades se modifica. O encapsulamento guia a definição de classes e objetos. Isto significa que cada classe e cada instância de uma classe empacotam atributos e operações, que manipulam esses dados”, (PRESSMAN, 2006, p.302).
  54. 54. 54 Desta forma ao trabalhar com sistemas orientados a objetos passa-se a direcionar os testes de unidade para as classes do sistema, garantindo desta forma que se esteja lidando com a menor parte testável do sistema. A linguagem orientada a objetos deixa mais uma dúvida em relação aos testes de unidade, que tem a ver com a sua capacidade de trabalhar herança. Ao trabalhar com heranças, tem-se várias subclasses partilhando atributos e operações de uma superclasse. Quando é necessário testar estas classes no contexto de unidade, deve-se testar sempre as subclasses, ignorando as classes abstratas, (PRESSMAN, 2006, p.303). “A interface do módulo é testada para garantir que a informação flui adequadamente para dentro e fora da unidade de programa que está sendo testada. A estrutura de dados local é examinada para garantir que os dados armazenados temporariamente mantenham sua integridade durante todos os passos da execução de um algoritmo”, (PRESSMAN, 2006, p.295). Neste caso, tanto para as linguagens convencionais como para as orientadas a objetos, é necessário testar as possibilidades de entrada e saída da unidade de forma intensa, validando principalmente os limites oferecidos pela unidade. “Casos de teste devem descobrir erros tais como (1) comparação de tipos de dados diferentes, (2) operadores ou precedência lógica incorretos, (3) expectativa de igualdade quando o erro de precisão torna a igualdade improvável, (4) comparação incorreta de variáveis, (5) terminação de ciclo inadequada ou inexistente, (6) falha na saída quando iteração divergente é encontrada, e (7) variáveis de ciclo inadequadamente modificadas”, (PRESSMAN, 2006, p.295). Como apresentado anteriormente, para que um teste de unidade seja executado da forma adequada, é necessário executá-lo de forma isolada das demais unidades do sistema. Entretanto existem dependências entre estas unidades que
  55. 55. 55 serão testadas, e diversas vezes não há uma forma de se testar uma unidade sem sua dependência. Desta forma é necessário que sua dependência seja passada para um pseudocontrolador (Driver) e/ou um pseudocontrolado (Stub), que precisam ser criados para cada teste de unidade que for executado. “Na maioria das aplicações um pseudocontrolador nada mais é do que um 'programa principal', que aceita os dados do caso de teste, passa tais dados ao componente (a ser testado) e imprime os resultados relevantes. Os pseudocontrolados servem para substituir módulos que são subordinados (chamados pelo) ao componente a ser testado”, (PRESSMAN, 2006, p.296). Com base nisto, é possível apresentar que um Driver(pseudocontrolador) é um programa que irá chamar o componente a ser testado informando os parâmetros de entrada necessários para a validação do teste de unidade, e que depois gera o retorno deste resultado de alguma forma. E podemos dizer que um Stub(pseudocontrolado) é um programa que simula uma dependência do componente que está sendo testado, desta forma quando o componente que está sendo testado precisa chamar a dependência, o stub recebe os parâmetros do componente e retorna alguns valores pré-estabelecidos que favorecem o objetivo do teste.
  56. 56. 56 3.3.2 Teste de Integração Roger Pressman define que “teste de integração é uma técnica sistemática para construir a arquitetura do software enquanto, ao mesmo tempo, conduz testes para descobrir erros associados às interfaces. O objetivo é, a partir de componentes testados no nível de unidade, construir uma estrutura de programa determinada pelo projeto”, (PRESSMAN, 2006, p.297). A partir disto é possível entender que os testes de integração tem como objetivo principal validar se todas as interfaces de comunicação entre as unidades estão funcionando corretamente. Desta forma é possível assegurar que o sistema trabalha em conjunto e que as informações trocadas entre os módulos funcionam corretamente. Fonte: (PRESSMAN, 2006, p.297) Figura 17: Ambiente de teste de unidade
  57. 57. 57 Existem duas abordagens a serem utilizadas quando se planeja testes de integração, elas podem ser teste de integração descendente ou teste de integração ascendente. Teste de Integração Descendente No teste de integração descendente23 a integração é inciada pelo modulo de programa principal, ou seja, aquele de mais alto nível e conseqüentemente que depende de todos os outros, em seguida é adicionado um módulo subordinado a este e assim por diante. O teste de integração descendente começa seu trabalho pelo alto nível da hierarquia e faz testes em todas as regras de tomadas de decisão. Isto faz com que este teste seja muito valorizado pelos profissionais responsáveis pelas regras de negócio do sistema. Roger Pressman nos indica cinco passos para implementar uma integração descendente: (PRESSMAN, 2006, p.298) 1. O módulo de controle principal é usado como Driver24 do teste, e os Stubs são substituídos por todos os componentes diretamente subordinados ao módulo de controle principal. 2. Dependendo da abordagem de integração selecionada, os Stubs subordinados são substituídos, um de cada vez pelos componentes reais. 3. Testes são conduzidos à medida que cada componente é integrado. 4. Ao término de cada conjunto de testes, outro Stub é substituído pelo componente real. 5. O teste de regressão (Explicado no item 3.3.5) pode ser conduzido para 23 Esta abordagem é conhecida como Top-Down, de cima para baixo. 24 A explicação sobre Stubs e Drivers encontram-se no item 3.3.1.
  58. 58. 58 garantir que novos erros não tenham sido introduzidos. O processo continua a partir do item 2 até que todo o programa esteja completo. Com base nas informações acima é possível deduzir que os testes de integração são trabalhosos de se gerar, devido a isto muitas empresas acabam por simplificar os testes de integração executando os testes diretamente sobre o módulo principal e com o sistema já completo. Desta forma consegue-se o mesmo resultado testando a integração de todas as interfaces do sistema e evitando o trabalho de criação dos Drivers e Stubs fazendo com que o sistema seja testado de forma mais rápida. Esta abordagem apesar de ser muito utilizada pode trazer consequências ruins, como o objetivo dos testes de integração é descobrir problemas de comunicação entre as interfaces de comunicação, testar o sistema inteiro de uma vez pode fazer com que seja muito difícil identificar o erro quando este aparecer, pois se o erro estiver ocorrendo num dos componentes da baixa hierarquia do qual muitos dos testes dependam, todos estes testes podem apresentar erro ao final e desta forma torna-se difícil descobrir em qual interação de componentes houve o erro. Teste de Integração Ascendente No teste de integração ascendente25 a integração dos componentes é iniciada da parte mais baixa da hierarquia dos componentes. Desta forma inicia-se os testes pelas unidades que não dependam de ninguém, adicionando em seguida os seus dependentes até que o sistema esteja completo. “Como os componentes são integrados de baixo para cima, o processamento necessário para os componentes subordinados em um determinado nível está sempre disponível e as necessidades de Stubs é eliminada”, (PRESSMAN, 2006, p.299). 25 Esta abordagem é conhecida como Boton-Up, de baixo para cima.
  59. 59. 59 Roger Pressman indica 4 passos para a implementação da integração ascendente: (PRESSMAN, 2006, p.299) 1. Componentes de baixo nível são combinados em agregados (clusters, algumas vezes chamados de construções), que realizam uma subfunção específica do software. 2. Um Driver é escrito para coordenar a entrada e a saída do caso de teste. 3. O agregado é testado. 4. Drivers são removidos e agregados são combinados movendo-se para cima na estrutura do programa. Pode-se entender os agregados como sendo outras partes do software que precisam ser testados, como por exemplo os bancos de dados. Desta forma Pressman nos diz que “Cada um dos agregados é testado usando um Driver”, (PRESSMAN, 2006, p.299). Entretanto, além de testar os agregados separadamente, é preciso ligá-los aos outros testes para garantir que toda a estrutura funciona em conjunto. Algo que faz com que os testes de integração ascendentes não sejam tão utilizados quanto os testes de integração descendentes é o fato de não haver como saltar nenhuma etapa o que mantém o custo para a implantação do mesmo alta. Roger Pressman apresenta uma sugestão para diminuir este custo descrevendo que “de fato, se os dois níveis superiores da estrutura do programa são integrados descendentemente, o número de Drivers pode ser reduzido substancialmente e a integração de agregados é grandemente simplificada”, (PRESSMAN, 2006, p.299).
  60. 60. 60 Teste de Integração Orientados a Objetos Para os testes de integração em linguagens orientadas a objetos, as técnicas convencionais mencionadas não são válidas e para estes casos podemos utilizar duas abordagens: (BINDER, 1994) ● Teste Baseado no Caminho da Execução (Thread-Based Testing) – Este teste é aplicado sobre um caminho de execução do sistema, integrando todos os componentes deste caminho que são executados individualmente. O teste de regressão26 é aplicado para garantir que nenhum efeito colateral ocorra. ● Teste Baseado no Uso (Use-Based Testing) – Inicia o teste por aquelas classes (chamadas classes independentes) que usam muito poucas ou nenhuma classes servidoras. Depois que as classes independentes são testadas, a camada seguinte de classes (chamadas classes dependentes) que usam as classes independentes, são testadas. Esta seqüência de teste de camadas de classes dependentes continua até que todo o sistema seja concluído. 3.3.3 Teste de Sistema Após a apresentação dos testes anteriores, também conhecidos como testes técnicos, o foco do teste agora passa a ser o sistema completo com todos os componentes preparados e configurados. Neste nível de abstração de testes, a diferença apresentada anteriormente entre os testes em sistemas clássicos ou orientados a objetos deixa de existir devido ao foco do trabalho que passa a ser totalmente relacionado ao funcionamento do software como um todo, o que envolve também outras partes do sistema que nos testes anteriores foram ignorados, como Hardware, Pessoal, informação e etc. 26 Teste de Regressão é melhor explicado no item 3.3.6
  61. 61. 61 “Teste de Sistema é na verdade uma série de diferentes testes cuja finalidade principal é exercitar por completo o sistema baseado em computador. Apesar de cada teste ter uma finalidade distinta, todos trabalham para verificar se os elementos do sistema foram adequadamente integrados e executam as funções a eles alocadas”, (PRESSMAN, 2006, p.306). Um problema clássico do teste de sistema é ele ser “dedo-duro”. Isto acontece porque ao expor um erro, cada desenvolvedor responsável por uma parte do sistema culpa outro desenvolvedor sobre o erro acontecido. Para diminuir este problema Roger Pressman indica ao engenheiro de software, (PRESSMAN, 2006, p.305): 1. Projetar caminhos de manipulação de erros que testem toda a informação que chegue de outros elementos do sistema; 2. Conduzir uma série de testes que simule maus dados ou outros erros em potencial na interface do software; 3. Registrar os resultados dos testes para usá-los como “evidência”, se houver um dedo-duro; 4. Participar do planejamento e projeto de testes de sistema para garantir que o software seja adequadamente testado. São apresentados neste trabalho apenas os testes que foram considerados os mais importantes participantes da composição do teste de sistema, pois tratar todos os testes que fazem parte do teste de sistema é considerado demasiado grande para este capítulo do trabalho.
  62. 62. 62 Teste de Recuperação Quando um sistema sofre uma falha, normalmente em seus requisitos constam informações de como o sistema deve se comportar, seja exibindo uma mensagem de erro, seja reinicializando o sistema ou efetuando outra operação qualquer. “O teste de recuperação é um teste de sistema que força o software a falhar de diversos modos e verifica se a recuperação é adequadamente realizada. Se a recuperação é automática (realizada pelo próprio sistema), a reinicialização, os mecanismos de verificação, a recuperação dos dados e o reinicio são avaliados quanto a correção. Se a recuperação requer intervenção humana, o tempo médio para reparo (mean-time-to-repair, MTTR) é avaliado para determinar se está dentro dos limites aceitáveis”, (PRESSMAN, 2006, p.306). Com base no texto, podemos resumir que o teste de recuperação força falhas no sistema para validar se as ações de recuperação estão de acordo com as definições dos requisitos do sistema. Teste de Segurança Roger Pressman explica que “teste de segurança verifica se os mecanismos de proteção incorporados a um sistema vão de fato protegê-lo de invasão imprópria”, (PRESSMAN, 2006, p.306). Como apresentado acima, o teste de segurança visa validar como o sistema está preparado para sofrer tentativas de invasões, não somente invasões de hackers27 , mas de funcionários descontentes, de concorrentes, e etc... Em teoria não há limites para o teste de segurança, tudo é permitido, desde roubar senhas até implementar uma falha propositada no sistema com o intuito de 27 Hacker são pessoas com um alto grau de conhecimento em computadores, que utiliza deste conhecimento para invadir e obter informações de locais não autorizados, normalmente fazendo isso por diversão ou para testar seus próprios limites/conhecimentos.
  63. 63. 63 facilitar uma invasão. Qualquer meio utilizado que consiga invadir o sistema de qualquer forma deve ser comunicado e corrigido. Roger Pressman aponta outra informação interessante ao descrever que “o papel do projetista é tornar o custo da invasão maior do que o valor da informação que será obtida”, (PRESSMAN, 2006, p.306). Teste de Estresse O teste de estresse tem como objetivo ultrapassar os limites do sistema, isto é, ele tem como objetivo alimentar o sistema com uma condição extrema onde o mesmo ultrapasse os níveis máximos aceitos pela documentação, a fim de garantir o cumprimento destes valores por parte do sistema. “O teste de estresse executa um sistema de tal forma que demanda recursos em quantidade, freqüência ou volume anormais”, (PRESSMAN, 2006, p.306). É extremamente aconselhável que ao executar um teste de estresse de algum sistema, se tenha o sistema sendo executado num ambiente similar ao de produção, pois qualquer diferença de hardware como memória, rede entre outros podem alterar a confiabilidade dos testes. Roger Pressman apresenta uma técnica variante do teste de estresse conhecida como teste de sensibilidade onde “em algumas situações (a mais comum ocorre em algoritmos matemáticos), um intervalo de dados muito pequeno, contido dentro dos limites de validade dos dados para um programa, pode causar processamento extremo e até errôneo, ou profunda degradação de desempenho” e nos diz que “o teste de sensibilidade tenta descobrir combinações de dados, dentro das classes de entrada válidas, que podem causar instabilidade ou processamento inadequado”, (PRESSMAN, 2006, p.307). Com isso é possível entender que o teste de sensibilidade pretende descobrir
  64. 64. 64 situações dentro dos limites estipulados pelos requisitos que causam alguma instabilidade ou comportamento estranho no sistema. Teste de Desempenho O teste de desempenho pode ocorrer em qualquer nível de testes, num teste de unidade por exemplo pode-se avaliar o desempenho de um componente isolado do sistema mas não se pode dizer que o desempenho do sistema é aceitável até que o desempenho de todos os seus componentes sejam testados em conjunto. “O teste de desempenho é projetado para testar o desempenho do software durante a execução, no contexto de um sistema integrado”, (PRESSMAN, 2006, p.307). Ao trabalhar com testes de desempenho é necessário avaliar a condição dos recursos do sistema de forma precisa, como ciclos do processador, leitura do disco entre outras. A instrumentação externa pode monitorar tempos de intervalos de execução do sistema, registrando os eventos e a condição dos recursos informados. “Instrumentando um sistema, o testador pode descobrir situações que levam à degradação e possível falha do sistema”, (PRESSMAN, 2006, p.306). O teste de desempenho é comumente aplicado junto com o teste de estresse aproveitando que o teste de estresse já aplica uma sobrecarrega no sistema, e com isto os dados colhidos pelo teste de desempenho podem informar a partir de que ponto o sistema passa a se comportar de forma estranha. 3.3.4 Teste de Aceitação Glenford Myers apresenta que “teste de aceitação é o processo de comparar o
  65. 65. 65 programa com os requisitos iniciais e com as necessidades atuais dos usuários finais”, (MYERS, 2004, p.144). Com base no texto, é possível entender que o teste de aceitação é efetuado sobre o produto final, ou seja, sobre o sistema completo e tem como objetivo principal validar se todos os requisitos solicitados inicialmente pelo cliente estão corretamente implementados e funcionando. Além disto, ele tem a intenção de verificar se as necessidades atuais do cliente estão sendo atendidas com o sistema. O teste de aceitação muitas vezes não é executado pela empresa que desenvolveu o software mas sim pelo cliente final. Algumas empresas de software disponibilizam para o cliente ao final do desenvolvimento um ambiente chamado Ambiente de Homologação, com acesso ao sistema final para que o cliente possa então efetuar os testes de aceitação. O teste de aceitação consiste basicamente em abrir o sistema e validar se todos os requisitos documentados estão funcionando adequadamente, não existe uma forma de automatizar este tipo de teste pois ele depende simplesmente do que foi acordado com o cliente e por isso a melhor forma de efetuar esta validação é a liberação do sistema para o cliente final. 3.3.5 Teste de Regressão Ao corrigir uma falha encontrada no sistema, é necessário não somente testar se a falha está corrigida, como também é necessário testar se todas as partes envolvidas com a correção desta falha ainda funcionam corretamente. A esta reavaliação de uma parte do sistema damos o nome de teste de regressão. Roger Pressman define o teste de regressão como sendo “a reexecução de algum subconjunto de testes que já foi conduzido para garantir que as modificações não propagassem efeitos colaterais indesejados”, (PRESSMAN,
  66. 66. 66 2006, p.300). O teste de regressão então consiste na reexecução de casos de teste já desenvolvidos e executados anteriormente, porém se torna inviável executar todos os casos de teste novamente a cada modificação efetuada no sistema, para evitar este problema Pressman nos indica três diferentes classes de casos de testes que valem a pena ser reexecutados, (PRESSMAN, 2006, 300): 1. Uma amostra representativa de testes que vão exercitar todas as funções do software. 2. Testes adicionais que focalizam funções do software, que serão provavelmente afetadas pela modificação. 3. Testes que focalizam os componentes de software que foram modificados. Desta forma, o teste de regressão pode garantir o funcionamento do sistema após a modificação efetuada. Roger Pressman complementa descrevendo que “o número de testes de regressão pode crescer significativamente. Assim sendo, a suíte de testes de regressão deve ser projetada para incluir apenas aqueles que cuidam de uma ou mais classes de erros em cada uma das principais funções do programa”, (PRESSMAN, 2006, p.300). 3.4 Técnicas de Teste de Software Um software é testado para que seja descoberto o maior número de erros possíveis no sistema, desta forma é necessário planejar para que os testes capturem a maior quantidade destes erros e as técnicas de teste de software são técnicas que auxiliam a maximizar as chances de se encontrar erros no sistema de software. Roger Pressman defende que “essas técnicas fornecem diretrizes sistemáticas para projetar testes que [1] exercitam a lógica interna e as interfaces de cada
  67. 67. 67 componente de software, e [2] exercitam os domínios de entrada e saída do programa para descobrir erros na função, no comportamento e no desempenho do programa”, (PRESSMAN, 2006, p.315). O resultado do trabalho para as técnicas de teste são casos de teste que respeitam as regras apresentadas acima e aumentam as chances de captura de erros no sistema. “Diferentes técnicas de testes são adequadas em diferentes momentos”, (PRESSMAN, 2006, p.289). Desta forma é necessário que se conheça as técnicas de teste para poder escolher a melhor para a situação existente no momento, garantindo uma solução direcionada e garantindo a melhor qualidade possível dos casos de teste que serão executados. 3.4.1 Teste de Caixa-Branca Esta técnica de teste visa o planejamento dos testes com foco no código, ou seja, o responsável pelo planejamento do teste deve escrever os casos de teste com o conhecimento de como o sistema se comporta internamente, suas condições e ciclos, e deve garantir que aos testes finalizados, todas as condições ou ciclos do sistema foram testadas por completo. Roger Pressman apresenta esta definição de outra forma, dizendo que “teste de caixa branca de software é baseado em um exame rigoroso do detalhe procedimental. Caminhos lógicos internos ao software e colaborações entre componentes são testados, definindo-se casos de testes que exercitam conjuntos específicos de condições e/ou ciclos”, (PRESSMAN, 2006, p.318). Um indicador comum utilizado para saber quanto deste código foi testado ou não é chamado de cobertura de código, ele indica qual a porcentagem das linhas de
  68. 68. 68 código que estão sendo testadas pelo menos uma vez. Um sistema que tem cem por cento do seu código coberto não está livre de erros, porém haverá menos chances de acontecer um erro por não ter testado uma parte do sistema. Glenford Myers apresenta dois problemas ao se pensar em testes de caixa branca, o primeiro deles é o fato de que o número de caminhos lógicos para uma função pode ser astronomicamente grande, o segundo é que mesmo se todos os caminhos forem testados, não há uma garantia de que o sistema não contem erros, (MYERS, 2004, p.12,13). Ele apresenta três explicações para o fato do sistema com cem por cento de cobertura de código ainda apresentar erros, e são, (MYERS, 2004, p.13): 1. Ao fazer um teste com cem por cento de cobertura de código você não tem garantia de que está testando a coisa certa. Por exemplo, imagine que foi solicitado a você fazer uma função para ordenação ascendente e por engano você criou uma ordenação descendente, neste caso cobrir cem por cento do código não irá descobrir o erro sendo que o teste está validando uma ordenação descendente. 2. O programa pode estar incorreto devido a caminhos perdidos28 . Teste de cem por cento do código pode não detectar a ausência de caminhos necessários. 3. Teste de cem por cento do código pode não descobrir erros de sensibilidade de dados29 . Isto é, erros causados por uma mudança no valor das variáveis utilizadas pelo programa não são capturados através da cobertura completa do código. Desta forma fica claro que não basta uma cobertura completa do código para garantir eficiência, é necessário novamente um bom planejamento dos testes para 28 Missing Paths é como está no original em inglês e o autor se refere a trechos do código que podem não ter sido implementados mesmo que fossem necessários. 29 Data-Sensitivity Errors refere-se a erros com devido a dados variáveis dentro do sistema.

×