DC-UFRPE/Licenciatura Plena em Computação/Engenharia de Software

Fonte: Wikiversidade

Programa da Disciplina[editar | editar código-fonte]

Nome: Engenharia de Software Código:06226
Departamento: Departamento de Computação Área: Ciência da Computação
Carga-horária total: 60 horas Créditos: 4
Carga-horária semanal: 4 horas (teóricas: 3; práticas: 1; EAD*: 0)
Pré-Requisitos: Nenhum Co-requisitos:Nenhum

Ementa[editar | editar código-fonte]

Processos de software. Ciclo de vida de desenvolvimento de software. Modelagem de software. Introdução a Modelos de Qualidade e de Gerenciamento de projetos de software. Ambientes de desenvolvimento de software. Padrões de projeto. Técnicas de teste de software. Reuso de componentes de software.

Prática como componente curricular (30h)[editar | editar código-fonte]

não há prática como componente curricular.

Objetivos[editar | editar código-fonte]

  • Familiarizar o aluno com fundamentos teóricos da engenharia de software;
  • Prover uma visão geral a todos os aspectos da produção de software;
  • Tornar o aluno capaz de compreender os principais aspectos relacionados à produção de um software.

Introdução[editar | editar código-fonte]

O que é engenharia de software?[editar | editar código-fonte]

A engenharia de software é um estudo detalhado da engenharia para o projeto, desenvolvimento e manutenção de software. A engenharia de software foi introduzida para resolver os problemas de projetos de software de baixa qualidade. Os problemas surgem quando um software geralmente excede prazos, orçamentos e níveis reduzidos de qualidade. Ele garante que o aplicativo seja construído de forma consistente, correta, dentro do prazo, do orçamento e dos requisitos. A demanda da engenharia de software também surgiu para atender à imensa taxa de mudança nos requisitos do usuário e no ambiente no qual o aplicativo deveria estar funcionando.

Descrição: Um produto de software é avaliado pela facilidade com que pode ser usado pelo usuário final e pelos recursos que oferece ao usuário. Um aplicativo deve pontuar nas seguintes áreas:

1) Operacional: Informa o quão bom um software funciona em operações como orçamento, usabilidade, eficiência, correção, funcionalidade, confiabilidade, segurança e proteção.

2) Transicional: A transição é importante quando um aplicativo é transferido de uma plataforma para outra. Assim, portabilidade, reutilização e adaptabilidade vêm nesta área.

3) Manutenção: Especifica o quão bom um software funciona no ambiente em mudança. Modularidade, manutenção, flexibilidade e escalabilidade vêm na parte de manutenção.

Ciclo de Vida de Desenvolvimento de Software é uma série de estágios na engenharia de software para desenvolver o aplicativo de software proposto, como:

1) Comunicação

2) Coleta de Requisitos

3) Estudo de Viabilidade

4) Análise do Sistema

5) Projeto de Software

6) Codificação

7) Teste

8) Integração

9) Implementação

10) Operações e manutenção

11) Disposição

A engenharia de software geralmente começa com a primeira etapa como uma iniciação de solicitação do usuário para uma tarefa específica ou uma saída. Ele envia sua solicitação a uma organização prestadora de serviços. A equipe de desenvolvimento de software segrega os requisitos do usuário, os requisitos do sistema e os requisitos funcionais. O requisito é coletado através da realização de entrevistas com um usuário, consulta a um banco de dados, estudo do sistema existente etc. Após o levantamento de requisitos, a equipe analisa se o software pode ser feito para atender a todos os requisitos do usuário. O desenvolvedor então decide um roteiro de seu plano. A análise do sistema também inclui uma compreensão das limitações do produto de software. De acordo com o requisito e análise, um projeto de software é feito.

A implementação do projeto de software começa em termos de escrever o código do programa em uma linguagem de programação adequada. O teste de software é feito durante a codificação pelos desenvolvedores e o teste completo é realizado por especialistas em testes em vários níveis de código, como teste de módulo, teste de programa, teste de produto, teste interno e teste do produto no envolvimento e feedback do usuário.

Qualidade de Software[editar | editar código-fonte]

O que é: Qualidade de Software?[editar | editar código-fonte]

A qualidade de software é definida como um campo de estudo e prática que descreve os atributos desejáveis ​​dos produtos de software. Existem duas abordagens principais para a qualidade de software: gerenciamento de defeitos e atributos de qualidade.

