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!