Top Banner
Test-Driven Development
57
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Test Driven Development (Delphi)

Test-Driven Development

Page 2: Test Driven Development (Delphi)

First, Some History

Page 3: Test Driven Development (Delphi)

Plan-Do-Check-Act

0Originally called Plan-Do-Study-Act0Created by Walter Shewhart at Bell Labs during the

1930s

Page 4: Test Driven Development (Delphi)

Iterative & Incremental Development

0The X-15 program in the 1950s used IID

Page 5: Test Driven Development (Delphi)

Test-First in the Swinging 60s

0X-15 team members seeded Project Mercury0 Time-boxed half-day iterations0 Tests were written first0 Reviews after each iteration0 Top-down development with stubs

Page 6: Test Driven Development (Delphi)

We were doing incremental development as early as 1957, in Los Angeles, under the direction of Bernie Dimsdale [at IBM’s Service Bureau Corporation]. He was a

colleague of John von Neumann, so perhaps he learned it there, or assumed it as totally natural. I do remember Herb Jacobs (primarily, though we all participated)

developing a large simulation for Motorola, where the technique used was, as far as I can tell, indistinguishable from XP.

When much of the same team was reassembled in Washington, DC in 1958 to develop Project Mercury, we had our own machine and the new Share Operating System,

whose symbolic modification and assembly allowed us to build the system incrementally, which we did, with great success.

Project Mercury was the seed bed out of which grew the IBM Federal Systems Division. Thus, that division started with a history and tradition of incremental development.

All of us, as far as I can remember, thought waterfalling of a huge project was rather stupid, or at least ignorant of the realities… I think what the waterfall description did

for us was make us realize that we were doing something else, something unnamed except for “software development.”

Gerald M. Weinberg

Page 7: Test Driven Development (Delphi)

Waterfall in the 1970s & 80s

0Blame the DoD and the CMMI

Page 8: Test Driven Development (Delphi)

Other stuff was happening

0Object-orientation0 Simula from the late 60s0 Smalltalk in the 70s at Xerox PARC

0Software distribution

Page 9: Test Driven Development (Delphi)

Into the 1990s

0UML evolves0www arrives

Page 10: Test Driven Development (Delphi)

What RUP was meant to be

Page 11: Test Driven Development (Delphi)

What RUP actually was

Page 12: Test Driven Development (Delphi)

RAD elaboration in the 90s

Page 13: Test Driven Development (Delphi)

XP arrives

Page 14: Test Driven Development (Delphi)

Test-Driven is in XP

Page 15: Test Driven Development (Delphi)

Tests are Feedback in XP

Page 16: Test Driven Development (Delphi)

Agile arrives

Page 17: Test Driven Development (Delphi)

Agile is just XP, rebadged

Page 18: Test Driven Development (Delphi)

and a Manifesto

Page 19: Test Driven Development (Delphi)

The Philosophy of TDD

Page 20: Test Driven Development (Delphi)

The Testing Game

0Red:0 “Write a failing test”

0Green:0 “Pass the failing test”

0Refactor0 “Clean the implementation”

Page 21: Test Driven Development (Delphi)

Write a failing test

0To know what test to write, you must:0 Analyze your problem0 Design your solution0 Code intentionally

0To dislike “Big Upfront Design” is not to dislike design

Page 22: Test Driven Development (Delphi)

Agile Problem Analysis

0 System Metaphor0 Arises from the Architectural Spike0 A simple design with the defining quality of explaining the

system design without reference to documents0 User Experience

0 Arises from the set of all user stories0 Provides a canvas onto which individual stories can be

painted0 User Story

0 Describes a specific user expectation0 Provides the functional constraints of implementation

Page 23: Test Driven Development (Delphi)

User Stories

0A user story comprises one or more sentences in the everyday or business language of the end user that captures what the user wants to achieve

Page 24: Test Driven Development (Delphi)

Agile Solutions

0 “Walk the solution”: for each user story0 Understand how this fits into the user experience0 Understand where the necessary functional

implementation goes in the architecture0 Design the functional implementation

Page 25: Test Driven Development (Delphi)

Goldilocks Design

0Design only what you need0 avoid YAGNI (You Ain’t Gonna Need It)

0Reuse existing implementation0 be DRY (Don’t Repeat Yourself)

0Prefer sketched designs over definitive design0 allow TDD to be part of your design process

0Don’t experiment in code0 use spikes where necessary

Page 26: Test Driven Development (Delphi)

First Exercise

0Brainstorm a realistic candidate application0Write a small set of user stories0Elaborate a user experience0Articulate a system metaphor0Time limit: one hour

Page 27: Test Driven Development (Delphi)

Analysis & Design

0There are a variety of approaches to functional analysis and implementation design

0The most commonly used are:0 The UML0 CRC Cards0 Design Patterns0 Linguistics & Semantics0 Personas0 Storyboards