Abordagem de Gerenciamento de Defeitos de Qualidade de Software[editar | editar código-fonte]

Um defeito de software pode ser considerado como qualquer falha em atender aos requisitos do usuário final. Defeitos comuns incluem requisitos perdidos ou mal compreendidos e erros de design, lógica funcional, relacionamentos de dados, tempo de processo, verificação de validade e erros de codificação.

A abordagem de gerenciamento de defeitos de software é baseada na contagem e gerenciamento de defeitos. Os defeitos são geralmente categorizados por gravidade e os números em cada categoria são usados ​​para planejamento. Organizações de desenvolvimento de software mais maduras usam ferramentas, como matrizes de vazamento de defeitos (para contar o número de defeitos que passam pelas fases de desenvolvimento antes da detecção) e gráficos de controle, para medir e melhorar a capacidade do processo de desenvolvimento.

Abordagem de Atributos de Qualidade de Software[editar | editar código-fonte]

Essa abordagem de qualidade de software é melhor exemplificada por modelos de qualidade fixa, como ISO/IEC 25010:2011. Esta norma descreve uma hierarquia de oito características de qualidade, cada uma composta por subcaracterísticas:

  •    Adequação funcional
  •    Confiabilidade
  •    Operabilidade
  •    Eficiência de desempenho
  •    Segurança
  •    Compatibilidade
  •    Manutenibilidade
  •    Transferibilidade

Testes de Software[editar | editar código-fonte]

Por que Testar?[editar | editar código-fonte]

Primeiro, por que testar? Bom, testar é necessário para revelar a presença de defeitos, para diminuir a probabilidade de falha durante o uso e aumentar a confiança e satisfação do cliente com o software, o que inclui comprir os requesitos contratuais, e assegurar a qualidade do produto. É importante lembrar que falhas em softwares também podem causar perdas monetárias e humanas irreversíveis, como uma paralização em um centro financeiro ou falha no acionamento de um airbag, por exemplo. Assim, os testes são uma maneira de avaliar a qualidade e reduzir o risco de falha do software em operação, então, é melhor testar ;-)

Ciclo de desenvolvimento.[editar | editar código-fonte]

As atividades de teste devem está presentes durante todo o ciclo de desenvolvimento do software e não apenas em uma parte específica dele. Pra cada atividade de desenvolvimento, existe uma atividade de teste correspondente e cada nível tem seu objetivo de teste específico. Por isso também é importante que o testador esteja familiarizado com os modelos mais comuns de ciclo de vida do desenvolvimento. Os modelos mais comuns são:

  • O de desenvolvimento sequencial, onde é seguido um fluxo sequencial e linear das atividades, as atividades de desenvolvimento são concluídas uma após a outra, como o modelo cascata, ou seja, uma fase só começar quando a fase anterior estiver concluída e os testes só começam depois de todas as atividades de desenvolvimento;

temos também:

  • Os modelos de desenvolvimento incremental, que vão se estabelecendo o requisitos, a modelagem, a construção e o teste do sistema por partes, ou seja, os recursos do software vão crescendo de forma incremental, vão sendo feitas entregas de parte já prontas pro usuário utilizar;

e por fim,

  • O desenvolvimento iterativo, que é feito junto a uma série de ciclos, geralmente com uma duração fixa, onde cada iteração fornece um software funcional que faz parte de um subconjunto crescente que, por sua vez, faz parte de um conjunto geral/maior de recursos até que o software final seja entregue ou o desenvolvimento seja interrompido. Exemplos deles são o Scrum, que cada iteração tende a ser relativamente curta (como dias ou algumas semanas) e os incrementos de recursos são correspondentemente pequenos, como alguns aprimoramentos ou dois ou três novos recursos. e também tem o Kanban,  que é implementado com ou sem iterações de tamanho fixo e podem fornecer um único recurso após a conclusão ou agrupar recursos para serem liberados;

