Codemash 2013 – Advanced Unit Testing Considering The Stakeholder

Presenter Peter Ritchie – Ottowa Canada peterritchie.com.

1:45 PM  1/10/2013 in Portia/Wisteria

My Overview

Interesting perspective as far as generating automated acceptance tests.  Good idea to write out acceptance tests in english using a BDD style Given, Then When syntax.  Doing this you can involve stakeholders in the acceptance test creation process.  Can then convert these english language tests to test code that now has meaning to the stakeholder.  To create documentation can write a tool to build a nice html report that is in a BDD format and lets stakeholder clearly see the results of tests they helped write and understand more thoroughly.

This is a great idea for acceptance testing.  It ignores the difficulty of doing this in systems that have a lot of dependencies that can’t be run real time for testing.  I see this is more a companion to developer unit testing than a replacement.  More importantly could be very handy at more thoroughly ferreting out requirements by having stakeholders help write acceptance tests in syntax they can understand.

My Notes

Agenda

  • Principles
  • Readability
  • Maintainability
  • Documentation
Principles
What is a unit test?
  • Automated
    Just an automated test as far as Peter is concerned.  A unit being tested is not meaningful to a stakeholder.   Acceptance testing is  what matters to stakeholders.
Why
  • Verify changes to code
Good Unit Tests
  • Automatable
  • Trustworthy
    a failure is meaningful and can actually fail
  • Readable
  • Maintainable
    don’t want to have to change unit tests every time you change any code
Going to focus on readable and maintainable unit testing.
Now he started walking through code examples:
  • Simple Calculate Class that adds two numbers
    three asserts in one test method which makes it unclear why the test failed when it fails.  Make smaller tests, with one actual test and a human readable name so failing test name tells you all you need to know.
  • Reviewed Arrange, Act Assert methodology as means for organizing a test
    Arrange test data, the Act by running method under test, then assert to validate test worked.
  • Refactors his tests to make tests more readable and to reduce duplicated code
    Setup and Teardown methods – reviewed that setup and teardown run before and after each test in the test class.
    If multiple tests are exact same code with just different parameters then can pass in rows of data to one test to just change parameters
BankAccount Demo
  • Used BankAccount class as example class to test to show more business logic complexity
  • Using BDD (Behavioral Driven Design) as mechanism for showing how to structure acceptance testing
    really downplayed the notion of mocking.   Can only do this testing if have whole system available
  • Acceptance Criteria
    Given an initial state, after a certain action, ensure that the post state is correct.  Good to have users write out acceptance tests by hand in Given, then when syntax.  Gerkin format.
  • Walked throw an example of updating class and test naming.   Class name now ‘when_depositing_to_active_account_through_atm.
    Uses ‘When’ clause to name files, then use ‘then’ clauses to name tests in the file.  Makes for a logical means of partitioning tests into smaller files that makes sense to the stakeholder.
  • Showed resharpers test runner, as far as how it shows nested view which may be more meaningful to the stakeholder
  • The Given is the setup of the test class
  • Showed example of using base class to share setup methods across multiple test fixtures
  • If you use a Given, When Then syntax when writing tests, as in having stakeholders write them, can use the above approach to convert them to acceptance test code that will then be much more meaningful to the stakeholder.
Fluent Interface
  • Walked threw example of a Fluent API for building a type so it is clear what every value that is being set is.
  •   new BankAccountBuilder().OfType(AccountType.Savings)
    .WithBalance(500m)
    .WithId(1);
  • Builder is only test code used for testing, not used in production code.
  • Fluent is method that sets property on instance that returns the instance to allow  chaining
  • public BankAccount WithId(int id)
    {
    this.Id = id;
    return this;
    }
  • Can use tools to run Given When Then structured tests to create report output that is very meaningful to stake holders.
    Scenario is ‘When’
    Given is Setup
    When are individual tests.
    DocumentationGenerator can be run to create acceptance test output
  • Walked through his implementation of DocumentationGenerator that runs tests and then builds nice html Scenario, Given Then When report.  Good idea.
    Basically gets test-fixtures from assembly finding them by attribute [TestFixture], sets up html header for fixture, runs tests creates html for each test, then writes end html for fixture and moves on!

Someone Recently Asked What Design Patterns I Used, Here’s What I Said.

There are a few design patters I use frequently, mainly because in business software the problems they are geared at solving come up often. The first is the Command pattern. This pattern in demonstrably useful in UI operations as it supports a generic means for undo and redo operations. When UI operations are implemented as atomic Command classes their undo redo operations are explicitly defined in a concrete object, and are generically invoked from the stack managing the executed commands as base commands. I have also come to find that the Command Pattern is very useful in pure business logic as well. In environments where distributed transactions are involved the Command pattern allows the definition of atomic transactions to be defined as a command in the business logic layer. The benefit of this structure is that each atomic Command can be chained and composite transaction behavior can be defined in the base Command class instead of by each operation itself.

