sexta-feira, 28 de novembro de 2008

Melhorando a Confiabilidade do Sistema Durante a Sprint

Oi pessoal,


Vamos falar de como podemos adaptar testes de software junto com a execução da Sprint. Neste texto não vamos falar sobre TDD e sim sobre o processo clássico de testes de software com uma adequação ao desenvolvimento ágil.

No planejamento da Sprint quando a equipe se reunião com o Product Owner é realizado o processo de analise de sistemas, nesta atividade a equipe analise cada Cartão de Historia e faz ANOTAÇÕES sobre os itens relevantes desta conversa. Estas anotações são registradas como um Histórico, para que exista uma aderência as necessidades que devem ser desenvolvidas.

Nesta mesma etapa (Planejamento da Sprint) entra o Analista de Testes, onde para cada Cartão de Historia ele elabora cenários de testes que o sistema vai ser submetido. Com as informações levantadas na Conversa com o Product Owner e os cenários de testes que o sistema vai ser submetido a equipe de construção passa a desenvolver o sistema.

Mas devemos deixar os desenvolvedores aguardando a relação de testes que o Analista de Teste vai criar? A resposta é não, o desenvolvimento é iniciado, pois sempre é possível realizar varias atividades ao mesmo tempo na Sprint que vai ser executada.

Para cada Cartão de Historia desenvolvido ou funcionalidades do Cartão de Historia identificadas nas Conversas com o Product Owner é possível realizar liberações para um testador de software. Este testador também faz parte da Equipe e o seu trabalho é realizar os testes durante a Sprint.

Alguns testes vão ser manuais e outros automatizados, vai depender do nível de construção do software já realizado durante a Sprint.

A união dos integrantes da equipe trabalhando juntos permite um conhecimento cada vez maior do negocio e desta maneira aumenta o grau de confiabilidade do sistema e possibilita a visão cada vez mais critica da equipe de tudo que esta sendo feito.

Deixarmos o testador como uma equipe a parte faz com que tenhamos uma perda de tempo com a transferência do código desenvolvido para a equipe de testes, a busca por erros pela equipe de teste e o retorno dos erros para a correção pela equipe de desenvolvimento, o que acarreta um gasto de tempo na execução deste processo.

Ágil é também evitar o desperdício e podemos diminuir a perda do tempo com a inserção do testador dentro da Sprint, pois os erros são identificados e corrigidos durante o desenvolvimento. Evitamos uma perda de tempo com o processo de passagem de Bastão de uma equipe para a outra, simplesmente fazendo a equipe de desenvolvimento e de teste de software trabalharem juntas.

Estar junto é muito importante, gera o espírito de equipe e comprometimento entre as pessoas.

Faz com que os problemas passem a ser NOSSOS problemas e não problemas da outra equipe.

Mas os testes no processo clássico também ocorrem após a Sprint estar terminada. Também temos os testes antes do termino da Sprint, para que o Product Owner receba um produto sem erro na Sprint Review.

Também é realizado testes de maneira clássica nas entregas de Releases, onde os integrantes da equipe de teste realizam uma checagem geral nos Cartões de Historia que fazem parte do sistema a ser entregue.

O ultimo ponto não menos importante é que a equipe junta permite uma gestão de escopo e controle dos requisitos de maneira mais sincronizada, quando temos equipes separadas existe a necessidade de uma comunicação melhor para alertas de alteração de escopo ou acordos realizados sobre funcionalidades. Uma equipe junta, próxima, permite com que esta comunicação ocorra de maneira mais fácil.

Um exemplo de como funciona o cenário de execução é:


1) Planejamento da Sprint

2) Identificação dos Testes para os Cartões de Historia / Inicio do Desenvolvimento

3) Testes sobre os Cartões de Historia desenvolvidos (Casos de Testes criados pelo Analista de Testes, Testes identificados pelo Analista de Testes para cada Cartão de Historia, Testes identificados pela equipe de desenvolvimento, Testes identificados pelo próprio testador)