Os 7 princípios dos testes.[editar | editar código-fonte]

  1. O teste mostra a presença de defeitos e não a sua ausência: Então não é porque o teste não encontrou defeitos que eles não existem, o teste “apenas” reduz a probabilidade de defeitos não descobertos permanecerem no software.
  2. Testes exaustivos são impossíveis: Quer dizer que testar tudo, todas as combinações de entradas e pré-condições, é inviável, exceto em casos triviais. Então, a análise de risco, as técnicas de teste e as prioridades devem ser usadas para concentrar os esforços de teste, em vez de tentar testar exaustivamente.
  3. O teste inicial economiza tempo e dinheiro: Teste no início do ciclo de vida de desenvolvimento ajudam a reduzir ou eliminar alterações que dão despesas posteriormente, como um retrabalho que poderia ser evitado.
  4. Defeitos se agrupam: Um pequeno número de módulos geralmente contém a maioria dos defeitos descobertos durante o teste de pré-lançamento ou é responsável pela maioria das falhas operacionais. Então, esses agrupamentos de defeitos são uma entrada importante em uma análise de risco usada pra focar os esforços de teste como diz o princípio 2.
  5. Cuidado com o paradoxo do pesticida: Assim como um pesticida deixa de matar os insetos e lagartas  depois de um tempo, por eles adquirem resistência ao pesticida, se os mesmos testes forem repetidos várias vezes, esses testes podem não encontrar mais novos defeitos. Então, para detectar novos defeitos, os testes e os dados de teste podem precisar serem alterados.
  6. O teste depende do contexto: Por exemplo, um software de controle industrial de segurança crítica é testado de forma diferente de um aplicativo móvel de comércio eletrônico ou ainda um teste em um projeto ágil é feito de forma diferente do que um teste em um projeto de ciclo de vida sequencial, isso porque eles têm suas diferenças de desenvolvimento, o que mostra também a importância de conhecer diferentes tipos de aplicações como web e mobile, por exemplo.
  7. Ausência de erros é uma ilusão: Que está muito ligada ao primeiro e segundo princípios de que não dá para cobrir todos os casos existentes e de que os testes só mostram a presença de defeitos não a ausência deles, então olhando por eles, de fato a ausência de erros tende a não ser possível.

Etapas da atividade de teste.[editar | editar código-fonte]

No que consiste a atividade de teste, qual suas etapas?

  1. Planejamento: É onde é estabelecido os recursos humanos, como alocação pessoas, por exemplo; tecnológicos, onde se vai testar, qual SO, qual o ambiente, etc.; estratégias; técnicas, como teste funcional e estrutural; e critérios. Com tudo isso temos como saída o plano de teste.
  2. Projeto de casos de teste:  Descreve uma condição particular a ser testada bem como o comportamento esperado para aquele cenário. Então eles são essenciais para que você teste o fluxo principal e fluxos alternativos importantes do software, se você não faz o projeto de casos de teste é muito provável que você deixe de cobrir alguns cenários importantes que poderiam até levar a situações críticas.
  3. Execução: Execução dos testes de acordo com o planejamento e a fase que vocẽ se encontra, que veremos a seguir.
  4. e por fim temos a análise dos resultado: Onde vamos comparar os resultados obtidos com os resultados esperados e verificar se era esse mesmo o comportamento esperado para o software naquele cenário.

Níveis da atividade de teste.[editar | editar código-fonte]

E aqui temos os níveis da atividade de teste, cada nível é uma instância do processo de teste como um todo, elas consistem nas atividades descritas anteriormente, as atividades de teste, aplicadas no contexto de cada nível. Então temos:

  1. Teste de unidade ou de componentes: Que tem foco nas menores unidades de um software (funções, procedimentos, métodos e classes que são componentes testáveis separadamente) e pode ser feito durante a implementação mesmo pelo próprio desenvolvedor que vai busca por erros simples de programação, lógica e estrutura de dados incorretos e coisas do gênero.
  2. Teste de integração: Que se concentra nas interações entre componentes ou sistemas.
    • Entre componentes, ele tem cofo nas interações e interfaces entre os componentes integrados e é executado após o teste do componente geralmente de forma automatizada.
    • E entre sistemas, ele tem foco nas interações e interfaces entre sistemas, pacotes e microserviços e pode ser feito após o teste do sistema ou em paralelo a ele. Ele busca por problemas entre os subsistemas, APIs, banco de dados como falhas de comunicação entre componentes, dados incorretos ou ausentes por exemplo.
  3. Teste de sistema: Já o testes de sistema se concentram no comportamento e nas capacidades de todo o produto, geralmente considerando as execuções das tarefas de ponta a ponta do sistema e os comportamentos não funcionais exibidos ao executar tais tarefas, como desempenho, portabilidade e manutenção do software.
  4. Teste de regressão: A manutenção pode inserir novos defeitos, por isso esse teste costuma ser feito após manutenções do software ou após o teste de feature, como a gnt faz aqui, para garantir que as modificações estão corretas e os requisitos anteriormente testados  continuam válidos.
    • OBS: Às vezes se faz um sanity(ou testes de sanidade) também, no lugar da regreção, isso acontece quando não se tem muito tempo pra fazer outra regressão antes da entrega, então o sanity é justamente o subconjunto do teste de regressão e nele verifica-se se todos os menus, funções, comandos estão funcionando bem.

