61
Test-Driven Development O que é? O que não é? E o que isto tem a ver com você? Carlos Eduardo Miranda Arquiteto .Net Add Technologies

Test driven development

Embed Size (px)

Citation preview

Page 1: Test driven development

Test-Driven Development

O que é? O que não é?

E o que isto tem a ver com você?

Carlos Eduardo MirandaArquiteto .Net

Add Technologies

Page 2: Test driven development

Agenda Introdução Por que ela “ainda” não é um padrão amplamente utilizado pelo mercado? TDD - O que é? TDD - Benefícios TDD – O que não é? Mitos sobre o TDD Prática do TDD E caso algum teste tenha falhado? Encontrei um bug, e agora? Tudo Verde! Done! Dificuldades na implantação do TDD na Empresa O que isto tem a ver com você? Glossário Solução – Criação de uma classe de Pilha – Stack

Page 3: Test driven development

Introdução O assunto nunca esteve tão em voga quanto nos últimos

anos; Não se trata de mais apenas um “modismo“ do mercado; Traz diversos benefícios para as empresas e clientes; Maior parte dos projetos de software não atigem os seus

objetivos em pelo menos uma das dimensões (tempo, custo, qualidade, escopo);

Desenvolver software não é desenvolver um produto físico; Softwares apoiam as áreas de negócio das empresas e

estes mercados mudam constantemente; Os requisitos vão mudar!

Page 4: Test driven development

Por que ela “ainda” não é um padrão amplamente utilizado pelo mercado?

Contra-Produtiva e Contra-Intuitiva à primeira vista (“Como assim criar um teste de uma classe que ainda não existe?!”);

Desenvolvedores não gostam de criar testes unitários, pois são chatos;

Falta de tempo e recursos (cronogramas apertados e poucos recursos);

Resistência à mudanças; Desconhecimento por parte de Gerentes e

Desenvolvedores; Desenvolvimento ágil ainda é visto com desconfiança e

como “sem controle”;

Page 5: Test driven development

TDD - O que é? Prática que foi originada nas rodas de desenvolvedores SmallTalk; Amplamente utilizada em metodologias ágeis como o XP (eXtreme

Programming) e o Scrum; Prática para “Desenvolvimento de Software” que prega que todo e

qualquer desenvolvimento deva ser precedido da criação de uma suíte de testes e que toda duplicação de código deve ser eliminada;

Testes são desenvolvidos na mesma linguagem de programação do sistema em desenvolvimento;

Testes quando criados podem até mesmo não compilar, neste momento eles não necessitam compilar;

A única regra é que os testes sejam criados antes da implementação das funcionalidades do sistema;

Page 6: Test driven development

TDD - Benefícios Melhora na interface das classes da aplicação; Maior desacoplamento das classes ; Aumento na Produtividade; Aumento da confiança pelo desenvolvedor em fazer alterações; Possibilidade de fazer Refactor (Refatoração de código); Cobertura de cenários da aplicação; Possibilidade de auto documentação a partir da Suite de Testes; Flexibilidade – maior facilidade em abraçar às mudanças nos

requisitos; Deploy simplificado – garantia de uma versão estável a todo o

momento, pronta para subir para a homologação ou produção;

Page 7: Test driven development

TDD – O que não é?

Ferramenta de teste;A Resolução de todos os problemas no

desenvolvimento de sistemas;Padrões de Projeto (Design Patterns);

Page 8: Test driven development

Mitos sobre o TDD

Test-Driven Development != QATest-Driven Development != Testes UnitáriosTest-Driven Development != Design Patterns

Page 9: Test driven development

Prática do TDD0. Setup (somente executado uma vez no ciclo de vida do

projeto);1. Red – Criar um teste que falhe (eliminar falsos positivos);2. Green – Criar a implementação mais simples possível que

faça o teste passar;3. Refactor! – Refatorar a implementação, melhorando-a de

modo incremental e controlada, fazendo com que o código comunique melhor o seu intento, eliminando duplicidades no código, fazendo as alterações arquiteturais (se estas se mostrarem necessárias) e executando os testes a cada alteração por menor que esta seja;

Page 10: Test driven development

E caso algum teste tenha falhado?