4) Testes sobre a Sprint Terminada (Execução Manual e Execução Automatizada)

5) Sprint Review


Dica: Nem sempre temos uma equipe de testes nos nossos projetos, mas quando temos, temos que potencializar a busca preventiva de falhas e sem perder tempo com troca de Bastão entre as equipes. União, essa a palavra.

Amplexos,

Abu

Capacidade de Adaptação

Oi pessoal,


Após tanta chuva aqui em Floripa um dia de Sol.




Devemos sempre nos adaptarmos ao meio que estamos inseridos. Eu lembro de uma frase: “Não tem como segurar o rumo do rio, ele sempre encontra um novo caminho”.

O Scrum Máster deve sempre se adaptar ao modelo funcional que a empresa possui. Nem todas as empresas são projetizadas, o que permite um trabalho muito mais potencializado para o gestor de projetos. Varias corporações são funcionais ou possuem modelo misto de gestão (matriz fraca, mista ou forte).

O PMBok mostra muito bem como funciona as mais diversas formas de gestão das corporações e como o gestor de projetos trabalha nestes modelos. Vale a pena dar uma lida.

Eu falo sempre nos meus treinamentos “Devemos sempre nos adaptar a corporação que estamos trabalhando”.

Não adianta achar que após um curso de Scrum e ver como o Scrum Máster deve trabalhar vai chegar na empresa e mudar tudo, isto dificilmente vai ocorrer. As mudanças podem sim ocorrer, mas nem sempre na velocidade que desejamos.

Hoje eu trabalho com a responsabilidade do Scrum Máster dividida conforme a estrutura funcional da empresa que trabalho, onde temos a equipe, o Scrum Máster da equipe, o coordenador de área, o gerente de área e ainda o gerente de vários projetos.

Sendo que as responsabilidades de cada pessoa esta diretamente vinculada a sua estrutura funcional, isto é o que eu chamo de responsabilidade compartilhada de gestão de projetos numa estrutura organizacional “Funcional”.

Adaptação, esta é a técnica. Assim podemos implantar o processo e mostrar os resultados.


Abraços,

Abu

segunda-feira, 24 de novembro de 2008

Documentação viva com Teste de Software II

Oi pessoal,

Eu já fiz um post sobre este tema, mas vamos complementar o post já existente.

Post original (Documentação viva com Teste de Software): http://blogdoabu.blogspot.com/2008/10/documentao-viva-com-teste-de-software.html

[Exemplo 4] – [Cartão de Historia]

Como um cliente, quero ter os comentários referentes aos livros consultados, para que eu possa saber a opinião de quem já leu

[Testes] - Template: [ação] [resultado] [objeto]

Mostrar comentário realizado para livro
Mostrar mais de um comentário realizado para o livro
Mostrar inexistência de comentário para um livro
Visualizar marcador de mais comentários que o valor maximo permitido para visualização para o livro

[1]

Os testes ficam...

#Mostrar comentário realizado para livro
def test_mostra_comentario
end

#Mostrar mais de um comentário realizado para o livro
def test_mostra_varios_comentarios
end

#Mostrar inexistência de comentário para um livro
def test_livro_sem_comentario
end

#Visualizar marcador de mais comentários que o valor maximo
#permitido para visualização para o livro

def test_visualiza_marcador_comentario
end

[2]

Podemos observar que para cada método de teste implementado existe o texto do teste realizado

Podemos melhorar a documentação, trocando o texto do teste realizado por um cenário de execução, os mesmos utilizados em Casos de Uso.

Exemplo

#Mostrar comentário realizado para livro
def test_mostra_comentario
end

fica....

#O ator seleciona a funcionalidade de visualizar o comentário
#O sistema identifica que o livro possui apenas um comentário
#O sistema recupera o comentário existente no livro
#O sistema apresenta o comentário existente do livro para o Ator

