VT.NET 20160411: An Intro to Test Driven Development (TDD)

24
An Intro to Test Driven Development (TDD) Rob Hale April 11, 2016

Transcript of VT.NET 20160411: An Intro to Test Driven Development (TDD)

Page 1: VT.NET 20160411: An Intro to Test Driven Development (TDD)

An Intro to Test Driven Development (TDD)Rob HaleApril 11, 2016

Page 2: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Goals

• Automated testing isn’t (always) TDD• Where it fits• Moq

Page 3: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Automated Unit Testing

Page 4: VT.NET 20160411: An Intro to Test Driven Development (TDD)

What’s a “unit”

• The test operates in isolation• tests should never depend on each other

Page 5: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Benefits of unit tests over end-to-end tests

• Error localization

• Execution time

• Tighter feedback loop

• Coverage

Page 6: VT.NET 20160411: An Intro to Test Driven Development (TDD)

40x

Page 7: VT.NET 20160411: An Intro to Test Driven Development (TDD)

What’s not a unit test?

I like Michael Feathers’ explanation from Working Effectively with Legacy Code. It’s not a unit test if:

• It talks to a database• It communicates across a network• It touches the file system• You have to do special things to your environment to run it (like

editing a config file)

Page 8: VT.NET 20160411: An Intro to Test Driven Development (TDD)

DIFFICULT SCENARIOS

TO UNIT TEST

Closed Object Models (Sharepoint, Silverlight)

Client – server architecture - Communicating Across a Network

An out-of-process call - Includes talking to databases and Web Services

UI/GUI interactionTouching the File SystemLegacy CodeRequires the Environment to

be configured

Page 9: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Test Driven Development

The basic cycle

Write a failing test

Make the test pass

Refactor

Page 10: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Put another way...

New requirement

Run Tests

Write new test

Write new test

Write new code

Run Tests

Refactor

Make it Better

Make it Fail

Make it Work

Page 11: VT.NET 20160411: An Intro to Test Driven Development (TDD)

“When you first start at doing TDD you know what the design should be. You know what code you want to write. So you write a test that will let you write that bit of code. “When you do this you aren't really doing TDD – since you are writing the code first (even if the code is only in your head ) “It takes some time to realize that you need to focus on the test. Write the test for the behavior you want - then write the minimal code needed to make it pass - then let the design emerge through refactoring. Repeat until done.”

--Brian Rasmussenhttp://www.slideshare.net/baronslideshare/testdriven-development-tdd

Page 12: VT.NET 20160411: An Intro to Test Driven Development (TDD)

An Exercise in Test Driven

Development

The idea here is going to be to go through the exercise of designing a portion of a new solution in real time.

After the exercise I want to circle back and point out the benefits we gained from the test first approach which may have been missed had we coded and then wrote tests.

Page 13: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Principles•Think About What You Are Trying To Do •Follow The TDD Cycle•Never Write New Functionality Without A Failing Test - Each test should be for a single concept

•Continually Make Small, Incremental Changes

•Keep The System Running At All Times - No one can make a change that breaks the system - Failures Must Be Address Immediately

•Is an activity of the developer

• Test code should be treated the same as “production” - maintained - refactor - source control

• Experimentation - Names don’t matter initially

• When you want to change existing code, first write covering, white box, unit tests and then use TDD to add new functionality

• Fix it in the simplest way possible using as many assumptions as you like

Page 14: VT.NET 20160411: An Intro to Test Driven Development (TDD)

TDD gives you

Design

Confidence

Documentation

Feedback

Page 15: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Realizing quality improvement through test driven development

Metric Description IBM:Drivers

MSFT:Windows

MSFT:MSN

MSFT:VS

Defect density of non-TDD team

W X Y Z

Defect density of team using TDD

0.61W 0.38X 0.24Y 0.09Z

% increase in coding time becauseof TDD [Management estimates]

15-20% 25-35% 15% 25-30%

http://research.microsoft.com/en-us/groups/ese/nagappan_tdd.pdf

Page 16: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Visualized another way...

http://research.microsoft.com/en-us/groups/ese/nagappan_tdd.pdf

Page 17: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Moq

Page 18: VT.NET 20160411: An Intro to Test Driven Development (TDD)

What’s a mock object?

A Test Double object that is pre-programmed with expectations which form a specification of the calls they are expected to receive

The nice thing about using mocks while doing TDD is we can mock something that doesn’t actually exist. Just define an interface and mock that. Later on we can create concrete implementations of the interface (through TDD, of course)

Page 19: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Chicago vs London

Ledger

● Calculate(string expression)

Calculator

● Add● Subtract● Multiply● ...

Based on http://programmers.stackexchange.com/a/123672

ledger.Calculate("5 * 7")

Page 20: VT.NET 20160411: An Intro to Test Driven Development (TDD)

[TestFixture]public class LedgerTests{ public static Ledger Ledger { set; get; }

public static int Value { get; set; }

public static Mock<ICalculator> calculator;

[SetUp] public void LedgerSetup() { calculator = new Mock<ICalculator>(); Ledger = new Ledger(calculator.Object); }

Page 21: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Chicago vs London

[Test]public void ChicagoStyle(){ Value = Ledger.Calculate("5 * 7"); Assert.AreEqual(35, Value);}

The Chicago/State school would have you assert whether the result is 35. The jUnit/nUnit frameworks are generally geared towards doing this.

Page 22: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Chicago vs London

[Test]public void ChicagoStyle(){ Value = Ledger.Calculate("5 * 7"); Assert.AreEqual(35, Value);}

The Chicago/State school would have you assert whether the result is 35. The jUnit/nUnit frameworks are generally geared towards doing this.

[Test]public void LondonStyle(){ calculator.Verify(calc => calc.Multiply(5, 7), Times.Exactly(1));}

The London/Interaction school would have you assert whether Calculator.Multiply(5,7) got called. The various mocking frameworks are useful for this, and it can be very useful if, for example, you don't have ownership of the "Calculator" object (suppose it is an external component or service that you cannot test directly, but you do know you have to call in a particular way).

Page 23: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Resources

• http://www.slideshare.net/dehringer/test-driven-development-5785229

• http://www.slideshare.net/baronslideshare/testdriven-development-tdd

• http://research.microsoft.com/en-us/groups/ese/nagappan_tdd.pdf

• http://www.martinfowler.com/articles/mocksArentStubs.html• Video: Llewellyn Falco & Woody Zuill - Practical Refactoring

• https://youtu.be/aWiwDdx_rdo• Video: Raymond Lim & Roy Osherove - TDD Pairing Session 1

• https://youtu.be/xX9hfPkA800• Video: Doc Norton - The Technical Debt Trap

• https://vimeo.com/97507576

Page 24: VT.NET 20160411: An Intro to Test Driven Development (TDD)

Other resources mentioned by attendees

The following resources were mentioned after the presentation. They require purchase or subscription.• Play by Play: TDD with Brad Wilson (Pluralsight)

• https://www.pluralsight.com/courses/play-by-play-wilson-tdd• Automated Testing for Fraidy Cats Like Me with Julie Lerman

(Pluralsight)• https://www.pluralsight.com/courses/automated-testing-fraidy-cats

• Test-Driven Development training by Mike Hill & Joshua Kerievsky (Industrial Logic)

• https://elearning.industriallogic.com/gh/submit?Action=AlbumContentsAction&album=before&devLanguage=Java