Page 28: Test Driven Development (Delphi)

UML

0The UML (Unified Modeling Language)0 It has the advantage that many developers have at least

some familiarity0 It has the disadvantage of significant complexity0 Most agile practitioners use ‘sketch’ UML, typically on a

whiteboard, in order to convey a mental model of a proposed solution

0 Be indicative, not definitive

Page 29: Test Driven Development (Delphi)

UML Use Case Diagram

0Describes the functionality provided by a system in terms of actors and their goals represented as use cases

Page 30: Test Driven Development (Delphi)

UML Activity Diagram

0Used to describe the business and operational step-by-step workflows of components in a system

Page 31: Test Driven Development (Delphi)

UML Sequence Diagram

0Shows how processes operate with one another and in what sequence

Page 32: Test Driven Development (Delphi)

UML Class Diagram

0Describes the structure of a system by showing the system's classes, their attributes, methods, and the relationships among the classes

Page 33: Test Driven Development (Delphi)

CRC Cards

0 Class Responsibility Collaboration cards are a brainstorming tool, proposed by Ward Cunningham and Kent Beck

0 They are typically used when determining which classes are needed and how they will interact

0 CRC cards are usually created from index cards on which are written:0 The class name0 Any base or derived classes (if applicable)0 The responsibilities of the class0 The names of other classes with which the class will

collaborate to fulfil its responsibilities

Page 34: Test Driven Development (Delphi)

CRC Card

Page 35: Test Driven Development (Delphi)

Design Patterns

0A general reusable solution to a commonly occurring problem within a given context

0A design pattern is not a finished design that can be transformed directly into code; it is a description or template for how to solve a problem that can be used in many different situations

0Typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved

Page 36: Test Driven Development (Delphi)

Some Creational Patterns

0 Factory method0 Define an interface for creating an object, but let derived classes decide which

class to instantiate0 Lazy initialization

0 Tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed

0 Object pool0 Avoid expensive acquisition and release of resources by recycling objects that

are no longer in use0 Resource acquisition is initialization

0 Ensure that resources are properly released by tying them to the lifespan of suitable objects

0 Singleton0 Ensure a class has only one instance, and provide a global point of access to it

Page 37: Test Driven Development (Delphi)

Some Structural Patterns

0 Adapter0 Convert the interface of a class into another interface clients

expect0 Bridge

0 Decouple an abstraction from its implementation allowing the two to vary independently

0 Facade0 Provide a unified interface to a set of interfaces in a subsystem

0 Proxy0 Provide a surrogate or placeholder for another object to

control access to it

Page 38: Test Driven Development (Delphi)

Some Behavioural Patterns

0 Chain of responsibility0 Avoid coupling the sender of a request to its receiver by giving

more than one object a chance to handle the request0 Command

0 Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations

0 Iterator0 Provide a way to access the elements of an aggregate object

sequentially without exposing its underlying representation0 Null object

0 Avoid null references by providing a default object

Page 39: Test Driven Development (Delphi)

Linguistics & Semantics

0Using the meanings and relationships of words and phrases employed in the user stories and other material to construct a language map of the problem domain

0Especially useful when dealing with ‘expert’ systems

Page 40: Test Driven Development (Delphi)

Personas

0Fictional characters created to represent the different user types within a targeted demographic, attitude and/or behaviour set that might use a site, brand or product in a similar way

Page 41: Test Driven Development (Delphi)

Storyboards

0A technique borrowed from the film industry

0Shows the user experience in sequence

Page 42: Test Driven Development (Delphi)

Second Exercise

0Take one or more of the user stories from the first exercise and apply a selection of the analysis and design techniques

0Draw up a list of the strengths and weaknesses of the techniques in relation to these particular user stories

0Time limit: one hour

Page 43: Test Driven Development (Delphi)

Testing Frameworks

0 MSTest0 Built-in to Visual Studio

0 Pex0 Experimental white-box testing from MS Research

0 NUnit0 Early open source port of JUnit for .net

0 MbUnit0 Another open source framework

0 xUnit0 Open source reset of NUnit

0 SpecFlow0 Open source behaviour-driven-development framework

Page 44: Test Driven Development (Delphi)

Arrange, Act, Assert

0The default pattern for unit tests1. Arrange all necessary preconditions and inputs2. Act on the object or method under test3. Assert that the expected results have occurred

Page 45: Test Driven Development (Delphi)

Test naming conventions

0Ad-hoc0 Anything goes

0Behavioural0 Tests are named according to the behaviour under test0 Good fit for collaboration tests (distinct from unit tests)

procedure CustomerPaysInChequeToCurrentAccount;

0Contractual0 Names follow the unit contract under test

http://alandean.blogspot.com/2011/11/unit-test-naming-convention.html

