Test Driven Development

Post on 09-May-2015

1.682 views 0 download

Transcript of Test Driven Development

Test Driven Development [TDD]

Christiano Milfont#XPCE 2009, FortalezaCopyleft 2009 Milfont.org

Desenvolvimento guiado a testes

Test Driven Development

“Desenvolvimento guiado por testes é um caminho de gerenciamento

do medo durante a programação.”Kent Beck - Test Driven

Development by Example

Test Driven DevelopmentStandup Meeting @ 9h

Pair Up

Test First [Prática]

Code Refactor

Integrar ou Disponibilizar

Ir para casa @ 17h

Test Driven Development

O ritmo em 3 A’s• Arrange [Criar um objeto]• Act [Invocar um método]• Assert [Verificar o resultado]

Refactoring Workbook, Bill Wake

Test Driven Development

RED-GREEN-REFACTOR1.Escreva um teste que não funciona.2.Escreva o código e faço-o funcionar.3.Refatore e elimine o código repetitivo.

Test Driven Development

Red Bar Patterns• One Step Test• Starter Test• Explanation Test• Learning Test• Another Test• Regression Test• Break• Do Over

Test Driven Development

Red Bar Patterns• One Step Test• Starter Test• Explanation Test• Learning Test• Another Test• Regression Test• Break• Do Over

Issue issue = member.createIssue(name).withType(type).withLevel(level).withSummary(summary).toProject(project);

Test Driven Development

Red Bar Patterns• One Step Test• Starter Test• Explanation Test• Learning Test• Another Test• Regression Test• Break• Do Over

@Testpublic void createIssueFromMember()

throws IllegalArgumentIssueException {member = new Member();issue = member

.createIssue("Issue created");Assert.assertNotNull(

ISSUE_IN_NULL, issue);Assert.assertEquals(

"State is not unconfirmed",

Status.UNCONFIRMED, issue.getStatus());

}

Test Driven Development

Red Bar Patterns• One Step Test• Starter Test• Explanation Test• Learning Test• Another Test• Regression Test• Break• Do Over

issue = new Member()

.createIssue("Issue created");Assert.assertNotNull(

ISSUE_IN_NULL, issue);Assert.assertEquals(

"State is not unconfirmed",

Status.UNCONFIRMED, issue.getStatus());

Test Driven Development

Red Bar Patterns• One Step Test• Starter Test• Explanation Test• Learning Test• Another Test• Regression Test• Break• Do Over

type = new Type(){{this.setId(Long.valueOf(10));this.setName(BUG);

}};member = new Member().withType(type);issue = member.getIssueInProgress();Assert.assertNotNull(ISSUE_IN_NULL, issue);Assert.assertNotNull("Type is null",

issue.getType());Assert.assertTrue("Type is not BUG",

issue.getType().getId() == type.getId());Assert.assertTrue("Type is not BUG",

issue.getType().getName() == type.getName());Assert.assertEquals("Type is not BUG",

issue.getType().getName(), BUG);

Test Driven Development

Red Bar Patterns• One Step Test• Starter Test• Explanation Test• Learning Test• Another Test• Regression Test• Break• Do Over

@Testpublic void

createIssueFromMemberWithNameEmpty() {...}

@Test

public void setTypeInIssueFromMember() throws IllegalArgumentIssueException {

…}

Test Driven Development

Red Bar Patterns• One Step Test• Starter Test• Explanation Test• Learning Test• Another Test• Regression Test• Break• Do Over

Issue issue = member.createIssue(name).withType(type).withLevel(level).withSummary(summary).toProject(project);

Assert.assertNotNull("Issue não gerada com sucesso!",

issue);Assert.assertTrue("Issue não gerada e id não atribuído",

issue.getId() > 0);

Test Driven Development

Red Bar Patterns• One Step Test• Starter Test• Explanation Test• Learning Test• Another Test• Regression Test• Break• Do Over