def test_mostra_comentario
end

[4]

Demais testes....

#O ator seleciona a funcionalidade de visualizar o comentário
#O sistema identifica que o livro possui dois comentários
#O sistema recupera o comentário existente no livro
#O sistema apresenta o comentário existente do livro para o Ator

def test_mostra_varios_comentarios
end

#O ator seleciona a funcionalidade de visualizar o comentário
#O sistema identifica que o livro não possui comentários
#O sistema recupera o comentário em branco do livro
#O sistema apresenta o comentário existente do livro para o Ator

def test_livro_sem_comentario
end

#O ator seleciona a funcionalidade de visualizar o comentário
#O sistema identifica que o livro possui vários comentários
#O sistema identifica em parametrização a quantidade máxima
#de comentários possíveis para um livro
#O sistema recupera o comentário existente no livro
#O sistema apresenta os comentários existente no livro para o Ator
#O sistema apresenta o símbolo de existência de mais comentários
#alem dos já mostrados para o Ator

def test_visualiza_marcador_comentario
end

[5]

Quando nos olhamos os testes referentes a comentários identificamos todos os requisitos de negocio que um Cartão teve como definição. Essas funcionalidades são os nossos testes, identificados e anotados em cada Cartão de Historia.

Desta maneira passamos a adotar os testes como uma forma de Use Cases, com os seus mais diversos cenários de execução.

Se um teste falha, pode ser que o código possui algum problema ou que a regra de negocio mudou.

Os testes são organizados como nosso modelo de domínio, onde domínios fortes levam os pacotes de trabalho e domínios menores são a implementação das regras de negocio que o nosso domínio possui.


Abraços a todos,


Abu

sexta-feira, 21 de novembro de 2008

As 3 peneiras de Sócrates

Oi pessoal,


Este post veio do grupo de bate papo "planejamento@yahoogrupos.com.br".

Vamos ao conteúdo....

Aí vai as 3 peneiras de Sócrates.

Leia com atenção, e deste ponto de sua vida para frente, use-as
sempre; você vai se sentir melhor.

Um homem foi ao encontro de Sócrates levando ao filósofo uma
informação que julgava de seu interesse:

Quero contar-te uma coisa a respeito de um amigo teu!

Espera — disse o sábio. - Antes de contar-me, quero saber se fizeste passar essa informação pelas três peneiras.

Três peneiras? Que queres dizer?

Devemos sempre usar as três peneiras. Se não as conheces, presta bem atenção. A primeira é a peneira da VERDADE. Tens certeza de que isso que queres dizer-me é verdade?

Bem, foi o que ouvi outros contarem. Não sei exatamente se é verdade.

A segunda peneira é a da BONDADE. Com certeza, deves ter passado a informação pela peneira da bondade. Ou não?

Envergonhado, o homem respondeu:

Devo confessar que não.

A terceira peneira é a da UTILIDADE. Pensaste bem se é útil o que vieste falar a respeito do meu amigo?

Útil? Na verdade, não.

Então, - disse-lhe o sábio -, se o que queres contar-me não é verdadeiro, nem bom, nem útil, então é melhor que o guardes apenas para ti.



Abraços,

Abu

Implementando Cartões de Historias Priorizados pelo Product Owner

Uma das técnicas de se garantir o retorno de Investimento do cliente é implementar Itens de Backlog priorizados pelo cliente. Esta ação também permite com que os riscos de cancelamento do projeto fiquem diminuídos, pois o cliente passa a receber em primeiro lugar o que ele considera importante.

Mas nem sempre o item priorizado pelo Product Owner é na visão da equipe de TI o primeiro a ser implementado. Este conflito de interesses pode ser um problema para o Scrum Máster, mas eu sempre faço a observação:

Engenharia de Software é diferente de Engenharia Civil.