Page 46: Test Driven Development (Delphi)

DUnit Assertions

0 Fundamentals0 Assert(…)0 Check(…)0 CheckSame(…)0 CheckEquals(…) or CheckNotEquals(…)0 CheckNull(…) or CheckNotNull(…)0 Fail(…)0 FailNotSame(…)0 FailEquals(…) or FailNotEquals(…)

0 Errors0 NotSameErrorMessage(…)0 EqualsErrorMessage(…) or NotEqualsErrorMessage(…)

Page 47: Test Driven Development (Delphi)

Diagnostics

0OutputDebugString(…)

Page 48: Test Driven Development (Delphi)

TDD at the Keyboard

1. Add a new test2. Run all tests and see if the new one fails3. Write some code4. Run all tests and see them succeed5. Refactor code6. Repeat

Page 49: Test Driven Development (Delphi)

Exercise 3

0Create a solution with two class libraries:0 TicTacToe0 TicTacToe.Facts

0Add a reference to xUnit.net in the Facts library0 http://nuget.org/

0Use TDD to implement Tic-Tac-Toe0 http://gojko.net/2009/08/02/tdd-as-if-you-meant-it-revisited/

0Time limit: one hour

Page 50: Test Driven Development (Delphi)

Refactoring Code

0 A disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behaviour

0 Usually motivated by noticing a code smell0 There are two general categories of benefits to the activity of refactoring

0 Maintainability0 It is easier to fix bugs because the source code is easy to read and the

intent of its author is easy to grasp0 This might be achieved by reducing large monolithic routines into a set of

individually concise, well-named, single-purpose methods0 It might be achieved by moving a method to a more appropriate class, or

by removing misleading comments.0 Extensibility

0 It is easier to extend the capabilities of the application if it uses recognizable design patterns, and it provides some flexibility where none before may have existed

Page 51: Test Driven Development (Delphi)

Refactoring Techniques0 Techniques that allow for more abstraction

0 Encapsulate Field: force code to access the field with getter and setter methods0 Generalize Type: create more general types to allow for more code sharing0 Replace Conditional with Polymorphism: move each leg of the conditional to an overriding

method in a derived class and make the original method abstract0 Techniques for breaking code apart into more logical pieces

0 Extract Method: turn part of a larger method into a new method0 Extract Class: moves part of the code from an existing class into a new class

0 Techniques for improving names and location of code0 Move Method or Field: move to a more appropriate class0 Rename Method or Field: changing the name to one that better reveals its purpose0 Pull Up: move to a base class0 Push Down: move to a derived class

0 Longer lists0 http://martinfowler.com/refactoring/catalog/index.html0 http://docwiki.embarcadero.com/RADStudio/en/Refactoring_Applications_Index

Page 52: Test Driven Development (Delphi)

Exercise 4

0Create a solution with two class libraries:0 RomanNumerals0 RomanNumerals.Facts

0Use TDD to solve the problem0 https://sites.google.com/site/tddproblems/all-problems-1/Roman-number-conversion

0Refactor the code as you go0Time limit: one hour

Page 53: Test Driven Development (Delphi)

Test Doubles

0 Objects that mimic real objects for testing purposes0 Dummies

0 Have no behaviour or throw exceptions0 Stubs

0 Provide the behaviour of a real object0 Spies

0 Record activity for later verification0 Mocks

0 Define the expected activity before the test is run0 Fakes

0 Employ a simpler implementation such as an in-memory database

0 See also http://martinfowler.com/articles/mocksArentStubs.html

Page 54: Test Driven Development (Delphi)

Mocking Frameworks

0Visual Studio doesn’t have one built-in0Moles

0 Experimental framework from MS Research0Open source

0 Moq, NCrunch, NMock2, Rhino Mocks, fakeiteasy0Commercial

0 TypeMock Isolator, JustMock

Page 55: Test Driven Development (Delphi)

SOLID Code

0 Single Responsibility principle0 An object should have only a single responsibility

0 Open/Closed principle0 Objects should be open for extension, but closed for modification

0 Liskov Substitution principle0 Objects should be replaceable with instances of their derived types

without altering correctness0 Interface Segregation principle

0 Many client specific interfaces are better than one general purpose interface

0 Dependency Inversion principle0 Depend upon abstractions; do not depend upon concretions

Page 56: Test Driven Development (Delphi)

Inversion of Control

0Microsoft0 Unity0 Common Service Locator

0Open source0 Castle Windsor, Autofac, StructureMap, Ninject, LinFu

Page 57: Test Driven Development (Delphi)

Exercise 5

0Create a solution with two class libraries:0 Translator0 Translator.Facts

0Use TDD to solve the problem0 TODO

0Refactor the code as you go0Use test doubles to isolate tests from dependencies

and resources to achieve SOLID code0Time limit: two hours