Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Tdd patterns1

740 views

Published on

  • Hello there! Get Your Professional Job-Winning Resume Here! http://bit.ly/topresum
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

Tdd patterns1

  1. 1. AMIR BARYLKO TDD PATTERNS FOR .NET DEVELOPERS SDEC 2010 DEVELOPER FOUNDATION TRACKAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  2. 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. 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. 4. SETUP Tools AutoMocking Movie LibraryAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  5. 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. 6. MOVIE LIBRARYAmir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  7. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 35. QUESTIONS?Amir Barylko - TDD Patterns MavenThought Inc.Wednesday, October 13, 2010
  36. 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. 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

×