Se o cliente deseja um Item de Backlog que não possui os seus predecessores construídos não tem problema para o mundo virtual, nos em TI podemos criar estes predecessores de maneira que eles possam atender o Item de Backlog que o cliente deseja.

Vamos a um exemplo, o cliente considera em um sistema de venda de livros pela internet os comentários existentes a um livro mais importante que o cadastro de livro, isto é, ele deseja ver primeiro como será a solução dos comentários de um livro e após esta solução trabalhar com o cadastro do livro.

Este é um apenas um exemplo e é neste exemplo é que vamos mostrar como fazer a solução utilizando TDD e a implementação do item priorizado pelo cliente.

[Exemplo 4] – [Cartão de Historia]

Como um cliente, quero ter os comentários referentes aos livros consultados, para que eu possa saber a opinião de quem já leu

[Testes] - Template: [ação] [resultado] [objeto]

Mostrar comentário realizado para livro
Mostrar mais de um comentário realizado para o livro
Mostrar inexistência de comentário para um livro
Visualizar marcador de mais comentários que o valor maximo permitido para visualização para o livro


[1]
Temos que criar os models de livro e comentários. O livro não é a prioridade, mas para podermos realizar o item de backlog ele se faz necessário.

ruby script/generate model livro

exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/livro.rb
create test/unit/livro_test.rb
create test/fixtures/livros.yml
exists db/migrate
create db/migrate/002_create_livros.rb

ruby script/generate model comentario

exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/comentario.rb
create test/unit/comentario_test.rb
create test/fixtures/comentarios.yml
exists db/migrate
create db/migrate/003_create_comentarios.rb

[2]
O próximo passo é criarmos os registros necessários para atender os nossos testes, para que isso seja possível devemos alimentar as estruturas de Fixtures

Lembrando os nossos testes....

1) Mostrar comentário realizado para livro
2) Mostrar mais de um comentário realizado para o livro
3) Mostrar inexistência de comentário para um livro
4) Visualizar marcador de mais comentários que o valor maximo permitido para visualização para o livro

Livros.yml

one:
id: 1
nome: Ruby OnRails

two:
id: 2
nome: Java

three:
id: 3
nome: Lean Solutions

four:
id: 4
nome: Livro sem comentario

Comentários.yml

one:
id: 1
livro_id: 1
comentario: xxxxx xxxxx

two:
id: 2
livro_id: 2
comentario: xxxxx xxxxx

three:
id: 3
livro_id: 2
comentario: yyyyy xxxxx

four:
id: 4
livro_id: 3
comentario: xxxx1 xxxxx

five:
id: 5
livro_id: 3
comentario: xxxx2 xxxxx

six:
id: 6
livro_id: 3
comentario: xxxx3 xxxxx

seven:
id: 7
livro_id: 3
comentario: xxxx4 xxxxx

eight:
id: 8
livro_id: 3
comentario: xxxx5 xxxxx

nine:
id: 9
livro_id: 3
comentario: xxxx6 xxxxx

ten:
id: 10
livro_id: 3
comentario: xxxx7 xxxxx


[3]
Massa de dados X Testes

1) Mostrar comentário realizado para livro

Para atender esta necessidade foi criado os registros necessários para o cadastro de livros

2) Mostrar mais de um comentário realizado para o livro

Para atender esta necessidade foi criado os registros necessários para que um livro tenha apenas um comentário, não tenha comentário e que tenha uma quantidade grandes de comentários

3) Mostrar inexistência de comentário para um livro

Para atender esta necessidade foi criado um registro de livro que não vai ter comentários

4) Visualizar marcador de mais comentários que o valor maximo permitido para visualização para o livro

Para atender esta necessidade foi criado uma quantidade de comentários para um livro, porem não temos em nenhum lugar a informação que determina o valor maximo permitido de visualização. Nos podemos resolver este item de parametrização por uma estrutura de cadastros de parâmetros ou por uma constante. Vamos manter o foco no problema que é os comentários dos livros e não um Cartão de Historia que trate de Parametrização e criarmos uma constante.

