Arquitetura de Software e Testes — conceitos e padrões
Classificado em Computação
Escrito em em
português com um tamanho de 18,02 KB
Arquitetura de Software e decisões de projeto
Decisões de projeto de arquitetura: projetam a organização de um sistema para satisfazer os requisitos funcionais e não funcionais de um sistema.
Visões da arquitetura
- Visão lógica: mostra as abstrações; deve ser possível relacionar os requisitos do sistema com as entidades.
- Visão de processo: mostra o comportamento em tempo de execução; é útil para avaliar características não funcionais como desempenho e disponibilidade.
- Visão de desenvolvimento: mostra como o software é composto (estrutura de módulos, organização do código).
- Visão física: mostra o hardware do sistema e como os componentes de software são distribuídos entre processadores.
Padrões e estilos arquiteturais
- Arquitetura em camadas: permite separação e independência. A funcionalidade do sistema é organizada em camadas separadas; cada camada depende apenas dos recursos e serviços oferecidos pela camada abaixo.
- Arquitetura repositório: descreve como um conjunto de componentes que interagem compartilha dados; todos os dados são centralizados em um repositório.
- Arquitetura cliente-servidor: composta por servidores que oferecem serviços, clientes que consomem esses serviços e uma rede de comunicação. Um benefício é a independência entre clientes e servidores, permitindo modificar serviços ou servidores sem alterar o sistema cliente.
- Arquitetura duto e filtro (pipe-and-filter): o processamento dos dados é organizado de modo que cada componente realiza uma transformação discreta dos dados; os dados fluem através de um pipeline de componentes.
- Arquitetura de aplicações: arquiteturas de aplicação encapsulam as principais características de uma classe de sistemas.
Projeto orientado a objetos com UML
Um sistema orientado a objetos é composto por objetos interativos que mantêm seu próprio estado local e oferecem operações sobre esse estado. Os objetos incluem os dados e as operações para manipulá-los; portanto, podem ser entendidos e modificados como entidades autônomas.
Diagramas UML
- Diagrama de atividade: mostra as atividades envolvidas em um processo ou no processamento de dados.
- Diagrama de casos de uso: mostra as interações entre um sistema e seu ambiente.
- Diagrama de sequência: mostra as interações entre atores e sistema e entre componentes do sistema ao longo do tempo.
- Diagrama de classes: mostra as classes de objetos no sistema e as associações entre elas.
- Diagrama de estado: mostra como o sistema ou um objeto reage a eventos internos e externos.
Modelos estruturais e dinâmicos
Modelos estruturais: exibem a organização de um sistema em termos de seus componentes e seus relacionamentos. Podem ser modelos estáticos que mostram a estrutura do projeto do sistema ou modelos dinâmicos que mostram a organização do sistema quando ele está em execução.
Modelos comportamentais
Modelos comportamentais mostram o que acontece ou deve acontecer quando o sistema responde a um estímulo do seu ambiente. Dois tipos de estímulos:
- Dados: alguns dados que chegam precisam ser processados pelo sistema.
- Eventos: alguns eventos disparam o processamento do sistema; podem ter dados associados, mas nem sempre.
Engenharia dirigida a modelos (MDE)
A engenharia dirigida a modelos é uma abordagem de desenvolvimento de software em que os modelos, em vez de programas, são as saídas principais do processo de desenvolvimento. Os programas executados em hardware/software são gerados automaticamente a partir dos modelos. O nível de abstração na engenharia de software é aumentado por meio desse processo; assim, os engenheiros não precisam se preocupar com detalhes de linguagem de programação ou especificidades das plataformas.
Testes, manutenção e reengenharia
Tipos básicos de teste
- Teste de caixa branca: o analista tem acesso ao código-fonte, conhece a estrutura interna do produto e pode escolher partes específicas de um componente para avaliação. É projetado em função da estrutura do componente e permite uma averiguação precisa do comportamento interno.
- Teste de caixa preta: o analista não tem acesso ao código-fonte e desconhece a estrutura interna do sistema. Também conhecido como teste funcional, pois é baseado nos requisitos funcionais do software; ele busca falhas que contrariem os requisitos da aplicação.
Manutenção e evolução
O ambiente muda, novos requisitos surgem e o sistema deve ser modificado; caso contrário, começa a ser considerado desatualizado e pode ser substituído por outro mais recente.
Três tipos de manutenção:
- Correção de defeitos: erros de codificação, requisitos e projeto.
- Adequação ambiental: quando ocorrem mudanças no hardware, no sistema operacional ou em software de apoio, o sistema deve ser modificado para se adequar a essas mudanças.
- Adição de funcionalidades: ocorre quando os requisitos do sistema mudam.
Reengenharia de software
A reengenharia é importante em sistemas legados para torná-los mais fáceis de manter. Consiste em melhorar a estrutura e a inteligibilidade, incluindo redocumentação do sistema, refatoração, alteração da arquitetura, mudança de linguagem e outros. Vantagens:
- Riscos reduzidos: há alto risco em redesenvolver um software essencial; reengenharia reduz esse risco.
- Custos reduzidos: o custo da reengenharia é significativamente menor do que o de desenvolvimento de novo software.
Deve-se descartar o sistema quando ele não contribui mais efetivamente para os processos de negócio da empresa — por exemplo, quando os processos mudam e o sistema se torna inútil para os novos processos.
Sistemas legados: opções estratégicas: descartar completamente o sistema; desativar e manter com manutenção regular; reestruturar para melhorar a manutenibilidade; substituir parte do sistema por novo.
Objetivos, verificação e validação
Um programa não precisa ser totalmente livre de erros antes de ser entregue: os testes não podem demonstrar que o software é totalmente livre de defeitos nem que se comportará conforme especificado em qualquer situação, pois sempre é possível que um teste esquecido seja o que descobrira problemas importantes.
Testes detectam apenas a presença de erros, não sua ausência: o teste é destinado a mostrar que um programa faz o que é proposto e a descobrir defeitos antes do uso; os resultados verificam erros, anomalias ou atributos não funcionais.
Objetivos dos testes
- Teste de validação: demonstrar ao desenvolvedor e ao cliente que o software atende aos seus requisitos (estamos construindo o produto certo?).
- Teste de defeitos: descobrir situações em que o software se comporta de maneira incorreta, indesejável ou diferente das especificações.
- Verificação: checar se o software atende aos requisitos funcionais e não funcionais (estamos construindo o produto da maneira certa?).
- Validação: garantir que o software atenda às expectativas do cliente; demonstra o que o software faz e o que o cliente espera.
Inspeção de software (verificação)
- Durante o teste, erros podem mascarar outros erros; como a inspeção é um processo estático, ela pode descobrir muitos erros sem execução do sistema.
- Versões incompletas de um sistema podem ser inspecionadas sem custos adicionais; para testes de sistema incompletos seriam necessários dispositivos de teste especializados, aumentando custo.
- Além de procurar defeitos, uma inspeção pode considerar atributos como qualidade do programa, conformidade com padrões, portabilidade e manutenibilidade, buscando ineficiências, algoritmos inadequados e estilo de programação pobre que dificultem manutenção.
- Inspeções são mais eficientes que testes de programa para detectar certos tipos de problemas.
Três fases de testes de software
- Testes de desenvolvimento: o sistema é testado durante o desenvolvimento para descobrir bugs; projetistas e programadores podem participar.
- Testes de release (caixa preta): uma equipe independente testa uma versão completa antes da liberação para usuários, verificando se atende aos requisitos das partes interessadas.
- Teste de usuário (aceitação): os usuários testam o sistema em seu próprio ambiente.
Testes de regressão e automatizados
Testes de regressão: reexecução de testes anteriores para verificar se alterações no programa não introduziram novos bugs. Garantem que o programa ainda satisfaz seus requisitos.
Testes automatizados: testes codificados em um programa que é executado cada vez que o sistema em desenvolvimento é testado. Não podem ser totalmente automatizados, pois só verificam se um programa faz aquilo a que se propõe ou se não gera efeitos colaterais indesejados.
Partes de um teste automatizado:
- Configuração: inicia-se o sistema com o caso de teste.
- Chamada: quando você chama o objeto ou método a ser testado.
- Afirmação: compara o resultado da chamada com o resultado esperado.
Testes de desenvolvimento e níveis de teste
Testes de desenvolvimento: responsáveis pelo desenvolvimento de testes e pela manutenção de registros detalhados de resultados, visando descobrir bugs.
- Teste unitário: unidades individuais de programa ou classes de objetos são testadas isoladamente; testa a funcionalidade de objetos ou métodos.
- Teste de componentes (integração de unidades): várias unidades individuais são integradas para criar componentes compostos; deve testar as interfaces dos componentes.
- Teste de sistema: alguns ou todos os componentes do sistema são integrados e o sistema é testado como um todo, verificando a interação entre componentes.
Testes unitários automatizados e frameworks
Unitários automatizados podem usar frameworks como junit para escrever e executar testes. Frameworks de teste unitário fornecem classes de teste genéricas que você pode estender para criar casos específicos; eles executam os testes implementados e informam, geralmente via interface gráfica, o sucesso ou falha. Um conjunto de testes pode ser executado em poucos segundos, permitindo rodar todos os testes a cada alteração no programa.
Escolha de casos de teste unitário
Objetivos dos casos de teste unitário:
- Mostrar que, quando usado como esperado, o componente faz o que se propõe.
- Revelar defeitos nos componentes se existirem.
Estratégias:
- Teste de partição: identificar grupos de entradas com características comuns e escolher testes representativos para cada grupo.
- Testes baseados em diretrizes: usar diretrizes de teste para escolher casos de teste.
Testes baseados em requisitos, cenário e desempenho
- Testes baseados em requisitos: o requisito deve ser escrito de modo que um teste possa ser projetado para ele; assim, um testador pode verificar se o requisito foi satisfeito.
- Teste de cenário: abordagem de teste de release em que você imagina cenários típicos de uso e os usa para desenvolver casos de teste.
- Teste de desempenho: projetado para assegurar que o sistema possa processar a carga a que se destina.
Teste de usuário e testes de release
Teste de usuário: estágio em que usuários ou clientes fornecem entradas e feedback sobre o sistema. A influência do ambiente de trabalho do usuário afeta confiabilidade, desempenho, usabilidade e robustez — inclui teste beta, teste de aceitação e teste alfa.
Testes de release: têm o objetivo de convencer o fornecedor do sistema de que ele é bom o suficiente para uso, demonstrando que oferece a funcionalidade, desempenho e confiabilidade especificados e que não falhará durante uso normal.
Reiteração: projeto orientado a objetos, objetivos e tipos de teste
Projeto orientado a objetos com UML: um sistema orientado a objetos é composto de objetos interativos que mantêm seu próprio estado local e oferecem operações sobre esse estado.
Dois objetivos distintos dos testes
- Teste de validação: demonstrar ao desenvolvedor e ao cliente que o software atende aos requisitos.
- Teste de defeitos: descobrir situações em que o software se comporta incorretamente, de forma indesejável ou diferente das especificações.
Verificação e validação
Verificação: checar se o software foi construído conforme os requisitos funcionais e não funcionais (estamos construindo o produto de maneira certa?).
Validação: garantir que o software atende às expectativas do cliente e às especificações (estamos construindo o produto certo?).
Inspeção e eficiência
Inspeção de software (verificação):
- Erros podem mascarar outros erros; como a inspeção é estática, ela pode descobrir muitos erros sem execução.
- Versões incompletas podem ser inspecionadas sem custos adicionais; testes exigiriam dispositivos especializados.
- A inspeção pode avaliar também qualidade do programa, conformidade com padrões, portabilidade e manutenibilidade.
- Inspeções são frequentemente mais eficientes que testes dinâmicos para detectar determinados problemas.
Três testes do software (reiterado)
- Testes de desenvolvimento: teste durante o desenvolvimento para descobrir bugs; projetos e programadores envolvidos.
- Testes de release (caixa preta): equipe independente testa versão completa antes de liberar para usuários.
- Teste de usuário (aceitação): usuários testam o sistema em seu próprio ambiente.
Testes de regressão e automatizados (reiterado)
Testes de regressão: reexecução de testes anteriores para verificar se alterações não introduziram novos bugs.
Testes automatizados: codificados em programas que são executados sempre que o sistema é testado. Não podem ser totalmente automatizados; apenas verificam que o programa faz o que se propõe ou detectam efeitos colaterais indesejados.
Processo de teste automatizado (reiterado)
- Configuração: inicia o sistema com o caso de teste.
- Parte de chamada: quando você chama o objeto ou método a ser testado.
- Parte de afirmação: compara o resultado da chamada com o resultado esperado.
Testes de desenvolvimento detalhados (reiterado)
Responsáveis pelo desenvolvimento de testes e manutenção de registros detalhados para descobrir bugs:
- Teste unitário: unidades individuais ou classes testadas isoladamente.
- Teste de componentes: varias unidades integradas para criar componentes compostos; foco nas interfaces.
- Teste de sistema: integração de componentes e teste do sistema como um todo, verificando a interação entre componentes.
Unitários automatizados e frameworks (reiterado)
Frameworks de teste unitário permitem escrever testes que são executados automaticamente e reportam sucesso ou falha, possibilitando execução rápida de todo o conjunto de testes após alterações no código.
Escolhas de casos de teste unitário e estratégias (reiterado)
Objetivos: demonstrar comportamento esperado e revelar defeitos. Estratégias: particionamento de entradas e testes baseados em diretrizes.
Testes baseados em requisitos, cenário, desempenho e usuário (reiterado)
- Teste baseado em requisitos: requisito escrito de modo que um teste possa ser projetado para ele.
- Teste de cenário: imaginar cenários típicos de uso para criar casos de teste de release.
- Teste de desempenho: assegurar que o sistema processe a carga esperada.
- Teste de usuário: estágio em que usuários dão entradas e feedback; ambiente do usuário influencia confiabilidade, desempenho, usabilidade e robustez (beta, aceitação, alfa).
Testes de release (reiterado)
Objetivo: convencer que o sistema é bom o suficiente para uso, mostrando que oferece funcionalidade, desempenho e confiança especificados e que não falhará em uso normal.
Diferença entre teste de release e teste de sistema
O teste de release deve ser realizado por uma equipe separada que não esteve envolvida no desenvolvimento do sistema. O teste de sistema feito pela equipe de desenvolvimento deve centrar-se em bugs e verificar se o sistema é bom suficiente para uso externo (teste de validação).
Observações finais
O conteúdo acima reorganiza e corrige o texto fornecido, mantendo todos os conceitos originais. Foram aplicadas correções ortográficas, gramaticais e de capitalização, além de formatação que melhora a leitura e a indexação para SEO: uso de títulos, listas e termos-chave relevantes.