Desfazer as últimas alterações, e refazer a funcionalidade de modo a não quebrar as funcionalidades construídas previamente;

O ideal é que a aplicação não seja quebrada (testes em vermelho) por mais do que poucos minutos;

Passos curtos, incrementais e controlados;

Page 11: Test driven development

Encontrei um bug, e agora?

Criar um teste que exponha este cenário descoberto, realizar a prática do TDD (Red – Green – Refactor!), assim como qualquer outro teste previamente planejado;

No longo prazo com a utilização desta prática teremos um produto cada vez melhor com uma quantidade maior de cenários cobertos, menos retrabalho e um número menor de bugs;

Page 12: Test driven development

Tudo Verde! Done!

Após a criação da sua Suíte de testes e a implementação do código que faz com que todos estes testes passem (assim como os testes para resolução de bugs), ou seja, tudo está verde, podemos concluir que o trabalho foi terminado para a iteração corrente;

Page 13: Test driven development

Dificuldades na implantação do TDD na Empresa

Investimento em treinamento;Grande barreiras culturais na empresa;Quebra de paradigma muito forte, pois põem

em cheque conceitos maduros na área de Desenvolvimento de Software (considerados como verdades absolutas);

Page 14: Test driven development

O que isto tem a ver com você?• Mais e mais empresas estão abraçando a idéia de

metodologias de desenvolvimento ágeis como XP e SCRUM;

• Demanda por profissionais que conheçam e já se utilizem destas metodologias e práticas deve crescer ao longo dos próximos anos;

• Desenvolvedores e empresas que abraçarem a mudança e assumirem que os requisitos vão mudar e que a maneira como estamos gerenciando os nossos projetos não é produtiva, certamente se beneficiarão mais e estarão na ponta quando o mercado como um todo fizer a transição;

• Eu estarei lá. E você?

Page 15: Test driven development

Glossário TDD – Test-Driven Development – Desenvolvimento

Dirigido a Testes. QA – Quality Assurance – Garantia da Qualidade. XP – eXtreme Programming – Programação Extrema é uma

metodologia ágil de desenvolvimento de software ágil, criada por Kent Beck.

SCRUM – é uma metodologia de gerenciamento de projetos, cujo nome vem de uma jogada do esporte rugby, em que os jogadores de cada time se encaixam formando uma espécie de muralha e onde outro jogador joga a bola no meio do túnel formado para que os dois grupos a disputem. Assim como em todas as metodologias ágeis o trabalho em equipe é fundamental.

Page 16: Test driven development

Solução – Criação de uma classe de Pilha – Stack

Problema:Criar uma classe que represente uma

pilha ilimitada em memória e que o acesso seja restrito ao último elemento inserido na pilha;

Page 17: Test driven development

Criar a Test List para a Pilha Analisando o requisito passado (Stack), foram observados os seguintes

testes iniciais:1. Criar uma pilha e verificar que está vazia;2. Inserir um objeto na Pilha e verificar que não está vazia;3. Inserir um objeto na Pilha , retirar este, e verificar que está vazia;4. Inserir um objeto na Pilha (guardando o seu valor), retirar este da Pilha e

verificar que estes são iguais;5. Inserir 3 objetos em sequência (guardando seus valores), e removê-los

verificando se estes são removidos na ordem correta;6. Retirar um elemento de uma Pilha sem elementos;7. Inserir um objeto na Pilha, buscar quem é o topo da Pilha e verificar que a

Pilha não está vazia;8. Inserir um objeto na Pilha (guardando o seu valor), buscar quem é o topo

da Pilha e verificar que estes são iguais;9. Buscar o topo de uma Pilha vazia;

Page 18: Test driven development

Análise da TestList

Analisando a TestList vemos que existem 3 operações e uma propriedade que podem ser executadas na Pilha:

Push(Object) (inserir um item na pilha);Pop() (remover um item da pilha, retonando-o);Top() (retornar o primeiro elemento sem retirá-lo

da pilha);IsEmpty (retorna um booleano indicando se a

pilha está vazia);

Page 19: Test driven development

Setup (executado somente uma vez)

Baixar do site http://www.nunit.org, o programa msi instalador;

