beyond basic unit testing: mocks, stubs, user interfaces, and refactoring for testability

39
Beyond Basic Unit Testing: Mocks, Stubs, User Interfaces, and Refactoring for Testability Benjamin Day http://benday.com

Upload: ankti

Post on 25-Feb-2016

68 views

Category:

Documents


2 download

DESCRIPTION

Beyond Basic Unit Testing: Mocks, Stubs, User Interfaces, and Refactoring for Testability. Benjamin Day http://benday.com. Who am I?. Owner, Benjamin Day Consulting, Inc. Email: [email protected] Web: http://www.benday.com Blog: http://blog.benday.com Trainer, Consultant - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Beyond Basic Unit Testing:

Mocks, Stubs, User Interfaces, and Refactoring for

Testability

Benjamin Dayhttp://benday.com

Page 2: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Who am I?

Owner, Benjamin Day Consulting, Inc.– Email: [email protected]– Web: http://www.benday.com– Blog: http://blog.benday.com

Trainer, Consultant– Visual Studio Team System, Team Foundation Server

Microsoft MVP for VSTS Microsoft VSTS/TFS Customer Advisory Council Microsoft Cloud Services Advisory Group Leader of Beantown.NET INETA User Group

Page 3: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Overview

Why do you care about unit testing? Testing Problems Testing Solutions Code

Page 4: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

WHAT & WHY?

Page 5: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

What is Test Driven Development?

Way of developing code so that you always have proof that something is working– Code that validates other code– Small chunks of “is it working?”

Small chunks = Unit Tests Kent Beck (“Test-Driven Development”,

Addison-Wesley) says “Never write a single line of code unless you have a failing automated test.”

Page 6: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

What is a Unit Test?

Wikipedia says, “a unit test is a procedure used to validate that a particular module of source code is working properly”

Method that exercises another piece of code and checks results and object state using assertions

Page 7: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Why Use TDD? High-quality code

– Fewer bugs– Bugs are easier to diagnose

“Test First” method ~up-front design Less time spent in the debugger Tests that say when something works

– Easier maintenance easier refactoring– Self documenting

Page 8: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Maximize Your QA Staff You shouldn’t need QA to tell you your

code doesn’t work Unit testing to minimizes the pointless

bugs– “nothing happened” – “I got an error message” + stack trace– NullReferenceException

QA should be checking for:– Meets requirements– Usability problems– Visual things (colors, fonts, etc)

When you get a bug assigned to you it should add business value

Page 9: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

PROBLEMS & SOLUTIONS

Page 10: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Testing Problems

Extra code just for the sake of the test Code coverage on exception handling Tendency toward end-to-end integration

tests– Databases– WCF & Services– Big back-end systems

Unit testing UIs

Page 11: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Testing Solutions

Mocks, Stubs, and Mocking Frameworks Interface-driven coding Factory Pattern and/or IoC Frameworks Repository Pattern Model-View-Presenter (MVP) Pattern Model-View-Controller (MVC) Pattern

Page 12: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Mocks vs Stubs vs Dummies vs Fakes

Martin Fowlerhttp://martinfowler.com/articles/mocksArentStubs.html

Dummy = passed but not used Fake = “shortcut” implementation Stub = Only pretends to work, returns

pre-defined answer Mock = Used to test expectations,

requires verification at the end of test

Page 13: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

RhinoMocks

Dynamic Mocking Framework By Ayende Rahien

http://ayende.com/projects/rhino-mocks.aspx

Free under the BSD license

Page 14: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

RhinoMocks Primer

MockRepository– Owns the mocking session

StrictMock<T>() Call order sensitive DynamicMock<T>() Ignores call order Stub<T>()

– Ignores Order– Create get/set properties automatically

ReplayAll()– Marks start of the testing

Page 15: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Demo 1: Stub With RhinoMocks

Page 16: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Demo 2: Test Exception Handling

Look at some existing code Refactor for testability Use RhinoMocks to trigger the exception

handler

Page 17: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Avoid End-to-End Integration Tests

Does a good test… …really have to write all the way to the

database? …really have to have a running WCF

service on the other end of that call? …really need to make a call to the

mainframe?

Page 18: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

The Repository Pattern

“Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.”– http://martinfowler.com/eaaCatalog/repository.h

tml

Encapsulates the logic of getting things saved and retrieved

Page 19: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Person Repository

