Smidig 2011 TDD Workshop

  • View
    1.102

  • Download
    1

Embed Size (px)

DESCRIPTION

Presentation from TDD workshop at Smidig 2011 hosted by Jonas Folles.The slides are in Norwegian.

Transcript

  • 1. TDD: FRA FIZZBUZZ TILPRAKTISK BRUK I PROSJEKT, OGHVORDAN JEG SKRIVER TESTER90 min workshop Smidig 2011Jonas Folles 14//11

2. LITT OM MEGJonas FollesScientist BEKK TrondheimAktiv i .NET fagmiljetBrukt TDD siden 2006 3. LITT OM DERE? 4. AGENDA Essensen i TDD Feedback Loops Lesbare tester Mocking Builder Pattern Satna Wish List Processor 5. RD, GRNN, REFAKTORERFEEDBACK LOOP I TDD 6. TDD GIR OSS TILBAMELEDINGER PDesign Implementasjon(er koden(virker koden) vellstrukturert) 7. TEST OPPFRSEL IKKE METODERI begynnelsen skrev vi tester som speiler klassen som testespublic class OrderProcessing{public void ProcessOrder(Order order){}public void ShipOrder(Order order){}}[TestFixture]public class OrderProcessingTest{[Test]public void ProcessOrderTest(){}[Test]public void ShipOrderTest(){}[Test]public void ShipOrderTest2(){}} 8. TEST OPPFRSEL IKKE METODERI found the shift from thinking in tests tothinking in behaviour so profound that Istarted to refer to TDD as BDD - Dan North, Introducing BDD blog post 9. TESTDOX NAVNEKONVENSJONHver test er en setning med klassen som testes som implisittsubjekt A List holds items in the order they were added A List can hold multiple references to the same item A List throws an exception when removing an item it doesnt hold 10. TESTKLASSE SKREVET ETTER TESTDOX KONVENSJON[TestFixture]public class ListTest{[Test]public void Holds_items_in_the_order_they_were_added(){}[Test]public void Can_hold_multiple_references_to_the_same_item(){}[Test]public void Throws_exception_when_removing_an_item_it_doesnt_hold(){}} 11. KLASSEVARIABLER I BUNNEN AV KLASSEN[TestFixture]public class OrderProcessingTest{[Test]public void Should_generate_shipping_statement_for_order(){}[SetUp]public void Given_we_have_an_order_processor(){emailService = new EmailMock();processor = new OrderProcessing(emailService);}private OrderProcessing processor;private EmailMock emailService;} 12. ARRANGE, ACT, ASSERT[Test]public void Should_read_inbox_location(){string[] parameters = {@"c:inbox", ""};var initParameter = new InitParameters(parameters);initParameter.Inbox.Should().Be(@"c:inbox");} 13. EKSEMPLER P ASSERTS[Test]public void Standard_NUnit_Asserts(){string input = "Merry Christmas";Assert.That(input, Is.EqualTo("Merry Christmas"));}[Test]public void NUnit_Should_Asserts(){string input = "Merry Christmas";input.Should(Be.EqualTo("Merry Christmas"));}[Test]public void Fluent_Asserts(){string input = "Merry Christmas";input.Should().Be("Merry Christmas");} 14. NUNIT SHOULD ASSERTSpublic class Be : Is { public Be() { } }public class Have : Has { public Have() { } }public class Contain : Contains { public Contain() { } }public static partial class ShouldExtensions{public static void Should(this object o, IResolveConstraint constraint){Assert.That(o, constraint);}public static void ShouldNot(this object o, Constraint constraint){Assert.That(o, new NotOperator().ApplyPrefix(constraint));}} 15. FLUENT ASSERTSinput.Should().Be("Merry Christmas");public static class MyFluentAsserts{public static StringAsserts Should(this string text){return new StringAsserts(text);}}public class StringAsserts{private readonly string _text;public StringAsserts(string text){_text = text;}public void Be(string otherString){Assert.That(_text, Is.EqualTo(otherString));}} 16. STANDARD NUNIT ASSERTS[Test]public void Standard_NUnit_Asserts(){string input = "Merry Christmas";Assert.That(input, Is.EqualTo("Merry Christmas"));}[Test]public void NUnit_Should_Asserts(){string input = "Merry Christmas";input.Should(Be.EqualTo("Merry Christmas"));}[Test]public void Fluent_Asserts(){string input = "Merry Christmas";input.Should().Be("Merry Christmas");} 17. ET EKSTRA STEG I TDD-PROSESSEN 18. IKKE LESBAR FEILMELDING[Test]public void Non_readable_diagnostics(){string input = "Merry Christmas";Assert.True(input == "Merry christmas");}------ Test started: Assembly: SantaWorkshop.Tests.dll ------Test SantaWorkshop.Tests.TempTest.Non_readable_diagnosticsfailed:Expected: TrueBut was: FalseTempTest.cs(35,0): atSantaWorkshop.Tests.TempTest.Non_readable_diagnostics()0 passed, 1 failed, 0 skipped, took 0,55 seconds (NUnit 2.5.5). 19. LESBAR FEILMELDING[Test]public void Readable_diagnostics(){string input = "Merry Christmas";Assert.That(input, Is.EqualTo("Merry christmas"));}------ Test started: Assembly: SantaWorkshop.Tests.dll ------Test SantaWorkshop.Tests.TempTest.Readable_diagnosticsfailed:String lengths are both 15. Strings differ at index 6.Expected: "Merry christmas"But was: "Merry Christmas"-----------------^TempTest.cs(42,0): atSantaWorkshop.Tests.TempTest.Readable_diagnostics()0 passed, 1 failed, 0 skipped, took 0,37 seconds (NUnit 2.5.5). 20. ET EKSTRA STEG I TDD-PROSESSEN 21. FOKUS P LESBARHETSom utvikler bruker vi langt mere tid p lese kode enn skrive kode Lett forst hva koden gjr gjennom testnavn Lett forst hvordan bruke koden gjennom test implementasjon Lett forst hvorfor en test feiler nr koden endrer seg Lett forst hvordan koden er implementert gjennom kontinuerligrefaktorering og fokuserte/sm klasser 22. TESTENE BLIR LEVENDE DOKUMENTASJON 23. LESBARHETTestkode beskriver hva koden gjr.Produksjonskode er absrrakt iKonkret i verdiene som brukes som verdiene som brukes, men konkret ieksempler p hva koden gjr, og til hvordan den fr jobben gjort.verifisere at den faktisk gjr det, menabstrakt i hvordan koden fungerer 24. HVOR BEGYNNER VI?TEST ETVANDRENDE SKJELETTTester fra utsiden og inn for hele tiden fokusere pfunksjonalitet som gir verdiBegynner teste et skjeletsom tar for seg den enklestefunksjonaliteten som gir meningSkrive en ende-til-endeakseptansetest som vil tvingeoss til begynne p denfaktiske implementasjonen 25. AKSEPTANSETEST SOM YTRE FEEDBACK LOOP 26. ATDD I ET STRRE PERSPEKTIV 27. UNIT, INTEGRATION &ACCEPTANCE TEST Unit TestIntegration TestAcceptance Test Tester vr kode Tester hvordan vr kode Tester systemet ende-til- integrerer med kode vi ende Uavhengig av milj ikke kontrollerer Fokus p brukerhistorier Kjrer raskt Kan rre milj (filsystem, Bruker s realistisk milj meldingsk)som mulig 28. CASE: SANTA WISHLIST PROCESSOR ITERASJON 1 Julenissen mottar store mengder nskelister til jul. nsker system for effektivisere behandlingen av disse. Systemet skal vre batch-basert, og lese innkommende nskelistersom skal gjres om til utgende pakke- og leveranselister Skal kjre som en Console Application som f.eks kan settes opp somen scheduled task Frste iterasjon gir alle barn det de har nsket seg aller mest 29. CASE: SANTA WISHLIST PROCESSOR INPUT/OUTPUT FORMATInput filformat:Jonas Folles (28)Wesselsgate 19, 7043 TrondheimNokia Lumia 800iPhone 4SiPad 2Output filformat:Nokia Lumia 800 (Jonas Folles, Wesselsgate 19, 7043 Trondheim)iPhone 4S (Ola Nordman, Kirkeveien 1, 1000 Oslo) 30. KLASSISK TDD VSLONON SCHOOL-TDD Verifisering av Verifisering av tilstand oppfrsel 31. KLASSISK TDDKent Becks Test-driven Development By ExampleEn algoritme oppdages en test av gangen.Tester tilstanden til systemet etter 32. ROMERTALL I KLASSISK TDDStegene og testene for finne romertall for et gitt tall kan se slik ut: Test 1: I => return I Test 2: II => if (number == 1) return I else return II Test 3: III => while (number > 0) concat I to result and decrement number Verifisering av tilstand 33. KLASSISK TDDVi lager en mer generell lsning en test av gangen, slik at vitil slutt ender opp med en enkel, elegant lsning somhndterer alle testene opp til n 34. LONDON STYLE-TDD / MOCKIST TDDGrowing Object Oriented Software Guided by Tests dendefinitive boka.Fokus p: Roller Ansvarsomrder Interaksjon Verifisering avoppfrsel 35. ET NETTVERK AV OBJEKTER 36. HVOR VI NSKER TESTE ETT OBJEKT FOR SEG 37. HVOR VI NSKER TESTE ETT OBJEKT FOR SEG 38. TESTING MED MOCK OBJEKTERVerifisering av oppfrsel 39. TESTING MED MOCK OBJEKTER[Test]public void Should_send_email_when_order_is_processed(){var emailMock = new Mock(); emailMock.Setup(e => e.SendMessage(It.Is(m => m.To == "jonas@follesoe.no"))) .Returns(true) .Verifiable("Did not send e-mail to customer as expected"); var orderProcessing = new OrderProcessing(emailMock.Object); var order = new Order {CustomerEmail = "jonas@follesoe.no"}; orderProcessing.ProcessOrder(order); emailMock.Verify();} 40. TESTING MED MOCK OBJEKTERTest Should_send_email_when_order_is_processed failed:Moq.MockVerificationException :The following setups were not matched:Did not send e-mail to customer as expected:ISendEmail e => e.SendMessage(It.Is(m => m.To =="jonas@follesoe.no")) 41. TESTING MED HNDSKREVET MOCK[Test]public void Should_send_email_when_order_is_processed(){var emailMock = new EmailMock();var orderProcessing = new OrderProcessing(emailMock);var order = new Order {CustomerEmail = "jonas@follesoe.no"};orderProcessing.ProcessOrder(order);emailMock.SendMessageWasCalled.Should().BeTrue("Should send e-mail to customer");emailMock.MessageThatWasSent.To.Should().Be("jonas@follesoe.no");} 42. TESTING MED HNDSKREVET MOCKTest Should_send_email_when_order_is_processed failed: ExpectedTrue because Should send e-mail to customer, but found False. 43. EMAILMOCK KLASSEpublic class EmailMock : ISendEmail{public Message MessageThatWasSent;public bool SendMessageWasCalled;public Exception ExceptionToThrow;public bool ReturnValue;public bool SendMessage(Message message){SendMessageWasCalled = true;MessageThatWasSent = message;if(ExceptionToThrow != null)throw ExceptionToThrow;return ReturnValue;}} 44. MOCK RAMMEVERK ELLERHNDSKREVNE MOCKS?Mock Rammeverk Hndskrevne Mocks Mulighet for avansert matching p Lett forst for nybegynnereparametere Lett debugge gjennom koden Slipper skrive enge mock klasser Presise feilmeldinger p hvilkeexpectations som ikke ble mtt 45. TESTING MED MOCK OBJEKTERTester hvordan vrt objekt sammarbeider med objektene rundt segGjennom skrive tester p denne mten designer vi bde det inngende ogutgende grensesnittet