Executar o programa de instalação do Nunit; Criar um projeto de testes para a classe a ser criada Stack; Referenciar a “dll” do framework de testes Nunit

(Nunit.Framework.dll) no projeto de testes; Referenciar o projeto da classe a ser testada; Fazer deste projeto, o projeto inicial da Solução; Configurar a inicialização automática do programa

Nunit.exe (interface visual dos testes unitários) na compilação do Projeto de Testes;

Page 20: Test driven development

Teste 1O primeiro teste escolhido foi verificar se uma pilha nova está vazia:// StackTests .cs using System;using NUnit.Framework;[TestFixture]public class StackTests{

[Test]public void Empty(){

Stack stack = new Stack();Assert.IsTrue(stack.IsEmpty);

}}Executar a solução;Erros de compilação (Stack não existe);

Page 21: Test driven development

Teste 1 (Red): Implementar o menor código que faça o teste compilar

// Stack.csusing System;public class Stack{

public Boolean IsEmpty{

get { return false; }}

}Executar a solução;Solução compilada com sucesso;Teste Empty falha (Red);

Page 22: Test driven development

Teste 1 (Green): Fazer o teste passar com a mais simples implementação

// Stack.csusing System;public class Stack{

public Boolean IsEmpty{

get { return true; }}

}Executar a solução;Solução compilada com sucesso;Teste Empty executado com sucesso;

Page 23: Test driven development

Teste 1 (Refactor!): Melhorar a implementação

// Stack.csusing System;public class Stack{

public Stack(){

this. _isEmpty = true; }private Boolean _isEmpty;public Boolean IsEmpty{

get { return this._isEmpty; }}

}Executar a solução;Solução compilada com sucesso;Teste Empty continua executando com sucesso;

Page 24: Test driven development

Teste 2O segundo teste escolhido foi verificar se ao adicionar um elemento a

pilha não está vazia:// StackTests .cs [Test]public void PushOne(){

Stack stack = new Stack();stack.Push(“primeiro elemento”);Assert.IsFalse(stack.IsEmpty, “Após a inclusão, IsEmpty deve ser false.”);

}Executar a solução;Erros de compilação (Stack não possui o método Push(Object));

Page 25: Test driven development

Teste 2 (Red): Implementar o menor código que faça o teste compilar

// Stack.csusing System;public class Stack{

public Stack(){

this._isEmpty = true; }private Boolean _isEmpty;public Boolean IsEmpty{

get { return this._isEmpty; }}public void Push(Object element_){}

}Executar a solução;Solução compilada com sucesso;Teste PushOne falha (Red);

Page 26: Test driven development

Teste 2 (Green): Fazer o teste passar com a mais simples implementação

// Stack.csusing System;public class Stack{

public Stack(){

this._isEmpty = true; }private Boolean _isEmpty;public Boolean IsEmpty{

get { return this._isEmpty; }}public void Push(Object element_){

this._isEmpty = false;}

}Executar a solução;Solução compilada com sucesso;Teste PushOne executado com sucesso;

Page 27: Test driven development

Teste 2 (Refactor!): Melhorar a implementação

// StackTests .cs using System;using NUnit.Framework;[TestFixture]public class StackTests{

private Stack stack;[SetUp]public void Init(){

stack = new Stack();}[Test]public void Empty(){

Assert.IsTrue(stack.IsEmpty);}[Test]public void PushOne(){

stack.Push(“primeiro elemento”);Assert.IsFalse(stack.IsEmpty, “Após um Push, IsEmpty deve ser false.”);

}}Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 28: Test driven development

Teste 3O terceiro teste escolhido foi verificar se ao adicionar um elemento e

retirá-lo a pilha está vazia:// StackTests .cs [Test]public void PushAndPop(){

stack.Push(“primeiro elemento”);stack.Pop();

Assert.IsTrue(stack.IsEmpty, “Após uma operação Push - Pop, IsEmpty deve ser true.”);

}Executar a solução;Erros de compilação (Stack não possui o método Pop());

Page 29: Test driven development

Teste 3 (Red): Implementar o menor código que faça o teste compilar

// Stack.csusing System;public class Stack{