Page 20: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Demo 3: Repository Pattern

Simplify database (or web service) unit test with a repository

Page 21: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

USER INTERFACE TESTING

Page 22: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

User Interfaces: The Redheaded Stepchild of the Unit Testing World

Not easy to automate the UI testing Basically, automating button clicks UI’s almost have to be tested by a

human– Computers don’t understand the “visual stuff”– Colors, fonts, etc are hard to unit test for– “This doesn’t look right” errors

The rest is:– Exercising the application– Checking that fields have the right data– Checking field visibility

Page 23: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

VSTS Web Tests

Record paths through your application Fills in form values Click buttons Validates

Difficult to do test-driven development

Page 24: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

My $0.02

Solve the problem by not solving the problem

Find a way to minimize what you can’t automate

Page 25: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

The Solution.

Keep as much logic as possible out of the UI– Shouldn’t be more than a handful of

assignments– Nothing smart– Real work is handled by the business tier

Test the business tier “Transaction Script” Pattern “Domain Model” Pattern “Service Layer” Pattern “Model View Presenter” Pattern “Model View Controller” Pattern

Page 26: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Service Layer Pattern

From “Patterns Of Enterprise Application Architecture”by Martin Fowler, Randy Stafford, et al.Chapter 9

“Defines an application’s boundary with a layer of services that establishes a set of available operations and coordinates the application’s response in each operation.”

-Randy Stafford

Page 27: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Model View Presenter (MVP)

Page 28: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Model View Presenter (MVP)

Page 29: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

The Common Tiers Presentation tier

– ASP.NET– Windows Forms– WPF– WCF Service – The “View” of MVP

Presenter Tier– Handles the

"conversation" between the presentation tier implementation and the business tier

– Defines the “View” Interfaces

– “Presenter” in MVP

Business tier– Business object

interfaces– Business objects• The “Model” in MVP– Business facades • Manipulate business

objects• Handle requests for

CRUD operations Data Access Tier Data Storage Tier

– SQL Server

Page 30: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Tiering Up: Keep Logic Out Of The UIs Business Object Tier (Domain Model

pattern) Business Façade Tier (Service Layer

pattern)– Create new Business Object methods (Factory

methods)– Wrap CRUD operations, abstract away data

access logic– Duplicate name checks

Create an interface to represent each page in your application

Create Editor Facades as an adapter between the UI interfaces and the business objects

Page 31: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

View interfaces Interface represents the fields

manipulated through the UI ASPX Page or Windows Form

Implements the interface– Interface’s properties wrap UI widgets– ICustomerDetail.CustomerName m_textboxCustomerName.Text

Use a stub represent the UI Write unit tests to test the functionality

of the presenter Avoid business objects favor scalars

Page 32: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

The Presenter

Service Layer Pattern Wrap larger operations that are relevant

to each UI page/screen interface– InitializeBlank(ICustomerDetail)– View(ICustomerDetail)– Save(ICustomerDetail)

Since each page implements the interface, pass the page reference to the facade

Page 33: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Model View Presenter (MVP)

Page 34: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Designing the UI for TestabilityPersonDetailView.aspx

Page 35: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Why is this more testable? Each page/screen only has to get/set

the value from interface property into the right display control

UI does not know anything about business objects

Doesn’t know about any details of loading or saving

Doesn’t have to know about validation

All this logic goes into the editor façade and testable via unit test

Page 36: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Avoid Referencing Business Objects in the UI “interfaces”

ASP.NET– Easier to write stateless pages (everything is in

ViewState)– No need to try to re-create complex objects in

code behind in order to save

Page 37: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Demo 4

Refactor to UI Interfaces

Page 38: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Summary: Testing Solutions

Mocks, Stubs, and Mocking Frameworks Interface-driven coding Factory Pattern and/or IoC Frameworks Repository Pattern Model-View-Presenter (MVP) Pattern

Page 39: Beyond Basic  Unit Testing:  Mocks, Stubs, User Interfaces, and Refactoring for Testability

Who am I?

Owner, Benjamin Day Consulting, Inc.– Email: [email protected]– Web: http://www.benday.com– Blog: http://blog.benday.com

Trainer, Consultant– Visual Studio Team System, Team Foundation Server

Microsoft MVP for VSTS Microsoft VSTS/TFS Customer Advisory Council Microsoft Cloud Services Advisory Group Leader of Beantown.NET INETA User Group