Em momento adequado esta constante é retirada e passamos a implementar o Cartão de Historia referente a Parametrização.

[4]
Podemos observar que a massa de dados necessária para a implementação dos testes nos ajudou a criamos um modelo de dados e um modelo de objetos.

[5]
Vamos criar a estrutura de testes do model de comentário

#Mostrar comentário realizado para livro
def test_mostra_comentario
assert true
end

#Mostrar mais de um comentário realizado para o livro
def test_mostra_varios_comentarios
assert true
end

#Mostrar inexistência de comentário para um livro
def test_livro_sem_comentario
assert true
end

#Visualizar marcador de mais comentários que o valor maximo permitido para visualização para o livro
def test_visualiza_marcador_comentario
assert true
end

[6]
Agora passamos a implementar o model para que os testes sejam atendidos

“Não vamos colocar aqui no post o model implementado, não é o objetivo do post.”


[7]
Podemos observar que o item de backlog priorizado pelo cliente foi possível de ser implementado, para esta implementação foi necessário atacarmos predecessores, como o cadastro do livro e a parametrização da quantidade de comentários a serem mostrados.

Mas devemos gastar energia apenas na implementação do nosso foco, “Comentários em Livros” e não nos predecessores. Os predecessores devem ser implementados ate o limite do atendimento do Item de Backlog que é nosso foco.

Nos sabemos que teremos que refazer partes do código dos itens predecessores quando for a vez deles de ser priorizado pelo cliente, mas com esta técnica nos estamos atacando o que é importante para o cliente e ao mesmo tempo realizando analise de sistemas para identificar requisitos correlacionados ao requisitos que estamos trabalhando.

Estes requisitos correlacionados vão sendo evoluídos com a implementação do nosso foco e implementados de maneira mais consistente no momento que o cliente deseja.


Este post foi longo, abraços a todos,


Abu

Story Test-Driven Development

Oi pessoal,


Uma imagem vale mais do que mil palavras.





Retirado do site: http://www.industrialxp.org/storyTdd.html


Abraços,

Abu

Desenvolvimento Orientado a Testes (TDD)

Aqui vai um sumário de 10 segundos de TDD:

Desenvolvimento orientado a testes significa que você escreve um teste automatizado, então escreve apenas código suficiente para fazê-lo passar, então você refatora o código primeiramente para melhorar a legibilidade e remover duplicação. Enxague e repita.


Retirado do livro: Scrum e XP direto das Trincheiras, disponível para download na InfoQ-Br: http://www.infoq.com/br/


Abraços a todos,

Abu

Programadores, essa gente...

Oi pessoal,

Eu recebi esta imagem via e-mail, não sei a referencia dela.

Abraços a todos,

Abu

quinta-feira, 20 de novembro de 2008

STDD (StoryTest-Driven Development)

Oi pessoal,

Segue o link sobre um artigo de STDD (StoryTest-Driven Development).

http://www.industriallogic.com/papers/storytest.pdf

Vale a pena ler este artigo,

Abraços,

Abu







Fotos da II Palestra de Scrum realizada no Barddal

Oi pessoal,


No dia 14/11 foi realizada a segunda palestra de Scrum no Barddal. Este evento foi possível pelo apoio da Mirela (Vice Diretora Acadêmica) e do professor Fabio Favarim.

Neste encontro foi possível mostrar o framework de trabalho Scrum, imagens do Blog do Abu e debater sobre alguns conceitos de “Lean”.

Muito obrigado a todos os participantes e a todos que possibilitaram este evento.


Abu









quarta-feira, 19 de novembro de 2008

TDD para o Cartão de Historia - 001

Oi pessoal,