public Stack(){

this. _isEmpty = true; }private Boolean _isEmpty;public Boolean IsEmpty{

get { return this. _isEmpty ; }}public void Push(Object element_){

this. _isEmpty = false; }public void Pop(){}

}Executar a solução;Solução compilada com sucesso;Teste PushAndPop falha (Red);

Page 30: Test driven development

Teste 3 (Green): Fazer o teste passar com a mais simples implementação

// Stack.csusing System;public class Stack{

public Stack(){

this._isEmpty = true; }private Boolean _isEmpty;public Boolean IsEmpty{

get { return this._isEmpty; }}public void Push(Object element_){

this._isEmpty = false; }public void Pop(){

this._isEmpty = true; }

}Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 31: Test driven development

Teste 3 (Refactor!): Melhorar a implementação

Neste ponto não há nenhuma replicação de código que possa ser retirada do código;

Então seguimos em frente;

Page 32: Test driven development

Teste 4O quarto teste escolhido foi adicionar um elemento (lembrando o seu

valor), retirá-lo e verificar se o elemento é o mesmo:// StackTests .cs [Test]public void PushAndPopContentCheck(){

Int32 expected = 1234;stack.Push(expected); Int32 actual = (Int32)stack.Pop();Assert.AreEqual(expected , actual);

}Executar a solução;Erros de compilação (o método Pop() retorna void);

Page 33: Test driven development

Teste 4 (Red): Implementar o menor código que faça o teste compilar

// Stack.csusing System;public class Stack{

public Stack(){

this._isEmpty = true; }private Boolean _isEmpty;public Boolean IsEmpty{

get { return this._isEmpty; }}public void Push(Object element_){

this._isEmpty = false; }public Object Pop(){

this. _isEmpty = true; return null;

}}Executar a solução;Solução compilada com sucesso;Teste PushAndPopContentCheck falha (Red);

Page 34: Test driven development

Teste 4 (Green): Fazer o teste passar com a mais simples implementação

// Stack.csusing System;public class Stack{

private Object _element;public Stack(){

this._isEmpty = true; }private Boolean _isEmpty;public Boolean IsEmpty{

get { return this._isEmpty; }}public void Push(Object element_){

this._element = element_; this._isEmpty = false;

}public Object Pop(){

this._isEmpty = true; Object top = this._element; this._element = null; return top;

}}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 35: Test driven development

Teste 4 (Refactor!): Melhorar a implementação

// Stack.csusing System;public class Stack{

private Object _element;public Stack(){}public Boolean IsEmpty{

get { return this._element == null; }}public void Push(Object element_){

this._element = element_; }public Object Pop(){

Object top = this._element ; this._element = null; return top;

}}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 36: Test driven development

Teste 5 (Red)O quinto teste escolhido foi adicionar 3 elementos (lembrando os seus valores), retirá-los e verificar se

os elementos são os mesmos:// StackTests .cs [Test]public void PushAndPopMultipleContentCheck(){

String pushed1 = “1”;stack.Push(pushed1);String pushed2 = “2”;stack.Push(pushed2);String pushed3 = “3”;stack.Push(pushed3); String popped = stack.Pop() as String;Assert.AreEqual(pushed3, popped);popped = stack.Pop() as String;Assert.AreEqual(pushed2, popped);popped = stack.Pop() as String;Assert.AreEqual(pushed1, popped);

}

Executar a solução;Solução compilada com sucesso;Teste PushAndPopMultipleContentCheck falha (Red);

Page 37: Test driven development

Teste 5 (Green): Fazer o teste passar com a mais simples implementação

// Stack.csusing System;using System.Collections;public class Stack{

private ArrayList _elements = new ArrayList();public Boolean IsEmpty{

get { return this._elements.Count == 0; }}public void Push(Object element_){

this._elements.Insert(0, element_); }public Object Pop(){

Object top = this._elements[0]; this._elements.RemoveAt(0); return top;

}}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 38: Test driven development

Teste 5 (Refactor!): Melhorar a implementação

Neste ponto não há nenhuma replicação de código que possa ser retirada do código;

Então seguimos em frente;

Page 39: Test driven development

Teste 6 (Red)

