beyond basic unit testing: mocks, stubs, user interfaces, and refactoring for testability
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 PresentationTRANSCRIPT
Beyond Basic Unit Testing:
Mocks, Stubs, User Interfaces, and Refactoring for
Testability
Benjamin Dayhttp://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– 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
Overview
Why do you care about unit testing? Testing Problems Testing Solutions Code
WHAT & WHY?
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.”
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
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
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
PROBLEMS & SOLUTIONS
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
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
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
RhinoMocks
Dynamic Mocking Framework By Ayende Rahien
http://ayende.com/projects/rhino-mocks.aspx
Free under the BSD license
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
Demo 1: Stub With RhinoMocks
Demo 2: Test Exception Handling
Look at some existing code Refactor for testability Use RhinoMocks to trigger the exception
handler
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?
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
Person Repository
Demo 3: Repository Pattern
Simplify database (or web service) unit test with a repository
USER INTERFACE TESTING
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
VSTS Web Tests
Record paths through your application Fills in form values Click buttons Validates
Difficult to do test-driven development
My $0.02
Solve the problem by not solving the problem
Find a way to minimize what you can’t automate
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
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
Model View Presenter (MVP)
Model View Presenter (MVP)
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
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
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
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
Model View Presenter (MVP)
Designing the UI for TestabilityPersonDetailView.aspx
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
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
Demo 4
Refactor to UI Interfaces
Summary: Testing Solutions
Mocks, Stubs, and Mocking Frameworks Interface-driven coding Factory Pattern and/or IoC Frameworks Repository Pattern Model-View-Presenter (MVP) Pattern
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