Segue a implementação do primeiro Cartão de Historia utilizando TDD. Eu sou um aprendiz em testes, mas eu espero que este post ajude a entender melhor o processo de desenvolvimento de software direcionado ao comportamento.

O código esta em Ruby. Por que Ruby??? Porque é divertido hahahaha

[Exemplo 1] – [Cartão de Historia]

Como um cliente, quero que o produto seja acompanhado com o valor de desconto para compra a vista, para que eu tenha a visibilidade da diferença monetária do produto a vista ou a prazo.

[Testes] - Template: [ação] [resultado] [objeto]

Mostrar valor do desconto de venda a vista
Mostrar percentual do desconto de venda a vista
Mostrar o valor do produto sem desconto de venda a vista
Mostrar o valor do produto com desconto de venda a vista

Validar valor do produto é maior que o valor do desconto para evitar um valor de desconto maior que o valor de venda

Validar valor do produto maior que zero para evitar produtos sem preço de venda

Mostrar valor do desconto de venda a prazo
Mostrar percentual do desconto de venda a prazo
Mostrar o valor do produto sem desconto na venda a prazo
Mostrar o valor do produto com desconto na venda a prazo


[1]
Para podermos criar os testes unitários do nosso Cartão de Historia vamos primeiramente criar um Model chamado Produto.

ruby script/generate model produto


exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/produto.rb
create test/unit/produto_test.rb
create test/fixtures/produtos.yml
create db/migrate
create db/migrate/001_create_produtos.rb

[2]
O ruby já criou a classe de teste chamada produto_test.rb

O meu primeiro passo foi identificar uma massa de dados para poder realizar o teste desejado. O teste escolhido foi “Mostrar valor do desconto de venda a vista”.

O ruby possibilita a criação de uma estrutura de carga de dados no banco de dados, chamada “Fixtures”. Para o meu teste eu criei dois registros no arquivo “produto.ymx”:

one:
 id: 1
 nome: Ruby OnRails
 preco: 50.00
 desconto: 10

two:
 id: 2
 nome: Java
 preco: 80.00
 desconto: 20

three:
 id: 3
 nome: Ruby OnRails II
 preco: 0.00
 desconto: 10

[3]
Após identificar a necessidade de massa de dados para teste, eu crie um algoritmo para poder executar o primeiro teste (arquivo: produto_test.rb).

# Mostrar o valor do produto com desconto de venda a vista
def test_valor_vista
 produto = Produto.find(1)
 preco = produto.preco
 desconto = produto.desconto
 desconto_perc = Float(desconto) / 100
 valor_desconto = preco * desconto_perc
 preco_vista = preco - valor_desconto
 assert_equal(preco_vista, 45)
end

[4]
Vamos criar o banco de dados para poder executar o teste

Devemos lembrar que o Ruby OnRails vai solicitar a configuração dos databases (database.yml)

development:
 adapter: mysql
 encoding: utf8
 database: tdd_development
 username: root
 password:
 host: localhost

test:
 adapter: mysql
 encoding: utf8
 database: tdd_test
 username: root
 password:
 host: localhost

production:
 adapter: mysql
 encoding: utf8
 database: tdd_production
 username: root
 password:
 host: localhost


create database tdd_development;

create database tdd_test;

create database tdd_production;

[5]
Agora vamos editar o arquivo de definição das tabelas de banco de dados (001_create_produtos.rb).

class CreateProdutos <>
 def self.up 
  create_table :produtos do |t| 
   t.string :nome, :limit => 100, :null => false
   t.decimal :preco, :precision => 6, :scale => 2, :null => false, :default => 0
   t.integer :desconto, :null => false, :default => 0 
   t.timestamps
  end
 end

 def self.down
  drop_table :produtos
 end
end

Realizar a migração dos dados

rake db:migrate



[6]
Vamos executar o teste

rake test:units

Started
......
Finished in 0.125 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

[7]
Agora podemos melhorar o nosso teste e criar o método de negocio.

Código do Teste