O sexto teste escolhido foi tentar retirar um elemento de uma pilha sem elementos:

// StackTests .cs [ExpectedException(typeof(InvalidOperationException))][Test]public void PopEmptyStack(){

stack.Pop();}

Executar a solução;Solução compilada com sucesso;Teste PopEmptyStack falha (Red);

Page 40: Test driven development

Teste 6 (Green): Fazer o teste passar com a mais simples implementação

// Stack.csusing System;using System.Collections;public class Stack{

private ArrayList _elements = new ArrayList ();public Boolean IsEmpty{

get { return this._elements.Count == 0; }}public void Push(Object element_){

this._elements.Insert(0, element_); }public Object Pop(){

if(this.IsEmpty)throw new InvalidOperationException(“A pilha está vazia.”);

Object top = this._elements[0]; this._elements.RemoveAt(0); return top;

}}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 41: Test driven development

Teste 6 (Refactor!): Melhorar a implementação

Ao realizar este teste vieram à tona mais alguns testes que deveriam ser incluídos em nossa TestList:10. Inserir nulo em uma pilha e verificar que ela não

está vazia.11. Inserir nulo em uma Pilha, retirá-lo e verificar

que o valor retornado é nulo.12. Inserir nulo em uma Pilha, chamar Top e verificar

que o valor retornado é nulo.

Page 42: Test driven development

Teste 7

O sétimo teste escolhido foi incluir um único objeto, chamar Top e verificar se a lista não está vazia:

// StackTests .cs [Test]public void PushTop(){

stack.Push(“42”); stack.Top(); Assert.IsFalse(stack.IsEmpty);

}

Executar a solução;Erros de compilação (o método Top() não existe);

Page 43: Test driven development

Teste 7 (Green): Implementar o menor código que faça o teste compilar

// Stack.csusing System;using System.Collections;public class Stack{

private ArrayList _elements = new ArrayList();public Boolean IsEmpty{

get { return this._elements.Count == 0; }}public void Push(Object element_){

this._elements.Insert(0, element_); }public Object Pop(){

if(this. IsEmpty)throw new InvalidOperationException(“A pilha está vazia.”);

Object top = this._elements[0]; this._elements.RemoveAt(0); return top;

}public Object Top(){

return null; }

}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 44: Test driven development

Teste 7 (Refactor!): Melhorar a implementação

Neste ponto não há nenhuma replicação de código que possa ser retirada do código;

Então seguimos em frente;

Page 45: Test driven development

Teste 8 (Red)O oitavo teste escolhido foi inserir um elemento na Pilha (guardando o

seu valor), chamar Top e verificar que os elementos são iguais:// StackTests .cs [Test]public void PushTopContentCheckElement(){

String pushed = “42”; stack.Push(pushed); String topped = stack.Top() as String; Assert.AreEqual(pushed, topped);

}

Executar a solução;Solução compilada com sucesso;Teste PushTopContentCheckElement falha (Red);

Page 46: Test driven development

Teste 8 (Green): Fazer o teste passar com a mais simples implementação

using System;using System.Collections;public class Stack{

private ArrayList _elements = new ArrayList();public Boolean IsEmpty{

get { return this._elements.Count == 0; }}public void Push(Object element_){

this._elements.Insert(0, element_); }public Object Pop(){

if(this.IsEmpty)throw new InvalidOperationException(“A pilha está vazia.”);

Object top = this._elements[0]; this._elements.RemoveAt(0); return top;

}public Object Top(){

return this._elements[0]; }

}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 47: Test driven development

Teste 8 (Refactor!): Melhorar a implementação

Neste ponto não há nenhuma replicação de código que possa ser retirada do código;

Então seguimos em frente;

Page 48: Test driven development

Teste 9 (Green)O nono teste escolhido foi inserir múltiplos elementos na Pilha (guardando o valor

do último inserido), chamar Top e verificar que os elementos são iguais:// StackTests .cs [Test]public void PushMultipleTopContentCheckElement(){

String pushed1 = “1”;stack.Push(pushed1);String pushed2 = “2”;stack.Push(pushed2);String pushed3 = “3”;stack.Push(pushed3); String topped = stack.Top() as String;Assert.AreEqual(pushed3, topped);

}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 49: Test driven development

