Você está na página 1de 48

ENGENHARIA DE SOFTWARE

AULA 06

Prof. José Carlos Correia Lima da Silva Filho


E-mail: jose.lima@estacio.br
ENGENHARIA DE SOFTWARE
Atividade Avaliativa
Em grupos, os alunos deverão escolher um sistema que seja do
conhecimento de todos (rede social, aplicativo de mensagens,
delivery, internet banking, etc.) e listar 10 casos de teste, que
podem abordar diversos cenários. Após o trabalho, os grupos
deverão apresentar os seus casos de teste, para os demais alunos.

Este trabalho vale 1,0 ponto, para compor a nota da AV1.

Pode-se usar a bibliografia da aula ou outra na internet(neste caso


TEM que se referenciar a origem: http://xxx.xxx.xx ) OBS: Trabalho
de 2 a 4 páginas (formato PDF), Não esqueça de colocar matrícula e
nome COMPLETO no trabalho

Os trabalhos deverão ser entregues ao professor por e-mail:


jose.lima@estacio.br
ENGENHARIA DE SOFTWARE
Tema

FASES DO DESENVOLVIMENTO DE SOFTWARE


ENGENHARIA DE SOFTWARE
Tema

IMPLEMENTAÇÃO E TESTES
TDD - Test Driven Development
• O que é?

• -TDD (Test Driven Development) é um técnica de programação ágil.


Com TDD especificamos nosso software em detalhes no momento
que vamos escrevê-lo criando testes executáveis e rodando-os de
maneira que eles mesmos testem nosso software.
• Serve para diagnosticar precocemente “bugs” que podem vir a ser
problemas na finalização do projeto.
TDD - Test Driven Development
• Genericamente: quando escrever um software, começar escrevendo
seu teste, uma classe que vai testar o software, assim, testar o
software e o remodelar até que os testes não falharem mais,então a
TDD pode ser definida como uma técnica de programação onde todo
o código produzido é criado em resposta a um código que falhou.
TDD - Test Driven Development
• Como funciona?

• -Escrever um teste, rodar este teste até que algo falhe, escrever o
código fonte mais simples possível para passar neste teste, escrever o
teste (melhorando para cobrir mais funções do código fonte do
produto), testar até que algo falhe, reescrever o código para que ele
passe no teste…. Permanecer nesse ciclo até o software estar
completo.
TDD - Test Driven Development
• ..::::Vantagens::::..

• -Simplicidade;
• -Confiança no código;
• -Documentação; e
• -Facilidade com refactorings.
TDD - Test Driven Development
• Incentiva a simplicidade: como a solução vai surgindo pouco a pouco,
a tendência é que não se perca tempo com aquilo que não tem
certeza que será usado em seguida. Expressões como “You Ain’t
Gonna Need It ”:”Voce não vai precisar disso” e “Keep It Simple,
Stupid “:”deixar simples,patético”são recorrentes quando se está
programando orientado a testes.
TDD - Test Driven Development
• Aumenta a confiança no código: o sistema funciona de maneira
estável porque existem testes que foram utilizados durante sua
criação e validam tudo o que foi criado. E se ainda assim algum erro
surgir, um novo teste é criado para reproduzí-lo e garantir que depois
de solucionado ele não irá se repetir.
TDD - Test Driven Development
• Ajuda como documentação: testes bem definidos são mais fáceis de
ler que o código fonte em si, eles são uma fonte eficiente para
entender o que o software faz. A documentação sempre estará
atualizada com a aplicação. O teste aponta a funcionalidade do
software.
TDD - Test Driven Development
• Facilita refactorings: quanto mais testes existem no sistema, maior é
a segurança para fazer refactorings. Um erro causado por algum
refactoring dificilmente vai passar despercebido quando um ou mais
testes falharem após a mudança.
TDD - Test Driven Development
Em TDD, um teste é um pedaço de software. A diferença entre teste
e o código que está sendo produzido é que os testes têm 2 funções
principais:
 De especificação: definir uma regra que o software deve obedecer.
 De validação: verificar que a regra é obedecida pelo software.
Geralmente os testes são criados com algum framework do tipo
xUnit (jUnit, nUnit Test::Unit etc) , mas também podem ser feitos
num nível de funcionalidades (através de softwares como o FitNesse
e Selenium) . Estas ferramentas servem basicamente para organizar
os testes e facilitar na criação das verificações.
TDD - Test Driven Development
• Processo de criação de desenvolvimento orientado a testes :

• -3 passos são repetidos até que não se consiga pensar em novos


testes, o que indica que a funcionalidade está pronta.
TDD - Test Driven Development
• 1- Escrever um teste que falhe. Pensar no que o código deve fazer,
definir quais são as verificações que precisam ser feitas. Não há um
limite no número de testes, portanto quanto menos funções cada
teste descrever ou verificar, melhor. Não é preciso se preocupar se a
classe ou método ainda não existe. Pensar primeiro no teste e só
depois que este estiver pronto, criar o esqueleto de código necessário
para que ele compile e falhe ao rodar.
TDD - Test Driven Development
• 2- Fazer o teste passar. escrever o mínimo de código para que o teste
passe. Controlar o instinto natural do programador de tentar prever
tudo que o código vai fazer e apenas fazer o teste passar. Mesmo que
tenha certeza que o código deve fazer mais coisas, fazer os testes
passarem deve ser a única preocupação nesse estágio.
TDD - Test Driven Development
• 3- Refatorar . Se o teste passar, verificar o que pode ser melhorado
no código. Geralmente para um teste passar é preciso inserir
duplicação através de constantes (técnica conhecida como Fake It).
Agora é a hora de melhorar o código e remover as duplicações,
lembrando que os testes devem continuar passando.
Exemplo
• Criar uma classe que diga se dada uma data, essa data se encontra
em determinado padrão.
Exemplo
• Primeiro passo:
• Criar um teste vazio que falha

import unittest
class FooTests(unittest.TestCase):

def testFoo(self):
self.failUnless(False)

def main():
unittest.main()
if __name__ == '__main__':
main()
Exemplo
 Continua-se codificando o teste, mesmo sem a classe a ser testada estar implementada
 Agora já se sabe um pouco mais sobre o problema e o método testFoo foi alterado para
testMatches

import unittest
class FooTests(unittest.TestCase):

def testMatches(self):
p = DatePattern(2004, 9, 28)
d = datetime.date(2004, 9, 28) self.failUnless(p.matches(d))

def main():
unittest.main()
if __name__ == '__main__':
main()
Exemplo
• Nesse ponto, temos que fazer o teste rodar...
• Então vamos criar a classe a ser testada

class DatePattern:
def __init__(self, year, month, day):
pass

def matches(self, date):


return True
Exemplo
• O código de matches na classe testada não tem valor
• Como justificar a necessidade de uma real implementação ?
• Com outro teste !!

def testMatchesFalse(self):
p = DatePattern(2004, 9, 28)
d = datetime.date(2004, 9, 29) self.failIf(p.matches(d))
Exemplo
• Para que o teste anterior rode alteramos a função matches

class DatePattern:

def __init__(self, year, month, day):


self.date = datetime.date(year, month, day)

def matches(self, date):


return self.date == date
Exemplo
• Nesse ponto os dois testes passam e parece que a classe DatePattern
é apenas um encapsulamento da classe date
• Qual a justificativa para a classe DatePattern ?

def testMatchesYearAsWildCard(self):
p = DatePattern(0, 4, 10)
d = datetime.date(2005, 4, 10) self.failUnless(p.matches(d))

• Esse teste falha !!


Exemplo
• Hora de fazer o novo teste passar
class DatePattern:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def matches(self, date):


return ((self.year and self.year == date.year or True) and self.month ==
date.month
and self.day == date.day)
Exemplo
• Adicionando novo método para checagem do mês

def testMatchesYearAndMonthAsWildCards(self):
p = DatePattern(0, 0, 1)
d = datetime.date(2004, 10, 1) self.failUnless(p.matches(d))

• Não Passou !!
• Consertar

def matches(self, date):


return ((self.year and self.year == date.year or True)
and (self.month and self.month == date.month or True)
and self.day == date.day)
Exemplo
• Código do método matches após os testes

def matches(self, date):


return ((self.year and self.year == date.year or True)
and (self.month and self.month == date.month or True) and (self.day and self.day
== date.day or True)
and (self.weekday and self.weekday == date.weekday() or True))

• Hora do Refactoring
Exemplo
 Refactoring (método matches muito mais claro agora não concorda?)

def matches(self, date):


return (self.yearMatches(date)
and self.monthMatches(date)
and self.dayMatches(date)
and self.weekdayMatches(date))

def yearMatches(self, date):


if not self.year: return True
return self.year == date.year

def monthMatches(self, date):


if not self.month: return True
return self.month == date.month

def dayMatches(self, date):


if not self.day: return True
return self.day == date.day

def weekdayMatches(self, date):


if not self.weekday: return True
return self.weekday == date.weekday()
ENGENHARIA DE SOFTWARE
Vídeo

Você ainda faz testes de software manuais? - YouTube


ENGENHARIA DE SOFTWARE
Tema

MANUTENÇÃO
Manutenção de Software
• Disciplina responsável por lidar com as
mudanças relacionados ao software depois
da sua entrega
•Software: código + documentação (requisitos,
análise, projeto, manuais, etc)

• “Ato de manter uma entidade em bom estado


de reparo, eficiência ou validade; para evitar
falhas ou declínio” (IEEE)
Custo da Manutenção

Representa até 90% dos custos de


desenvolvimento
33
Manutenibilidade
• Facilidade de manutenção de um sistema

• Difícil de quantificar
•Alguns aspectos do sistema podem ser medidos
(ex: complexidade, portabilidade)

•Entretanto não existe fórmula mágica

• Apesar disso, reconhecer características de


um sistema fácil de manter é importante
Manutenibilidade (exemplo
de métricas)
• Métricas de Chidamber-Kemerer (CK):
específicas para sistemas orientado a objetos
• Profundidade da Herança (DIT)

• Número de Filhos (NOC)

• Acoplamento entre Objetos (CBO)

• Falta de Coesão em Métodos (LCOM)

• Métodos Ponderados por Classes (WMC)

• Resposta para Classe (RFC)


Desenvolvimento x Manutenção
• Adicionar uma nova funcionalidade durante o
desenvolvimento é mais “fácil” que durante a manutenção

• Manutenção de software deve respeitar certos parâmetros


e restrições existentes

• Ex: ao projetar uma nova funcionalidade, o mantenedor


deve investigar o sistema atual para abstrair sua
arquitetura e detalhes de baixo-nível
•Realizar como a mudança será acomodada

•Prever o impacto da mudança (efeito cascata)

•Determinar as características necessárias para o trabalho


• Arquitetos e construtores devem tomar cuidado para não
enfraquecer a estrutura existente de uma casa quando
adições são realizadas

• Apesar do custo de um novo cômodo ser mais barato que o


37
custo de uma construção completa, o custo por metro
quadrado é muito mais alto

• Isso ocorre pois é necessário: remoção de paredes,


alteração do encanamento/fiação, cuidados…
Razões para
Manutenção de Software
• Se um sistema é utilizando, ele nunca está finalizado pois
precisa sempre evoluir para:
• Adicionar funcionalidades Corrigir

• defeitos

Melhorar
• design
Comunicar

com outros sistemas Migrar


de SO, BD, bibliotecas, etc Adaptar a
diferentes hardware Adaptar a leis,

regras de negócio, etc Refatorar

código

Categorias de Manutenção

• Manutenção corretiva

• Manutenção preventiva

• Manutenção adaptativa

• Manutenção perfectiva

SWEBOK - IEEE
Categorias de Manutenção

14 http://www.leandromtr.com/tecnologia-informacao/tipos-de-manutencao-de-
software
Manutenção Corretiva

• Modificações no software para corrigir defeitos

• Ex: defeitos em requisitos, projeto, código…

• Devido a sua natureza “ad hoc”, pode gerar


outros problemas como aumento de
complexidade e outros efeitos cascatas
Manutenção Preventiva
• Modificações no software para prevenir potenciais
problemas no futuro

• Lida com o deterioramento de estruturas, previne


falhas e melhora a manutenabilidade

• Torna os programas mais fáceis de entender e


facilita trabalhos de manutenção futuros

• Ex: reestruturação de código, otimização de código,


refatoração, atualização de documentação…
Manutenção Adaptativa
• Adaptações para manter o software usável
devido às alterações no ambiente externo

• Ocorre pois ambiente está em constante


evolução, mesmo quando defeitos não existem

• Ex: alteração no SO, BD, servidor, compilador,


bibliotecas, frameworks, hardware…

• Se SO é atualizado, mudanças podem ser realizadas


no software para acomodar o novo SO
Manutenção Perfectiva (ou
Evolutiva)

• Modificações para fornecer melhorias aos


usuários

• Expande os requisitos do sistema

• Quando o software se torna útil, os usuários


solicitam melhorias além do escopo inicial

• Ex: novas funcionalidades


Proporção de Manutenção

45

http://www.leandromtr.com/tecnologia-informacao/tipos-de-manutencao-de-
software
Leis de Lehman
• O termo manutenção de software data dos anos 60/70

• Durante um período de 20 anos de pesquisas, formulou-


se o termo “Leis de Evolução” proposto por Lehman

• 8 leis de evolução

• Leis: Mudança contínua, Complexidade crescente, Auto


regulação, Conservação da estabilidade organizacional,
Conservação de familiaridade, Crescimento Contínuo,
Declínio da qualidade, Sistema de feedback
Leis de Lehman
1.Mudança contínua: software deve ser continuamente
adaptado, senão torna-se menos satisfatório

2.Complexidade crescente: se não forem tomadas medidas


para reduzir complexidade, ela irá aumentar progressivamente

6.Crescimento contínuo: software deve ter funcionalidades


ampliadas para manter a satisfação dos seus usuários; o
projeto inicial não inclui tudo e deve ser aumentado

7.Declínio da qualidade: software perde qualidade se não é


alterado para refletir as mudanças do ambiente externo
ENGENHARIA DE SOFTWARE
Atividade Avaliativa
Em grupos, os alunos deverão criar um mapa mental incluindo
todos os conceitos aprendidos sobre testes de software. Para isso,
poderão utilizar a ferramenta Miro, ou outra da preferência do
grupo.

Este trabalho vale 1,0 ponto, para compor a nota da AV1.

Os trabalhos deverão ser entregues ao professor por e-mail:


jose.lima@estacio.br

Você também pode gostar