There are two other patterns I use frequently to make code less coupled and more testable. The first, the Factory Pattern, was much more helpful before the wide acceptance of dependency injection frameworks. The Factory Pattern allows me to abstract the creation of classes from their consumers. This allows the consumed class to be an abstraction, an interface, and allows the management of its creation to be removed as a concern from the consumer. From a testing perspective this allows the injection of mock objects in situations where a consumer of an object is being unit tested and the consumed object has an outside dependency, such as connecting to a database or making a network call. The Factory Pattern also keeps the consumer from being directly coupled to the object it’s consuming. This lesser coupling makes it that much easier to manage changes to the consumed object. If changes to the consumed object do not change the interface the consumer is using, then changes to the consumed object have no effect on the consumer at all.

I use the Singleton Pattern frequently to apply abstraction to objects that do not need to keep state. Static classes cannot implement interfaces, which makes it difficult to mock them when testing their consumers. Singletons allow for a method of applying an interface to what otherwise would be a static class. Using a Singleton instead of a just creating a separate instance for each call to a class allows for more efficient memory management since only one instance to manage, and the interface allows the Singleton to be mocked when and if necessary.

Lately I have used the Mediator Pattern. This pattern became useful in the UI work I have done in the context of event handling. I implemented a Mediator Pattern to create an event aggregator so event handlers and throwers would register and listen and throw events to the event aggregator, instead of directly to each other. This assisted in minimizing memory leaks due to improper releasing of event references , and also decreased coupling of classes needed for direct event relationships.

Resetting Subversion Solution Binding In Ankh and Visual Studio

Had to reset a solution binding in Visual Studio 2008 after a Subversion repository was changed to use https. We’re using Ankh for Subversion access from Visual Studio.

You would think changing source control bindings would be under File->Subversion->Change Source Control. It’s not.

To change binding roots have to right click on your solution and select Subversion->Switch Solution. Not a big deal, but I spent about 20 minutes running this down. Hope it helps someone.

CodeMash 2010 Wrap UP

I attended CodeMash at Kalahri in Sandusky, Ohio last Wednesday and Thursday.  I skipped out on the last day to catch up on some work.  All in all it was a great experience.  I learned quite a bit and also felt validated in many of the approaches we’ve been taking at work.

Below are my notes from the sessions I attended.  I also have to note my favorite quote from CodeMash.  Barry Hawkins was giving a presentation on Domain Driven Design.  When trying to describe the experience of talking to Doman Driven Design people about Domain Driven Design, (apparently they can be long winded in their explanations)  he said something like, “it’s like talking to Ents with crack pipes”.  I liked that description a lot!

Session Notes:

Engineering Vs Design

Domain Driven Design

Software Design and Testablity

User Stories Closing The Agile Loop

Keynote – Lean Methodology

Agile – Iteration Zero

Practical B/TDD

Fundamentals Of Software Engineering

CodeMash – Engineering Vs Design

It’s my last session today and forever at CodeMash this year.  I’m not able to show tomorrow.  Currently sitting in on Engineering Vs Design, given by Joe Nuxoll.

Reviewing Web 2.0 and RIA‘s, things like Google Maps, could they have been envisioned by a designer with no software knowledge or vice versa?  Probably not.  Must have design and engineering mixed together in ways not previously needed.  UI Engineering is design and design is UI Engineering.

Traditional Roles in product development: Designers, UI Developers, and web UI developers.  More and more you are seeing people who can do all of these tasks as need to understand them all.  New breed of tools to simplify this sort of work, RIA Design tools:  Adobe Catalyst, JavaFX Production Suite.

Important to cross train engineers and designers as they function with very different processes.  Important to educate engineers on the design process and designers on the engineering process to encourage mutual skill appreciation.  To this end co-location is very helpful.  Much easier for designers and engineers to understand and support each others processes if they are situated together.

Important to understand the difference between prototype and production.  Build many prototypes and be willing to throw them away.  Joe likes to use a separate folder in subversion for design, partly because subversion is good at handling design type resources and partly to separate highly iterative resources.   The design folder is prototype work, not production.  Also brings benefit of version control to design, where it is not traditionally used.

Build detailed facades.  These are generally not going to be production code, be ready to throw much of it away.  Really iterate to get it right.  Stub out back end calls and keep back end people in the loop.  Make sure the UI team has regular check ins with the back end team.

Once you’ve iterated to the point where can start work on production code can lift much of the final iteratino prototype code to start production work.  Keep prototypes clean by doing production work in separate source control folder.

Joe seems to be wrapping up although still 20 minutes left in the session.  I think we’re going to Question and Answer now.  Question came up as to how to get end users to not focus on color and such when reviewing a functional wire frame?  Joe’s answer, keep all design detail out of functional wireframe so nothing for end user to get distracted by.

Wire frame prototyping should happen before visual design.  Designers need app functionality to be fairly solid before they can effectively begin their work.  Interaction and functionality should be defined thoroughly before visual design.

Well that’s a wrap.  Another good session, not very technical but very relevant to our current work.