Técnicas de teste.[editar | editar código-fonte]

Um tipo ou uma técnica de teste é um grupo de atividades destinada a testar características específicas de um software, ou parte dele, com base em objetivos de teste específicos. São eles:

  1. Teste estrutural ou de caixa branca: Que avalia o comportamento interno do componente de software, ou seja, ele trabalha diretamente no código-fonte do software para avaliar aspectos como testes de condição, de fluxo de dados, de ciclo e caminhos lógicos. A maioria dos critérios dessa técnica utiliza uma representação  do programa conhecida como “grafo de programa”. Exemplos desses critérios são: o critério de McCabe ou teste de caminho base, que utiliza caracterısticas de controle da execução do programa para determinar os requisitos de teste; critérios de fluxo de dados e de controle; critério de todos os nós; todos os arcos; potenciais usos; etc.
  2. Teste funcional ou de caixa preta: Ele envolve testes que avaliam as funções que o sistema deve executar. Os testes funcionais devem ser realizados em todos os níveis de teste, embora o foco possa ser diferente em cada nível. Nele não é considerado o comportamento interno do software, são fornecidos dados de entrada, o teste é executado e o resultado obtido é comparado ao resultado esperado que é o resultado previamente conhecido, onde o sucesso se dá caso os resultados sejam iguais. Esse teste tem como principais passos identificar as funções que o software deve realizar e criar casos de testes capazes de verificar se tais funções estão sendo executadas corretamente. Exemplos de critérios do testes de caixa preta são: Particionamento de classes equivalentes, análise do valor limite, combinatorial( que são elementos que satisfazem um critério) e grafo de causa e efeito.
  3. Testes baseados em defeitos ou de mutação: Como o nome sugere, são testes baseados em defeitos típicos para ajudar a criar bons conjuntos de teste. Neles , São criados programas quase iguais ao original, porém com pequenas modificações que são chamados de mutantes. Quando seu conjunto de testes identificam erros nesses mutantes se diz que o mutante foi morto, caso contrário seu conjunto de teste não é bom o suficiente, ou seja, quanto mais mutantes mortos, melhor. E como são gerados os mutantes? São criados baseados nos operadores de mutação, que são regras de quais alterações devem ser feitas com base na linguagem de programação que o programa é escrito, por exemplo, em C existem 75 operadores de mutação que consistem em variáveis e constantes, operadores aritméticos e de decisão. Há mutantes que são tão similares aos programas originais que não podem ser mortos, esses mutantes são chamados de mutantes equivalentes. Também há um score de mutação que é: quantidade de mutantes mortos /(dividido pelo) total de mutantes -(menos) os mutantes equivalentes. Por exemplo, foram feitos um total de 110 mutantes, 10 deles eram mutantes equivalentes e 60 mutantes foram mortos. Então, vai ficar 60/100 = 0,6.
  4. Testes exploratórios: São testes que buscam além das especificações e requisitos do sistema. Eles tem como objetivo encontrar defeitos que normalmente  não são capturados por outras abordagens, como testes scriptados, mas são uma atividade complementar a testes planejados. Eles costumam ser usados quando há um curto ciclo de desenvolvimento, ou a documentação sofre constantes mudanças ou ainda estão desatualizadas.

Automação de testes mobile com Apium[editar | editar código-fonte]

Esta seção tem como objetivo compartilhar instruções e informações para você dar o pontapé inicial na automação de testes mobile com a ferramenta Apium. Nela, você verá oque é o Apium, a instalação dos pré-requezitos, oque são as sessões do Apium, emulação de dispositivos e instalação de APKs e escrita do código de automação de testes, clique aqui.

Automação de testes com cypress[editar | editar código-fonte]

O Cypress é uma ferramenta de teste de front-end de última geração criada para a web moderna. Abordamos os principais pontos problemáticos que os desenvolvedores e engenheiros de controle de qualidade enfrentam ao testar aplicativos modernos.[1] [2]

Metodologias ágeis[editar | editar código-fonte]

