Baixe o app para aproveitar ainda mais
Prévia do material em texto
EE2 - Engenharia de Software e Sistemas Resumo baseado no Livro Engenharia de Software Sommerville e Slides do Professor Verificação e Validação (V & V) Validação: estamos construindo o produto correto? Se atende as expectativas do cliente. Verificação: estamos construindo o produto corretamente? Verifica se o software está de acordo com a especificação. Fatores que influenciam para analise da confiança adequada no software, de acordo com a sua funcionalidade: Função do Software: O nível de confiabilidade necessário depende de quão critico é o software. Expectativas do usuário: se o software com falhas ainda é aceitável Ambiente de mercado: o quão vale um maior custo de verificação e validação. É mais importante um software mais barato ou com menos erros. Abordagens complementares para a verificação e análise de sistema: Inspeções de software ou revisão em pares: analisam e verificam documento de requisitos, diagramas de projeto e código-fonte de programa. É uma técnica estática, pois não é preciso executar o software. Não pode verificar se o software é útil operacionalmente. Teste de software: Técnica dinâmica e principal na V & V. Executar a implementação e analisar resultados. Podem revelar presença de erros, não a sua ausência. Teste de Validação: é o que o cliente deseja, atende aos requisitos. Podem ser feitos testes estatísticos para verificar desempenho. Teste de defeitos: destinado a revelar problemas na implementação: inconsistência entre programa e especificação. Inspeções podem ser feitas em todas as etapas de desenvolvimento do software, teste apenas quando um protótipo ou versão executável. V & V e debugging são processos feitos de forma intercalada, ao encontrar um erro ele é prontamente corrigido. V & V: estabelece a existência de defeitos. Debugging: localiza e corrige os defeitos. Planejamento de verificação e validação: Processo de Teste: descrição das fases principais do processo de teste. Rastreabilidade de requisitos: Cada requisito é testado individualmente Itens testados: os produtos do processo de software a serem testados devem ser especificados. Cronograma de Testes: quando devem ser realizados os testes, alocação de recursos para os mesmos. Procedimento de registro de testes: resultados dos testes devem ser registrados Requisitos de hardware e de software: quais as ferramentas utilizadas e qual o uso de hardware Restrições: o que afeta o processo de teste. Inspeções de software: Geralmente focado no código-fonte, mas a inspeção dos requisitos também ocorre. Conhecimento sobre o domínio e sobre programação aumentam a eficácia. Vantagens ta inspeção sobre o teste: Durante testes, erros podem mascarar outros erros. Testes detectam erros não sua ausência. Em uma única sessão de inspeção você pode localizar vários erros. Em inspeções versão incompletas podem ser inspecionadas, enquanto que para testes você precisaria desenvolver testes especializados, que aumentariam o custo. Em inspeções você pode encontrar mais detalhadamente erros do programa como algoritmos ineficientes ou inadequados. Estudos comprovam que inspeções são mais eficientes para a detecção de erros. Mas não exclui a necessidade de testes. Inspeções de Programa: revisões cujo objetivo é detecção de defeitos de programa. A diferença básica entre outras revisões de qualidade é que o objetivo especifico das inspeções é encontrar os defeitos do programa, mais do que considerar questões mais amplas do projeto. Voltada explicitamente para detecção e não correção de erros. Para uma inspeção é necessário: a equipe de inspeção disponha de uma especificação precisa, os membros devem esta familiarizados com todos os aspectos projeto. Uma visão geral do sistema é apresentado à equipe, então ocorre a inspeção, os erros descobertos são anotados. Modificações são feitas por quem desenvolveu o software (autor/proprietário). Uma nova inspeção pode ou não ser necessária. Checklists de inspeção: usada para direcionar a inspeção, refletem os erros mais comuns de uma determinada linguagem de programação. Inspeções podem executar o sistema através de passo-a-passo de seu código. Análise estática automatizada: varre o texto do programa e tenta descobrir condições potencialmente errôneas. Um complemento, mas não um substituto Estágios na analise: Análise de fluxo de controle: Verifica loops, múltiplos pontos de saída ou de entrada e códigos inacessíveis. Análise de uso de dados: detecta variáveis não inicializada ou não usadas. E condições redundantes: sempre verdadeiras ou sempre falcas. Análise de interfase: verifica a consistência das declarações de rotina e procedimento e seus usos. Verifica procedimentos nunca usados. Análise de fluxo de informações: detecta a dependência entre variáveis, logo detecta valores que foram erroneamente computados. Análise de caminho: identifica todos os caminhos possíveis de um programa. São muitos os tipos de analises possíveis, mas elas são limitadas: escalabilidade, completude, precisão, excesso de informações. Esse tipo de análise é mais comum em linguagens como C, que tem tipagem fraca. Linguagens como Java tem tipo forte, mas analises mais sofisticada podem ser úteis. Teste de Software Falha: incapacidade do software de realizar a função requisitada. Ex: terminação anormal Falta: causa de uma falha. Ex: código incorreto ou faltando Erro: estado intermediário, provém de uma falta, pode resultar em falha Falta Erro Falha Confiabilidade de software: estimativa probabilística que mede com qual freqüência o software irá executar sem erros. Dados de testes: entradas selecionadas para testar o software Casos de teste: dados de teste, saídas esperadas e cenários específicos da execução. Eficácia de testes: um bom caso de teste é aquele com mais probabilidade de revelar um erro e que simula bem o ambiente do usuário final. Testes de componentes: teste de componentes individuais de programa Teste de sistema: teste de grupo de componentes integrados Teste de defeitos: tem como meta descobrir defeitos em programas. Os testes podem ser extremos, acima da necessidade de como o sistema será usado. Teste de sistemas: envolve a integração de dois ou mais componentes. Teste de integração: teste para detecção de erros decorridos de interações falhas entre componentes. Para facilitar a detecção uma integração incremental é recomendada. Teste de regressão: ao realizar mais um incremento na integração, testes passados podem ser refeitos. Teste de releases ou teste de aceitação: teste de uma versão do sistema que será distribuída a clientes. Tem como meta aumentar a confiança de que o software atende aos requisitos. É um teste de caixa-preta. As diretrizes, recomendações, para escolha de testes são: Entradas que forcem o sistema a gerar erros (mensagens, overflow) e saídas invalidas Forçar a cálculos muito grande e muito pequenos. Repetir a mesma entrada ou uma serie de entradas varias vezes. Teste de desempenho ou teste de estresse: serie de testes onde a carga é constantemente aumentada até que o desempenho do sistema se torne inaceitável. Causa o surgimento de defeitos. Leva o sistema ao extremo, altamente útil para testar falhas em grande número de acessos a rede ou banco de dados. Tipos de Teste: Teste de Segurança e controle de acesso: verifica se todos os mecanismos de proteção estão funcionando e forma satisfatória. Teste de integridade de dados: verifica a corretude dos métodos de acesso ao banco de dados, verifica a garantia de das informações. Teste de configuração ou portabilidade: Verifica se o sistema funciona nas diversas plataformas (tipos de conexão com a internet, software/hardware, browser, configuração do servidor) Teste de instalação e desinstalação: funcionalidade do instalador e desinstalador sob as múltiplas condições de instalação. Teste de Documentação: verifica se a documentação corresponde à informação correta e apropriada. Teste de ciclo de negócios: garante que o sistema funciona corretamentedurante o ciclo de negócio. Teste de Componentes ou teste de unidade: Tipos de componentes que podem ser testados: Funções ou métodos Classes de um objeto Componentes compostos que constituem diferentes objetos ou funções. Esses componentes compostos têm uma interface definida usada para acessar sua funcionalidade. Ao testar uma classe de objetos, os testes devem abranger todas as características do objeto: Teste de todas as operações associadas ao objeto Atribuir e interrogar todos os atributos associados ao objeto. Simular todos os eventos que provocam mudança de estados do objeto. Teste de interfaces: existem vários tipos de interface, logo diferentes tipo de erros possíveis: Interface de parâmetros: dados são passados de um procedimento para outro Interfaces de memória compartilhada: um bloco de memória é compartilhado entre funções ou procedimentos. Interfaces de procedimentos: um subsistema engloba um conjunto de procedimentos para serem chamados por outros subsistemas. Interfaces de passagem de mensagem: um componente solicita serviço a outro componente passando uma mensagem para ele. E recebe como resposta uma mensagem. Erros de interface: Mau uso de interface: um componente chama um outro componente e comete um erro no uso de sua interface, passando, por exemplo, atributos fora de ordem. Mau entendimento da interface: falso entendimento sobre comportamento de um componente. Erros de timing: componentes chamados funcionam em velocidade diferente da esperada, como resultado informações desatualizadas são acessadas. Projeto de casos de teste: a meta é criar um conjunto de testes que sejam eficazes em validação de testes de defeitos. Teste baseado em requisitos: todos os requisitos são testados e vários testes são gerados para um mesmo requisito Teste de partição: o conjunto de testes possíveis é dividido em “classes” equivalentes (partições de equivalência), ou seja, quando um teste dessa classe retornar um valor esperado todos dessa classe iram, isso reduz o número de casos testados. Ex: números positivos, entradas validas, entradas invalidas, etc. Usar seqüência de tamanhos diferentes em testes diferentes Teste estrutural ou teste caixa-de-vidro: derivação de casos de teste de acordo com a estrutura do programa. Exercitar todas as declarações do programa, não todos os caminhos. Teste de caminho: testar se cada caminho independente do programa é executado pelo menos uma vez. Se todos os caminhos forem executados, pode-se assegurar que cada declaração no método foi executada pelo menos uma vez e cada ramo foi exercitado às condições verdadeiras e falsas. Complexidade ciclomática: numero de caminhos possíveis de um código. Poucas evidencias de que é uma ferramenta de previsão de esforço de teste mais confiável do que linhas de código. (e-n +2) | e = arestas do grafo | n = nº nos do grafo Baixa à moderada: < 20 Alta: > 20 Muito alta: > 50 Automação de testes: os workbenches de testes fornecem uma variedade de ferramentas que executam testes automaticamente, como o conjunto de classe de Java JUnit. Eles podem simular parte do projeto que não foi implementado a fim de gerar dados de teste. Os workbenches podem ser adaptados para o sistema. Saídas de teste podem ser preparadas manualmente para comparação. Gerenciamento de Configuração Um gerenciamento de sistema de software em desenvolvimento tem que ser feito, pois requisitos mudam durante o desenvolvimento e uso. Logo um gerenciamento tem de ser feito, pois é fácil perder a rastreabilidade de quais mudanças foram incorporadas. Envolve o desenvolvimento e a aplicação de procedimentos e padrões para gerenciar um produto de software em evolução. Novas versão são criadas quando: Mudam para maquinas SO diferentes Oferecem funcionalidade diferente São configuradas para requisitos de usuários particulares O processo de gerenciamento de mudança precisa alcançar equilíbrio entre burocracia e rastreabilidade. Planejamento de gerenciamento de configuração: Todos os produtos do processo de software podem ser gerenciados: especificação, projetos, programas, dados de teste, manuais do usuário. Principais atividades do gerenciamento de configuração: Controle de versão Gerenciamento e registro de mudanças Organização e geração dos Builds do sistema. Gerenciamento de mudanças: os softwares estão sujeitos as mudanças continuas por parte dos usuários, desenvolvedores ou forças do mercado. O gerenciamento de mudanças visa rastrear essas mudanças para que os reparos corrijam falhas e as falhas em decorrência desses reparos sejam facilmente detectável. Acompanhamento de mudanças: o maior problema no gerenciamento de mudanças é acompanhar o seu status, mas ferramentas de gerenciamento fornecem meios de acompanhar esse processo, existe uma possibilidade de envio de e-mails automáticos de solicitação de mudanças. Comitê de controle de mudanças (CCB): mudanças pode ser revisadas por um grupo que decide se são adequadas em vários aspectos. Pode conter representantes tanto do cliente quanto do pessoal fornecedor. Procedência histórica: um tipo de “linha do tempo” das mudanças. Registra as mudanças (por quem foi feita, quando e a razão) Gerenciamento de versões e releases: elabora um esquema de identificação de versões de forma a identificá-las de forma única, bem como planejamento de nova versão. Assegura que procedimentos e ferramentas de gerenciamento das versões sejam adequadamente aplicados. Versões: apresenta funcionalidades distintas, de alguma forma, de outras instâncias do sistema. Variante: apenas pequenas diferenças em relação a outras instâncias. Release: instâncias do sistema distribuído pra alguém que não faz parte da equipe de desenvolvimento. Técnicas para identificação de componentes: Numeração de versões Identificação baseada em atributos: Os atributos podem ser associados a uma versão com a combinação de atributos que a identificam. Consulta baseada em atributos: Ex. ‘a mais recente versão em Java’, etc. Identificação orientada a mudanças: cada componente é denominado como na identificação de baseada em atributos, mas é também associado a algumas solicitações de mudanças. Branching e Merging: elemento fundamental no gerenciamento de configurações. Compromisso entre produtividade e risco. Branching: usar diferentes “ramos” de desenvolvimento para aumentar o paralelismo. Branchs são uteis para implementar mudanças ou funcionalidade pontual, com eles é possível atribuir tarefas a todos da equipe. Branch = um ramo Código não é compartilhado entre branches Merging: a combinação de uma desses ramos com o ramo principal. Diferenças entre os branches combinados precisam ser resolvidas Funcionalidades de um Sistema de Controle de Versões: Manutenção de um repositório de itens de configuração com suporte ao checkin e ao checkout distribuídos Criação e manutenção de informações de múltiplas versões Criação e merging de branches Capacidade de realizar consultas sobre versões dos sistemas, com base em seus atributos Construção (build) de sistemas: É o processo de compilação e ligação de componentes de software em um sistema executável, varias combinações podem ser feitas, e logo diversos sistemas. Esse processo é apoiado por ferramentas automatizadas que são dirigidas por ‘scripts de construção’. Construção de sistemas: A construção de um sistemas é algo altamente dispendioso. Ferramentas de construção de sistemas podem fornecer: Uma linguagem de especificação de dependência e um interpretador associado Seleção de ferramentas e apoio à instanciação Compilação distribuída Gerenciamento de objetos derivados. Reuso de Software Na maioria das disciplinas de engenharia, os sistemas são projetados por meio de composição de componentes existentes, porém em engenharia de software, grande parte de um novo sistema é construída do zero. Essa situação vem mudando. Modalidades de reuso: Reuso do sistema da aplicação: um sistema inteiro pode ser reusado por incorporação a outrossistemas sem mudanças. Reuso de componentes: componentes de uma aplicação como subsistemas ou objetos simples. Reuso de bibliotecas Reuso de conhecimento: princípios e padrões Benefícios: Confiança aumentada: software reusado já foi testado mais vezes, erros já foram encontrados e corrigidos. Risco de processo reduzido: custo de software existente é conhecido, enquanto que os custos de desenvolvimento são altamente variantes. Uso eficiente de especialistas: em vez de fazer o mesmo trabalho repetidamente, eles podem desenvolver software reusável englobando os seus conhecimentos. Conformidade com padrões: interfaces padronizadas fazem reuso, o que poupa tempo, gera mais facilidade no uso por parte do usuário leigo. Desenvolvimento acelerado: apresentação de uma versão rapidamente ao mercado vale mais do que custos. O reuso faz com que essa rapidez ocorra, pois tempo de desenvolvimento e validação são reduzidos. Problemas: Custos de manutenção aumentados: se o código-fonte do componente não estiver disponível os custos de manutenção poderão ser aumentados. Falta de apoio de ferramenta: o conjunto de ferramentas CASE podem não apoiar o desenvolvimento com reuso. Síndrome de não-inventado-aqui: Alguns engenheiros de software preferem reescrever componentes porque acreditam que podem aprimorá-los. E porque escrever um software original é mais desafiador do que reusar. Criação e manutenção de uma biblioteca de componentes: preencher uma biblioteca de componentes reusáveis e assegurar aos desenvolvedores que podem usar essa biblioteca é algo caro. Procura, compreensão e adaptação de componentes reusáveis Panorama do reuso: Existem muitas abordagens diferentes para reuso, em uma variedade de níveis, desde funções simples até sistemas completos de aplicação. Reuso Acidental vs. Reuso Sistemático Desenvolvimento com Reuso vs. Desenvolvimento para Reuso Fatores de planejamento de reuso: O cronograma de desenvolvimento para o software: se o software tem que ser desenvolvido rapidamente O ciclo de vida previsto do software: software de vida longa deve ter fácil manutenção O conhecimento, habilidades e experiência da equipe de desenvolvimento: uma equipe experiente tem mais facilidade de trabalhar com tecnologias de reuso complexas. A importância do software e seus requisitos não funcionais: para sistemas críticos é necessário criar um caso de confiança para o sistema. O domínio da aplicação: em alguns domínios de aplicação, tal como sistemas de informações industriais e médicos, há vários produtos genéricos que podem ser reusados por meio de configuração par uma situação específica. A plataforma de execução para o software: alguns componentes são específicos para uma determinada plataforma, então seu sistema só poderá reusá-lo caso seja para essa plataforma. A abordagem de reuso empregada Frameworks: um projeto de sistema ou subsistema feito de uma coleção de classes e as interfaces entre elas. É instanciado através da implementação de classes concretas que estendem certas partes abstratas do framework. Frameworks são entidades genéricas e moderadamente complexas que geram um esforço para compreendê-los, mas podem promover grande economia de esforço Classes abstratas e interfaces Hotspots Classes de framworks: Frameworks de infra-estrutura de sistema: Apóiam o desenvolvimento de partes fundamentais de um sistemas, tais como comunicações, interfaces de usuário e compiladores. Frameworks de integração/middleware: Padrões e classes que apóiam a comunicação e a troca de informações de componentes. Frameworks de domínio específico: Apóiam o desenvolvimento de tipos específicos de aplicações, tais como sistemas médicos, de telecomunicações e financeiros Reuso de sistemas: Reuso de aplicações inteiras: integração de vários sistemas para criar uma nova aplicação, ou pela configuração de um sistema para um ambiente. Reuso de componentes COTS (Commercial Off-The-Shelf systems): geralmente são sistemas de aplicação completos que oferecem uma API. É uma estratégia viável de desenvolvimento para alguns tipos de sistemas tais como os de e-commerce. O benefício-chave é o desenvolvimento mais rápido da aplicação. Geralmente com um custo menor Há duvidas quanto: Ao produto COTS oferece a funcionalidade mais apropriada. Já que pode haver diversos produtos similares que podem ser usados. Como os dados serão trocados. Produtos individuais usam estruturas únicas de dados e formatos. Quais características do produto serão realmente usadas? A maioria dos produtos tem mais funcionalidade do que é necessário Problemas de integração de sistemas COTS Falta de controle sobre funcionalidades e características de qualidade Problemas com a interoperabilidade, pois sistemas COTS diferentes podem fazer suposições diferentes Nenhum controle sobre a evolução do sistema Evolução de Software de Refatoração As organizações fazem grandes investimentos em seus sistemas de software – eles são ativos críticos de negócios. Para manter o valor desses ativos de negócio, eles devem ser mudados e atualizados. A maior parte do orçamento de software nas grandes organizações é voltada para evolução, ao invés do desenvolvimento de sistemas novos Dinâmica de evolução de programas: é o estudo de mudança de sistema. Lehman e Belady propuseram que havia uma série de ‘leis’ (hipóteses) que se aplicavam a todos os sistemas quando eles evoluíam. Na prática, são observáveis, de fato, em sua grande maioria em sistemas de grande porte Lei de Lehman: Mudança contínua: Manutenção é um processo inevitável. Complexidade crescente: Alteração do sistema degrada sua estrutura Evolução de programa de grande porte: Sistemas de grande porte possuem dinâmica própria (estágios iniciais de desenvolvimento) Estabilidade organizacional: Estado saturado. Mudanças de recursos e pessoal não têm efeito. Novas funcionalidades introduzem novos defeitos, logo não orçar grandes incrementos sem pensar nas correções de defeitos Qualidade em declínio: Declínio da qualidade e insatisfação dos usuários Aprimoramento a partir de sistemas de feedback Manutenção de software: É a modificação de um programa após ter sido colocado em uso. Normalmente não envolve mudanças consideráveis na arquitetura do sistema. Ocorrem pela modificação de componentes existentes e pela adição de novos componentes ao sistema. Tipos de manutenção: Manutenção para reparar defeitos de software Manutenção para adaptar o software a um ambiente operacional diferente Manutenção para adicionar funcionalidade ao sistema ou modificá-lo Custos de manutenção: Geralmente, são maiores que os custos de desenvolvimento (de 2 a 100 vezes, dependendo da aplicação). A manutenção corrompe a estrutura do software, tornando a manutenção posterior mais difícil e cara. Fatores de custo de manutenção: Estabilidade da equipe: custos são reduzidos se o mesmo pessoal estiver envolvido por algum tempo. Responsabilidade contratual: Os desenvolvedores podem não ter responsabilidade pela manutenção, portanto, não há incentivo para projetar para mudanças futuras. Habilidade do pessoal: O pessoal da manutenção geralmente é inexperiente e tem conhecimento limitado de domínio. Idade e estrutura do programa: À medida que os programas envelhecem, sua estrutura é degradada e se torna mais difícil de ser compreendida e modificada. Previsão de manutenção: Avaliação de quais partes do sistema pode causar problemas e ter altos custos de manutenção. Processos de evolução: dependem do tipo de software que está sendo mantido, dos processos de desenvolvimento usados, das habilidades e das experiências do pessoal envolvido. Propostas para mudança são os direcionadores para a evolução do sistema. Metodologias mais novas não costumam ter um processo separado Previsão de mudanças: A previsão do número de mudanças requer o entendimento dos relacionamentos entre um sistema e seu ambiente. Sistemas fortemente acoplados requerem mudanças sempre que o ambienteé mudado. Medidas de processo podem ser usadas para avaliar a facilidade de manutenção. Se qualquer uma ou todas essas estão aumentando, isso pode indicar um declínio na facilidade de manutenção: Número de solicitações para manutenção corretiva; Tempo médio necessário para análise de impacto; Tempo médio para implementar uma solicitação de mudança; Número de solicitações de mudança pendentes. Solicitação de mudanças urgentes pode ter de ser executadas sem passar por todos os estágios do processo de desenvolvimento de software. Se um defeito sério de sistema tem de ser reparado Se mudanças no ambiente do sistema têm efeitos inesperados; Se existem mudanças de negócio que necessitam de uma resposta muito rápida (e.g. mudança de lei) POP (Patch-Oriented Programming) Podem resultar em problemas ainda piores Reengenharia de sistema: É a reestruturação ou reescrita de parte ou de todo um sistema sem mudar sua funcionalidade. Aplicável onde partes de um sistema de grande porte necessitam de manutenção freqüente. Simplicidade é um objetivo complexo. Atividades: Conversão de código-fonte: Converter o código para uma nova linguagem. Engenharia reversa: Analisar o programa para compreendê-lo. Aprimoramento da estrutura de programa: Analisar e modificar a estrutura para facilidade de entendimento. Modularização de programa: Reorganizar a estrutura do programa. Reengenharia de dados: Limpar e reestruturar os dados do sistema. Fatores de custo da reengenharia: A qualidade do software que deve passar pela reengenharia. O apoio de ferramentas disponíveis para reengenharia. Extensão da conversão de dados. A disponibilidade do pessoal especializado: principalmente em sistemas antigos. Refatoração: Uma pequena modificação no sistema que não altera o seu comportamento funcional final, mas que melhora alguma qualidade não-funcional: simplicidade, flexibilidade e clareza. Cada passo da refatoração é trivial, rápido, sistemático, obvio. Geralmente é automatizada por ferramentas. É importante para desenvolvimento e evolução Exemplos: Mudança do nome de variáveis Mudanças nas interfaces dos objetos Pequenas mudanças arquiteturais Encapsular código repetido em um novo método Generalização de métodos Refatoração pode adicionar erros, mesmo em casos automatizados, então antes de começá-la casos de teste devem ser estruturados para a ajudar a detectar os erros. Formato da estrada de refatoração: Nome da refatoração. Resumo da situação na qual ela é necessária e o que ela faz. Motivação para usá-la (e quando não usá-la). Mecânica, i.e., descrição passo a passo. Exemplos para ilustrar o uso. Qualidade de Software Dedica-se a assegurar que o nível requerido de qualidade seja atingido. Envolve a definição de padrões e procedimentos apropriados de qualidade e a garantia de que sejam seguidos. Deve visar o desenvolvimento de uma ‘cultura de qualidade’ Qualidade deve atender às sua especificação Problemas: Tensão entre os requisitos de qualidade do cliente (eficiência, confiabilidade, etc.) e requisitos de qualidade do desenvolvedor (facilidade de manutenção, reusabilidade, etc.) Alguns requisitos de qualidade são difíceis de especificar de uma maneira não-ambígua As especificações de software são, geralmente, incompletas e freqüentemente inconsistentes Gerenciamento de qualidade é particularmente importante para sistemas grandes e complexos A documentação de qualidade é um registro do progresso Equipes menores menos documentos de gerenciamento de qualidade Atividades de gerenciamento de qualidade: Garantia de qualidade: Estabelece procedimentos e padrões organizacionais para qualidade Planejamento de qualidade: Seleciona procedimentos e padrões aplicáveis para um projeto específico e o modifica quando necessário. Controle de qualidade: Assegura que os procedimentos e os padrões sejam seguidos pela equipe de desenvolvimento de software. O gerenciamento de qualidade deve ser separado do gerenciamento de projeto para assegurar independência Objetivos potencialmente conflitantes Qualidade de processo e de produto: segundo alguns modelos a qualidade do processo influencia no produto. Contudo, existe uma relação complexa e pouco compreendida entre processos de software e qualidade de produto. Qualidade baseada em processo: A aplicação de habilidades individuais e a experiência são muito importantes no desenvolvimento de software. Fatores externos, como a novidade de uma aplicação ou a necessidade de um cronograma de desenvolvimento acelerado, podem piorar a qualidade do produto. Deve-se tomar cuidado para não impor padrões de processo inadequados Padrões de processo: Definir padrões de processo, tais como o modo como as revisões devem ser conduzidas, o gerenciamento da configuração. Monitorar o processo de desenvolvimento para assegurar que os padrões estejam sendo seguidos Relatar sobre o processo para a gerência de projeto e para o comprador do software Não usar práticas inadequadas simplesmente porque padrões foram estabelecidos Padrões de produto definem características que todos os componentes devem exibir Ex. um estilo de programação comum. Padrões de processo definem características relativas aos processos de software Importância dos Padrões: Englobam as melhores práticas São um arcabouço para os processos de garantia de qualidade Padrões fornecem continuidade: Novos funcionários podem compreender a organização pela compreensão dos padrões que são adotados Problemas com padrões: Podem não ser vistos como relevantes ou atualizados pelos engenheiros de software Envolvem, freqüentemente, muita burocracia Difícil manter a documentação associada Desenvolvimento de Padrões: Envolver os engenheiros na elaboração desenvolvimento: Eles devem compreender as razões de um padrão Revisar padrões e seu uso regularmente: Padrões podem se tornar rapidamente desatualizados e isso reduz sua credibilidade. Incorporar novas “melhores práticas” Padrões devem ter ferramentas de apoio Medições métricas de software: A medição de software se dedica a derivar um valor numérico para algum atributo de um produto ou de processo de software. Permite comparações objetivas entre técnicas e processos. Métricas de Software: Contagem de determinados elementos de um sistema de software, processo ou documento Permitem que o software e o processo de software sejam quantificados Podem ser usadas para prever atributos de produto e para controlar o processo de software. As métricas de produto podem ser usadas para previsões gerais ou para identificar componentes anômalos Suposições de métricas: Uma propriedade do software pode ser medida Existe um relacionamento entre o que podemos medir e o que queremos conhecer: Podemos somente medir atributos internos, mas estamos, muitas vezes, mais interessados em atributos externos de software Esse relacionamento foi formalizado e validado. O processo de medição: Um processo de medição de software pode ser parte do controle de qualidade Algumas métricas são difíceis de coletar de forma automatizada. Ex. Separação de interesses Os dados coletados durante este processo devem ser mantidos como um recurso da organização. Torna possíveis comparações entre projetos Recomendações: Não colete dados desnecessários: As questões a ser respondidas devem ser decididas previamente e os dados necessários identificados Conte às pessoas porque os dados estão sendo coletados: Não dependa da memória: Colete dados quando são gerados, e não depois que um projeto foi finalizado Métricas de Produto: Uma métrica deve ser um previsor de qualidade de produto. Classes de métrica de produto Dinâmicas: coletadas em tempo de execução. Ajudam a avaliar a eficiência e a confiabilidade. São diretamente relacionadas aos atribuitos de qualidade de software É relativamente fácil medir o tempo de resposta de um sistema (atributo de desempenho) ou a frequência com que ele falha (atributo de confiabilidade).Estáticas: coletadas em tempo de compilação. Ajudam a avaliar a confiabilidade, a facilidade de compreensão e a facilidade de manutenção. Têm um relacionamento indireto com atributos de qualidade É necessário estabelecer um relacionamento entre essas métricas e as propriedades, tais como complexidade, facilidade de compreensão e de manutenção. Algumas métricas são coletadas a partir de informações sobre o produto. Ex. Número de bugs conhecidos Analise de medições: Nem sempre é óbvio o que os dados significam. É muito importante usar métricas experimentalmente validadas Desenvolvimento de sistemas tolerantes a falhas Todos os usuários desejam que um sistema seja confiável, mas alguns sistemas, como os críticos demandam uma necessidade maior de confiabilidade, e então exigem técnicas especificas de engenharia de software Para atingir a confiança medidas são tomadas: Prevenção de falhas: O sistema é desenvolvido de modo que provadamente atenda sua especificação Remoção de falhas: Técnicas de verificação e de validação são usadas para descobrir e remover falhas em um sistema antes que seja entregue. Tolerância a falhas: O sistema é projetado de forma que as falhas no software entregue não resultem em defeitos em tempo de execução Redundância: Parte do sistema ou de suas ações que não seria necessária se falhas não existissem. Ex: componente duplicado, reinicialização Diversidade: Prover a mesma funcionalidade de maneiras diferentes para que eles não falhem de forma análoga A adição de diversidade e de redundância aumenta a complexidade. Simplicidade e V & V extensivas podem ser uma rota mais eficiente para a confiança de software Software livre de falhas: Os métodos atuais de engenharia de software permitem a produção de software livre de defeitos, sistemas relativamente pequenos. Significa que o software atende à especificação, não significa que sempre executará corretamente. Processos confiáveis: Para assegurar um número mínimo de defeitos de software, é importante ter um processo de software bem definido e repetível, que não depende inteiramente de habilidades individuais, isto é, podem ser realizados por pessoas diferentes. Para detecção de defeitos, é claro que as atividades de processo devem incluir um esforço significativo dedicado à verificação e à validação. Atividades que ajudam na remoção de falhas: Inspeções de requisitos: Descoberta de problemas com a especificação Gerenciamento de requisitos: Acompanhamento de mudanças no projeto e implementação Verificação de modelos: Análise automática de modelos Inspeções de projeto e de codificação: Listas de defeitos comuns para descoberta e remoção deles Análise estática: Análise de programas Planejamento e gerenciamento de teste: Cobertura e rastreabilidade entre testes e requisitos Gerenciamento de configuração: Inclusão correta de componentes no sistema Arquiteturas adequadas: Remoção localizada de erros. Tolerância a falhas: Sistemas críticos devem ser tolerantes a falhas, significa que o sistema pode continuar em operação apesar da falha do software Complementar a técnicas para remover falhas Um sistema é tolerante a falhas com relação a um dado modelo de falhas Falha, erro, defeito Etapas de tolerância a defeitos, feito em tempo de execução: Detecção de erros: O sistema deve detectar se um erro ocorreu (um estado incorreto de sistema). Envolve a definição de restrições que devem ser mantidas em todos os estados legais, e a verificação do estado contra essas restrições Avaliação de danos: As partes do estado de sistema afetadas pelo erro devem ser detectadas Recuperação de erros: O sistema deve ir para um estado ‘seguro’ estável Reparação de erros: O sistema pode ser modificado para evitar recorrência da falha Avaliação de Danos: Analisa o estado do sistema para estimar a extensão da corrupção causada por um erro. Deve verificar quais partes do estado do sistema foram afetadas pelo erro. Geralmente, é baseada em ‘funções validadas’, que podem ser aplicada aos elementos de estado para avaliar se seu valor está dentro de uma faixa permitida. Recuperação de erros: Recuperação por avanço (forward error recovery): Levar o estado do sistema para um novo estado livre de erros. A recuperação por avanço é específica de aplicação Corrupção de dados codificados: Adicionam redundância aos dados codificados -- dados redundantes podem ser usados para reparação de dados corrompidos Ponteiros redundantes: Quando ponteiros redundantes são incluídos em estruturas de dados uma lista ou repositório de arquivos corrompido pode ser reconstruída se um número suficiente de ponteiros não estão corrompidos. Tratamento de exceções: Ênfase na estruturação Recuperação por retrocesso (backward error recovery): Restaurar um estado anterior, livre de erros, do sistema. A recuperação por retrocesso de erros é mais simples e genérica. Não se aplica a todos os casos. Transações são um método popular: Mudanças não são aplicadas até que a computação seja completada. Se um erro ocorre, o sistema é deixado no estado anterior ao da transação. Checkpoints locais Checkpoints distribuídos periódicos: Baseados em logs Arquiteturas tolerantes a falhas: Técnicas de V & V não são capazes de ajudar a prever interações entre o hardware e o software. Mau entendimento dos requisitos pode significar que as verificações são incorretas ou incompletas Se requisitos de confiabilidade são críticos, pode ser usada uma arquitetura específica para apoiar tolerância a falhas Podem tolerar falhas de hardware e/ou de software. Tolerância de falhas de hardware: Depende da redundância modular tripla (TMR) Três componentes idênticos replicados recebem a mesma entrada e têm suas saídas comparadas Se uma saída é diferente, ela é ignorada e uma falha do componente é simulada. Premissas básica: Falhas de hardware decorrem de falhas de componentes (e.g. por desgaste natural) e não de projeto. Falhas são exceções e falhas simultâneas são raras TMR e Software: As suposições básicas da TMR não valem para sistemas de software. Não é possível simplesmente replicar os mesmos componentes quando eles têm falhas de projeto em comum. Falhas simultâneas de componentes seriam, portanto, virtualmente inevitáveis. Diversidade do projeto: Versões diferentes do sistema são projetadas e implementadas de maneiras diferentes. Podem apresentar modos de falha diferentes. Abordagens diferentes para projeto: Implementação em linguagens de programação diferentes; Uso de ferramentas e ambientes de desenvolvimento diferentes; Execução em diferentes sistemas operacionais Algoritmos e escolhas de projeto diferentes Abordagem para diversidade de projeto: Programação de N-versões: A mesma especificação é implementada em uma série de versões diferentes por equipes diferentes, logo uma baixa probabilidade dessas equipes cometerem os mesmos erros. Todas as versões calculam simultaneamente e a saída da maioria é selecionada usando um sistema de votação. Essa é a abordagem mais comumente usada, por exemplo, em muitos modelos da aeronave comercial Airbus. Blocos de recuperação: Uma série de versões explicitamente diferentes da mesma especificação são escritas e executadas em seqüência, reduz a probabilidade de erro comuns. Um teste de aceitação é usado para selecionar a saída a ser transmitida, que é difícil de elaborar de forma independente do algoritmo. Nem sempre é aplicado em sistema de tempo real, pois à sua operação é seqüencial. Problema para diversidade de projeto: Equipes não são culturalmente diversas e tendem a resolver os problemas da mesma maneira. Erros característicos: Equipes diferentes comentem os mesmos erros. Algumas partes de uma implementação são mais difíceis que outras: Equipes tendem a cometer erros no mesmo lugar; Falhas na especificação: são refletidas em todas as implementações; Esses problemas podem ser mitigados pelo uso de representações múltiplas da especificação.
Compartilhar