Teste 9 (Refactor!): Melhorar a implementação

Neste ponto não há nenhuma replicação de código que possa ser retirada do código;

Então seguimos em frente;

Page 50: Test driven development

Teste 10 (Green)O décimo teste chamar Top diversas vezes e verificar que os elementos são iguais:// StackTests .cs [Test]public void MultipleTopContentCheckElement(){

String pushed = “1”;stack.Push(pushed); String topped1 = stack.Top() as String; Assert.AreEqual(pushed , topped1); String topped2 = stack.Top() as String; Assert.AreEqual(topped1, topped2); String topped3 = stack.Top() as String;Assert.AreEqual(topped2, topped3);

}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 51: Test driven development

Teste 10 (Refactor!): Melhorar a implementação

Neste ponto não há nenhuma replicação de código que possa ser retirada do código;

Então seguimos em frente;

Page 52: Test driven development

Teste 11 (Red)

O décimo primeiro teste é chamar Top em uma pilha vazia

// StackTests .cs [ExpectedException(typeof(InvalidOperationException))][Test]public void TopEmpty(){

stack.Top();}

Executar a solução;Solução compilada com sucesso;Teste TopEmpty falha (Red);

Page 53: Test driven development

Teste 11 (Green): Fazer o teste passar com a mais simples implementação

// Stack.csusing System;using System.Collections;public class Stack{

…public Object Pop(){

if(this.IsEmpty)throw new InvalidOperationException(“A pilha está vazia.”);Object top = this._elements[0]; this._elements.RemoveAt(0); return top;

}public Object Top(){

if(this.IsEmpty)throw new InvalidOperationException(“A pilha está vazia.”); return this._elements[0];

}}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 54: Test driven development

Teste 11 (Refactor!): Melhorar a implementação

…public Object Pop(){

Object top = Top();this._elements.RemoveAt(0);return top;

}public Object Top(){

if(this.IsEmpty)throw new InvalidOperationException(“A pilha está vazia.”);

return this._elements[0]; }…

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 55: Test driven development

Teste 12 (Green)

O décimo segundo teste é inserir nulo e verificar que a pilha não está vazia.

// StackTests .cs [Test]public void PushNull (){

stack.Push(null);Assert.IsFalse(stack.IsEmpty);

}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 56: Test driven development

Teste 12 (Refactor!): Melhorar a implementação

Neste ponto não há nenhuma replicação de código que possa ser retirada do código;

Então seguimos em frente;

Page 57: Test driven development

Teste 13 (Green)

O décimo terceiro teste é inserir um objeto nulo chamar Pop e verificar que o valor retornado é nulo e que a pilha está vazia.

// StackTests .cs [Test]public void PushNullCheckPop(){

stack.Push(null); Assert.IsNull(stack.Pop());Assert.IsTrue(stack.IsEmpty);

}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 58: Test driven development

Teste 13 (Refactor!): Melhorar a implementação

Neste ponto não há nenhuma replicação de código que possa ser retirada do código;

Então seguimos em frente;

Page 59: Test driven development

Teste 14 (Green)

O décimo quarto teste é inserir um objeto nulo chamar Top e verificar que o valor retornado é nulo.

// StackTests .cs [Test]public void PushNullCheckTop(){

stack.Push(null); Assert.IsNull(stack.Top());

}

Executar a solução;Solução compilada com sucesso;Após às alterações, todos os testes continuam passando com sucesso.

Page 60: Test driven development

Teste 14 (Refactor!): Melhorar a implementação

Neste ponto não há nenhuma replicação de código que possa ser retirada do código;

Então seguimos em frente;

Page 61: Test driven development

Stack.csusing System;using System.Collections;public class Stack{

private ArrayList _elements = new ArrayList();public Boolean IsEmpty{

get { return this._elements.Count == 0; }}public void Push(Object element_){

this._elements.Insert(0, element_); }public Object Pop(){

Object top = Top();this._elements.RemoveAt(0);return top;

}public Object Top(){

if(this.IsEmpty)throw new InvalidOperationException(“A pilha está vazia.”);

return this._elements[0]; }

}