A indústria de software começou a se desenvolver a partir dos anos 1970, quando a IBM abriu as portas de um mercado totalmente novo. Para isso, ela lançou mão de uma estratégia agressiva, comercializando softwares separados dos equipamentos e de código fechado. Embora esse modelo tenha sido bem sucedido comercialmente, permitindo a venda de programas “de prateleira” até em supermercados, tecnicamente ele tinha problemas. Um deles era a impossibilidade de correção de falhas em razão da inacessibilidade do código-fonte, o que só mudaria a partir de 1984, graças a Richard Stallman, fundador da Free Software Foundation (FSF). Apesar da evolução em termos de acesso, os métodos de desenvolvimento permaneciam os mesmos, com velhas práticas herdadas da indústria. A metodologia ágil surge então como resposta à necessidade de mudar os processos, tornando a indústria de softwares capaz de responder às demandas dos seus clientes.

De certa forma, o método ágil foi um grito de “basta” dado pelo Manifesto para Desenvolvimento Ágil de Software. O movimento propôs uma nova abordagem para o desenvolvimento de soluções tecnológicas, mais adequada aos desafios do seu tempo. São signatários desse documento histórico 17 nomes de peso da indústria de tecnologia, todos com importantes contribuições em seus respectivos segmentos.

Ele parte de quatro valores fundamentais:

  • Indivíduos e interações são mais importantes que processos e ferramentas
  • Software em funcionamento é melhor que uma documentação abrangente
  • Colaboração com o cliente é superior a negociação de contratos
  • Responder a mudanças vale mais que seguir um plano.

Destaque para a observação que se segue a esses valores:

“Mesmo havendo valor nos itens à direita, valorizamos mais os itens à esquerda”.[3]

Turmas[editar | editar código-fonte]

  • 2019.1
  • 2019.2
  • 2020.1
  • 2020.2
  • 2020.3 (PLE)
  • 2020.4 (PLE)
  • 2021.1
  • 2021.2

Bibliografia[editar | editar código-fonte]

Bibliografia básica:[editar | editar código-fonte]

  1. PRESSMAN, R., MAXIN, B.R. Engenharia de Software: Uma Abordagem Profissional. 8. ed. Porto Alegre: McGrawHill, 2016.
  2. SOMMERVILLE, I. Engenharia de Software. 9. ed. São Paulo: Pearson Brasil, 2011.
  3. IEEE Computer Society. Guide to the Software Engineering Body of Knowledge (SWEBOK), 2004. Available in http://www.computer.org/portal/web/swebok
  4. VALENTE, T.M. Engenharia de Software Moderna: Princípios e Práticas para Desenvolvimento de Software com Produtividade. Local de publicação: UmLivro, 2020.
  5. MACORATTI, J.C. O ciclo de vida do desenvolvimento de Software. macoratti.net. Disponível em: https://www.macoratti.net/17/09/net_slcd1.htm. Acesso em: 07/08/2022.

Bibliografia complementar:[editar | editar código-fonte]

  1. OWLER, M. UML Essencial: um breve guia para linguagem padrão. Bookman Editora, 2014.
  2. PMBOK. A guide to the project management body of knowledge: PMBOK Guide- Fifth Edition Project Management Institute Newtown Square PA, USA. 2013
  3. BOOCH, G.; RUMBAUGH, J.; JACOBSON, I. UML - Guia do Usuário. 2ed. Rio de Janeiro: Campus, 2006.
  4. WELLS, D. Extreme Programming: a gentle introduction, 2009.
  5. SCHWABER, K.; BEEDLE, M. Agile software development with Scrum. [S.l.]: Microsoft Press, 2004.
  6. GAMMA, E.; HELM, R.; JOHNSON, R.; VLISSIDES, J. Padrões de Projeto: soluções reutilizáveis de software orientado a objetos. Porto Alegre: Bookman, 2004.
  7. ROCHA, Ana Regina Cavalcante da; MALDONADO, José Carlos; WEBER, Kival Chaves. Qualidade de software. São Paulo: Prentice Hall, 2001.

Conteúdos complementares:[editar | editar código-fonte]

Certified Tester Foundation Level Syllabus, Version 2018 V3.1, International Software Testing Qualifications Board.

Os Agilistas - Podcast sobre agilismo.

Notícias sobre Engenharia de Software[editar | editar código-fonte]

Referências:[editar | editar código-fonte]

  1. https://www.cypress.io/
  2. https://docs.cypress.io/guides/overview/why-cypress
  3. https://fia.com.br/blog/metodologias-ageis/