# Mostrar o valor do produto com desconto de venda a vista
def test_valor_vista
 produto = Produto.find(1)
 assert_equal(produto.valor_vista, 45)
end

Código do Model

def valor_vista
 preco = self.preco
 desconto = self.desconto
 desconto_perc = Float(desconto) / 100
 valor_desconto = preco * desconto_perc
 preco_vista = preco - valor_desconto
 return preco_vista
end

Executamos o teste de novo

rake test:units

Started
......
Finished in 0.125 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

[8]

Agora vamos implementar o resto dos testes

require File.dirname(__FILE__) + '/../test_helper'

class ProdutoTest <>
 # Replace this with your real tests. 
 #Mostrar valor do desconto de venda a vista 
 def test_valor_desconto 
  produto = Produto.find(1) 
  assert_equal(produto.valor_desconto, 5)
 end 

 #Mostrar percentual do desconto de venda a vista 
 def test_perc_desc 
  produto = Produto.find(1) 
  assert_equal(produto.perc_desc, 10) 
 end 

 #Mostrar o valor do produto sem desconto de venda a vista 
 def test_valor_produto 
  produto = Produto.find(1) 
  assert_equal(produto.valor_produto, 50) 
 end 

 #Mostrar o valor do produto com desconto de venda a vista 
 def test_valor_vista 
  produto = Produto.find(1) 
  assert_equal(produto.valor_vista, 45) 
 end 

 #Validar valor do produto é maior que o valor do desconto para evitar um valor de desconto maior que o valor de venda 
 def test_valida_valor_desconto 
  produto = Produto.find(1) 
  ret = produto.valida_valor_desconto 
  assert_equal(ret, true) 
 end 

 #Validar valor do produto maior que zero para evitar produtos sem preço de venda 
 def test_valor_maior_que_zero_ok 
  produto = Produto.find(1) 
  ret = produto.valor_maior_que_zero 
  assert_equal(ret, true) 
 end 

 #Validar valor do produto maior que zero para evitar produtos sem preço de venda 
 def test_valor_maior_que_zero_erro 
  produto = Produto.find(3) 
  ret = produto.valor_maior_que_zero 
  assert_equal(ret, false) 
 end 
end 

[9] 

O model após a implementação dos testes fica: 

class Produto <>
 def valor_vista 
  preco = self.preco 
  desconto = self.desconto 
  desconto_perc = Float(desconto) / 100 
  valor_desconto = preco * desconto_perc 
  preco_vista = preco - valor_desconto 
  return preco_vista 
 end 

 def perc_desc 
  return self.desconto 
 end 

 def valor_produto 
  return self.preco 
 end 

 def valor_desconto 
  preco = self.preco 
  desconto = self.desconto 
  desconto_perc = Float(desconto) / 100 
  valor_desconto = preco * desconto_perc 
  return valor_desconto 
 end 

 def valida_valor_desconto 
  if (valor_vista <>
   ret = false 
  else 
   ret = true 
  end 
  return ret 
 end 

 def valor_maior_que_zero 
  if (valor_produto <= 0) 
   ret = false 
  else 
   ret = true 
  end 
  return ret 
 end 
end 

[10] 

Devemos lembrar que o processo não é seqüencial e sim interativo e incremental.

[11]

Ficou faltando os testes de venda a prazo, como estamos realizando apenas as operações de venda a vista estes testes não vão ser implementados no momento. Os testes de venda a prazo devem ser encaminhados para um Cartão de Historia que trate da venda a prazo, para que as responsabilidades dos Cartões fiquem coesas.


Mostrar valor do desconto de venda a prazo
Mostrar percentual do desconto de venda a prazo
Mostrar o valor do produto sem desconto na venda a prazo
Mostrar o valor do produto com desconto na venda a prazo




Terminamos.....

Agora vamos implementar os outros Cartões de Historia nos próximos post´s.


Abu