Tdd patterns1

  • 336 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
336
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
11
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. AMIR BARYLKO TDD PATTERNS FOR .NET DEVELOPERS SDEC 2010 DEVELOPER FOUNDATION TRACKAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 2. WHO AM I? • Architect • Developer • Mentor • Great cook • The one who’s entertaining you for the next hour!Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 3. WHY TDD? • Test first approach • Quality driven • Easy to refactor • Regression tests as byproduct • Increase developer’s confidenceAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 4. SETUP Tools AutoMocking Movie LibraryAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 5. TOOLS • Testing framework: NUnit, MbUnit, MSpec, rSpec • Mocking framework: Rhino Mocks, Moq, TypeMock, nSubstitute • Test Automation: Scripts that can run the test from the developer computer. • CI server: Unit test should be run after each commit, integration tests, schedule tests. • Reports and Notifications: The team should realize right away that the tests are broken (broke the build jar).Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 6. MOVIE LIBRARYAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 7. AUTO MOCKING • Automatic dependency creation for System Under Test • Dictionary of dependencies to reuse by type • Faster setup of tests without specifying creation • Build your own: StructureMap • Or use MavenThought Testing • What about too many dependencies?Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 8. BEFORE AUTOMOCKING protected IStorage Storage { get; set; } Define SUT protected ICritic Critic { get; set } & Dependencies protected MovieLibrary Sut { get; set; } public void Setup() { Initialize each this.Storage = Mock<IStorage>(); this.Critic = Mock<ICritic>(); this.Sut = new MovieLibrary(this.Storage, this.Critic) }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 9. AFTER AUTOMOCKING SUT public abstract class Specification : AutoMockSpecificationWithNoContract<MovieLibrary> { } public class When_movie_library_is_created : Specification { [It] public void Should_do_something_with_critic() { Dep<IMovieCritic>().AssertWasCalled(...); } } DependencyAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 10. PATTERNS One feature at a time Dependency Injection State Check Dependency Lookup Behaviour Database Parameters Smelly TestAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 11. ONE FEATURE PER TEST • Easy to approach Given That (arrange) • Easy to understand When I Run • Easy to maintain (act) • Enforce Given, When, Then Then it should ... (assert)Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 12. XUNIT UNIT TESTING [TestFixture] public class MovieLibraryTest { private MockRepository _mockery; private Library _library; private IMovieCritic _critic; [Test] [SetUp] public void WhenXXXX() public void BeforeEachTest() { { Assert.IsEmpty(_library.Contents); this._mockery = new Mockery(); } this._critic = _mockery.Create...; this._library = new Library... [Test] } public void WhenYYYYAndZZZAndWWWW() { [TearDown] // record, playback, assert public void AfterEachTest() } { this._library.Clear(); }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 13. ARRANGE ACT ASSERT [Test] public void When_Adding_Should_Appear_In_The_Contents() { // Arrange var before = _sut.Contents.Count(); // Act _sut.Add(_movie1); // Assert Assert.Contains(_sut.Contents, _movie1); Assert.AreEqual(before + 1, _sut.Contents.Count()); }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 14. ONE FEATURE MANY SCENARIOS Feature Specification When_xxxx.cs When_yyyy.cs When_zzzz.csAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 15. FOCUS [Specification] public class When_movie_library_is_cleared : MovieLibrarySpecification { protected override void WhenIRun() { AddLotsOfMovies(); this.Sut.Clear(); } [It] public void Should_have_no_movies_in_the_library() { this.Sut.Contents.Should().Be.Empty(); } }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 16. CHECK THAT STATE! • Care about the end state var m = new Library... • Does not validate SUT transitions Run Test • Verify the state agains the m.Count.Should(...) expected valueAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 17. WHY CHECK IMPLEMENTATION? [Specification] public class When_movie_library_lists_non_violent_movies : MovieLibrarySpecification { [It] public void Should_call_the_critic() { Dep<IMovieCritic>().AssertWasCalled(c => c.IsViolent(...)); } }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 18. EXPECTED STATE [Specification] public class When_movie_library_lists_non_violent_movies : MovieLibrarySpecification { [It] public void Should_return_all_the_non_violent_movies() { this._actual.Should().Have.SameSequenceAs(this._expected); } }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 19. BEHAVIOUR IS EVERYTHING • Checking the expected var m = Mock<...> behaviour happened • Uses mock objects m.Stub(...) • The behaviour is specified for each mock object Run Test • The expected methods m.AssertWasCalled(...) should be calledAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 20. HOW ABOUT EVENTS? • Where is the state? • Should I create a concrete class? [It] public void Should_notify_an_element_was_added() { .......???? }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 21. ASSERT BEHAVIOR protected override void GivenThat() { base.GivenThat(); this._handler = MockIt(this._handler); this.Sut.Added += this._handler; } [It] public void Should_notify_an_element_was_added() { var matching = ...; this._handler.AssertWasCalled(h => h(Arg.Is(this.Sut), matching)); }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 22. PARAMETERS & FACTORIES [Row(1)] • Avoid duplication and [Row(2)] repetition void Method(int arg) [Row(typeof(...))] • Generic Parameters void Method<T>(...) • Parameters Factories [Factory(...)] void Method(string arg) • Random strings void Method([Random]...) • Random numbers void Method([Random]..., [Factory]...)Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 23. COMBINE public When_movie_is_created( [RandomStrings(Count=5, Pattern="The great [A-Za-z]{8}")] string title, [Factory("RandomDates")] DateTime releaseDate) { this._title = title; this._releaseDate = releaseDate; }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 24. DEPENDENCY INJECTION • Remove hardcoded Initialize dependency dependencies • Introduces dependency in Stub dependency with the constructor / setter mock • Easy to test and maintain Assert the mock is returned •S OLIDAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 25. HARDCODED DEPENDENCIES public MovieLibrary() { this.Critic = new MovieCritic(); this._posterService = new SimplePosterService(); } How are we going to test it?Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 26. INJECT DEPENDENCIES public MovieLibrary(IMovieCritic critic, IPosterService posterService, IMovieFactory factory) : this(critic) { this._posterService = posterService; this._factory = factory; }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 27. DEPENDENCY LOOKUP • Remove hardcoded Initialize service dependencies locator • Introduces a factory or Stub to return a mock service locator • Easy to test and maintain Assert the mock is returned •S OLIDAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 28. HARDCODED SERVICE public void Import(IDictionary<string, DateTime> movies) { movies.ForEach(pair => this.Add(new Movie(...))); } Hardcoded!!!Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 29. FACTORY public void Import(IDictionary<string, DateTime> movies) { movies.ForEach(pair => this.Add(this._factory.Create(...))); } COULD BE A SERVICE LOCATOR....Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 30. DATABASE TESTING • Base class to setup the Create Database database • The test always works with a Populate clean database • Can be configured to Store populate data if needed • To Retrieve and Assert test only DB operationsAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 31. USE TEMPORARY FILES protected BaseStorageSpecification() { DbFile = Path.GetTempFileName(); } protected override ISessionFactory CreateSut() { var factory = SessionFactoryGateway.CreateSessionFactory(SQLiteConfiguration .Standard .UsingFile(DbFile) .ShowSql(), BuildSchema); return factory; }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 32. CREATE & POPULATE private void BuildSchema(Configuration config) { // delete the existing db on each run if (File.Exists(DbFile)) { File.Delete(DbFile); } // export schema new SchemaExport(config).Create(true, true); }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 33. TEST DB OPERATIONS [ConstructorSpecification] public class When_movie_is_created : PersistentMovieSpecification { /// <summary> /// Validates the mapping /// </summary> [It] public void Should_have_the_right_mappings() { this.Sut.AutoSession(s => new PersistenceSpecification<Movie>(s) .CheckProperty(p => p.Title, "Space Balls") .VerifyTheMappings()); } }Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 34. OMG: WHAT’S THAT SMELL? • Setup is too big • Write only tests • Hard to understand • Tests List<T> dependencies • Checking state between calls • Needs SQL server running with MsQueue and Biztalk • Inspect internals of the class • Code coverage rules! • Can’t write a test for that • No automation is possibleAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 35. QUESTIONS?Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 36. THANK YOU! • Contact me: amir@barylko.com, @abarylko • Download: http://www.orhtocoders.com/presentations • Books: The rSpec book, xUnit Patterns.Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  • 37. RESOURCES • NUnit: http://www.nunit.org • Gallio & MbUnit: http://www.gallio.org • MavenThought Testing: http://maventcommons.codeplex.com • Rhino Mocks: http://www.ayende.com • StructureMap: http://structuremap.sourcefore.com • TeamCity: http://www.jetbrains.comAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010