@Testpublic void createIssueFromMemberWithNameNull() {

try {issue = new Member()

.createIssue(null);Assert.fail("Didn't find expected exception of type " +

IllegalArgumentIssueException.class.getName());} catch (IllegalArgumentIssueException e) {

Assert.assertEquals("Exception correctly catch",

"Name is null or empty“, e.getMessage());}

}

Test Driven Development

Red Bar Patterns• One Step Test• Starter Test• Explanation Test• Learning Test• Another Test• Regression Test• Break• Do Over

Test Driven Development

Green Bar Patterns• Fake It (‘till you make it)• Triangulate• Obvious Implementation• One to Many

Test Driven Development

Green Bar Patterns• Fake It (Till you make it)• Triangulate• Obvious Implementation• One to Many context.checking(new Expectations() {{

oneOf(repository).persist(with(any(Issue.class)));will(new CustomAction("Add id value to issue") {

public Object invoke(Invocation invocation)throws Throwable {( (Issue)

invocation.getParameter(0)).setId(Long.valueOf(1));

return null;}

});}});

Test Driven Development

Green Bar Patterns• Fake It (Till you make it)• Triangulate• Obvious Implementation• One to Many

@Testpublic void setNullSummaryInIssueFromMember() {...}@Test

public void setSummaryInIssueFromMember() {...}@Test

public void setEmptySummaryInIssueFromMember() { ..}

Test Driven Development

Green Bar Patterns• Fake It (Till you make it)• Triangulate• Obvious Implementation• One to Many ...

List<Issue> issues = new ArrayList<Issue>() {{

this.add(new Issue(Long.valueOf(134)));}

}...Assert.assertTrue(“blable”, issues.size()==1);

Test Driven Development

Green Bar Patterns• Fake It (Till you make it)• Triangulate• Obvious Implementation• One to Many ...

List<Issue> issues = new ArrayList<Issue>() {{

this.add(new Issue(Long.valueOf(134)));}

}...Assert.assertTrue(“blable”, issues.size()==1);

Test Driven Development

Testing Patterns• Child Test• Mock Object• Self Shunt• Log String• Crash Test Dummy• Broken Test• Clean Check-In

Test Driven Development

Testing Patterns• Child Test• Mock Object• Self Shunt• Log String• Crash Test Dummy• Broken Test• Clean Check-In

@RunWith(JMock.class)public class LifeCycleOfIssueInProjectTest { ... }

@RunWith(JMock.class)public class ReportIssuesTest { ... }

Test Driven Development

Testing Patterns• Child Test• Mock Object• Self Shunt• Log String• Crash Test Dummy• Broken Test• Clean Check-In

context.checking(new Expectations() {{oneOf(repository).persist(with(any(Issue.class)));will(new CustomAction("Add id value to issue") {

public Object invoke(Invocation invocation)throws Throwable {( (Issue)

invocation.getParameter(0)).setId(Long.valueOf(1));

return null;}

});}});

Test Driven Development

Testing Patterns• Child Test• Mock Object• Self Shunt• Log String• Crash Test Dummy• Broken Test• Clean Check-In

context.checking(new Expectations() {{oneOf(repository).persist(with(any(Issue.class)));will(new CustomAction("Add id value to issue") {

public Object invoke(Invocation invocation)throws Throwable {( (Issue)

invocation.getParameter(0)).setId(Long.valueOf(1));

repository.issues.add(

( (Issue) invocation.getParameter(0)));

return null;}

});}});...Assert.assertTrue(repository.size() == 12);

Test Driven Development

Testing Patterns• Child Test• Mock Object• Self Shunt• Log String• Crash Test Dummy• Broken Test• Clean Check-In

Test Driven Development

Testing Patterns• Child Test• Mock Object• Self Shunt• Log String• Crash Test Dummy• Broken Test• Clean Check-In

@Testpublic void createIssueFromMemberWithNameNull() {

try {issue = new Member()

.createIssue(null);Assert.fail("Didn't find expected exception of type " +

IllegalArgumentIssueException.class.getName());} catch (IllegalArgumentIssueException e) {

Assert.assertEquals("Exception correctly catch",

"Name is null or empty“, e.getMessage());}

}

Test Driven Development

Testing Patterns• Child Test• Mock Object• Self Shunt• Log String• Crash Test Dummy• Broken Test• Clean Check-In

Test Driven Development

Testing Patterns• Child Test• Mock Object• Self Shunt• Log String• Crash Test Dummy• Broken Test• Clean Check-In

Test Driven Development

Test Double• Dummy• Fake• Stubs• Spies• Mocks

Test Driven Development

Test Double• Dummy• Fake• Stubs• Spies• Mocks

...List<Issue> issues = new ArrayList<Issue>() {

{this.add(new

Issue(Long.valueOf(134)));}

}...Assert.assertTrue(“blable”, issues.size()==1);

Test Driven Development

Test Double• Dummy• Fake• Stubs• Spies• Mocks

...IssueRepository repository = new FakeRepository();List<Issue> issuesUnconfirmeds = repository.

getIssuesUnconfirmeds();Assert.assertTrue(“blable”, issuesUnconfirmeds !=

null);...public class FakeRepository implements

IssueRepository {public List<Issue> getIssuesUnconfirmeds() {

return new ArrayList<Issue>();}

}

Test Driven Development

Test Double• Dummy• Fake• Stubs• Spies• Mocks

context.checking(new Expectations() {{ignoring(repository).count();will(returnValue(42));

}});...Assert.assertEquals(12 , repository.count());

Test Driven Development

Test Double• Dummy• Fake• Stubs• Spies• Mocks

context.checking(new Expectations() {{oneOf(repository).persist(with(any(Issue.class)));will(new CustomAction("Add id value to issue") {

public Object invoke(Invocation invocation)throws Throwable {( (Issue)

invocation.getParameter(0)).setId(Long.valueOf(1));

repository.issues.add(

( (Issue) invocation.getParameter(0)));

return null;}

});}});...Assert.assertTrue(repository.size() == 12);

Test Driven Development

Test Double• Dummy• Fake• Stubs• Spies• Mocks

context.checking(new Expectations() {{oneOf(repository).persist(with(any(Issue.class)));will(new CustomAction("Add id value to issue") {

public Object invoke(Invocation invocation)throws Throwable {( (Issue)

invocation.getParameter(0)).setId(Long.valueOf(1));

return null;}

});}});

Test Driven Development

Fixture Setup• Setup• Tear Down

@Beforepublic void setUp() throws Exception {

Connection conn;try {

... IDatabaseConnection connection =

new DatabaseConnection(conn); DatabaseOperation.INSERT.execute(connection,

new FlatXmlDataSet(new FileInputStream( “issuetrackr.xml")));

conn.close();} catch (Exception exc) { ... }

}