Blog do Abu: Novembro 2008
Melhorando a Confiabilidade do Sistema Durante a Sprint
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.
Postado por Nelson Abu Samra Rahal Junior às 16:12 2 comentários: Links para esta postagem
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.
Postado por Nelson Abu Samra Rahal Junior às 12:11 Nenhum comentário: Links para esta postagem
Documentação viva com Teste de Software II
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
Os testes ficam...
#Mostrar comentário realizado para livro
def test_mostra_comentario
#Mostrar mais de um comentário realizado para o livro
def test_mostra_varios_comentarios
#Mostrar inexistência de comentário para um livro
def test_livro_sem_comentario
#Visualizar marcador de mais comentários que o valor maximo
#permitido para visualização para o livro
def test_visualiza_marcador_comentario
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.
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
Demais testes....
#O sistema identifica que o livro possui dois comentários
#O sistema identifica que o livro não possui comentários
#O sistema recupera o comentário em branco do livro
#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 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
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.
Postado por Nelson Abu Samra Rahal Junior às 14:25 Nenhum comentário: Links para esta postagem
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:
Postado por Nelson Abu Samra Rahal Junior às 13:27 3 comentários: Links para esta postagem
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.
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
create app/models/livro.rb
create test/unit/livro_test.rb
create test/fixtures/livros.yml
create db/migrate/002_create_livros.rb
ruby script/generate model comentario
create app/models/comentario.rb
create test/unit/comentario_test.rb
create test/fixtures/comentarios.yml
create db/migrate/003_create_comentarios.rb
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
nome: Ruby OnRails
nome: Java
nome: Lean Solutions
nome: Livro sem comentario
Comentários.yml
livro_id: 1
comentario: xxxxx xxxxx
livro_id: 2
comentario: yyyyy xxxxx
livro_id: 3
comentario: xxxx1 xxxxx
comentario: xxxx2 xxxxx
comentario: xxxx3 xxxxx
comentario: xxxx4 xxxxx
comentario: xxxx5 xxxxx
comentario: xxxx6 xxxxx
comentario: xxxx7 xxxxx
Massa de dados X Testes
Para atender esta necessidade foi criado os registros necessários para o cadastro de livros
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
Para atender esta necessidade foi criado um registro de livro que não vai ter comentários
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.
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.
Vamos criar a estrutura de testes do model de comentário
#Visualizar marcador de mais comentários que o valor maximo permitido para visualização para o livro
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."
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,
Postado por Nelson Abu Samra Rahal Junior às 12:10 Nenhum comentário: Links para esta postagem
Retirado do site: http://www.industrialxp.org/storyTdd.html
Postado por Nelson Abu Samra Rahal Junior às 09:02 Nenhum comentário: Links para esta postagem
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/
Postado por Nelson Abu Samra Rahal Junior às 08:10 Nenhum comentário: Links para esta postagem
Programadores, essa gente...
Eu recebi esta imagem via e-mail, não sei a referencia dela.
STDD (StoryTest-Driven Development)
Segue o link sobre um artigo de STDD (StoryTest-Driven Development).
Vale a pena ler este artigo,
Postado por Nelson Abu Samra Rahal Junior às 15:25 Nenhum comentário: Links para esta postagem
Fotos da II Palestra de Scrum realizada no Barddal
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.
Postado por Nelson Abu Samra Rahal Junior às 08:07 Um comentário: Links para esta postagem
TDD para o Cartão de Historia - 001
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.
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
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
create app/models/produto.rb
create test/unit/produto_test.rb
create test/fixtures/produtos.yml
create db/migrate/001_create_produtos.rb
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":
preco: 50.00
desconto: 10
preco: 80.00
nome: Ruby OnRails II
preco: 0.00
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)
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)
database: tdd_development
database: tdd_test
database: tdd_production
create database tdd_development;
create database tdd_test;
create database tdd_production;
Agora vamos editar o arquivo de definição das tabelas de banco de dados (001_create_produtos.rb).
class CreateProdutos <>
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
drop_table :produtos
Realizar a migração dos dados
Vamos executar o teste
Finished in 0.125 seconds.
Agora podemos melhorar o nosso teste e criar o método de negocio.
assert_equal(produto.valor_vista, 45)
Código do Model
def valor_vista
preco = self.preco
desconto = self.desconto
return preco_vista
Executamos o teste de novo
Agora vamos implementar o resto dos testes
class ProdutoTest <>
#Mostrar valor do desconto de venda a vista
def test_valor_desconto
assert_equal(produto.valor_desconto, 5)
#Mostrar percentual do desconto de venda a vista
def test_perc_desc
assert_equal(produto.perc_desc, 10)
#Mostrar o valor do produto sem desconto de venda a vista
def test_valor_produto
assert_equal(produto.valor_produto, 50)
#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
def test_valida_valor_desconto
ret = produto.valida_valor_desconto
assert_equal(ret, true)
#Validar valor do produto maior que zero para evitar produtos sem preço de venda
def test_valor_maior_que_zero_ok
ret = produto.valor_maior_que_zero
def test_valor_maior_que_zero_erro
produto = Produto.find(3)
assert_equal(ret, false)
O model após a implementação dos testes fica:
class Produto <>
def perc_desc
return self.desconto
def valor_produto
return self.preco
def valor_desconto
return valor_desconto
def valida_valor_desconto
if (valor_vista <>
def valor_maior_que_zero
if (valor_produto <= 0)
Devemos lembrar que o processo não é seqüencial e sim interativo e incremental.
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.