Using Actors in your Tests / Specifications

Context :

I had reached a situation were a lot of my tests were really doing a lot of set up work around a user – I went back to the original stories and use cases and started to understand that in fact what I was doing was replicating Scenarios by representing state within the User object, my natural go to place at this point would of been StoryQ and more of a BDD style approach. however due to time constraints I didn’t feel I could justify the weight of a BDD implementation, none the less i continued to feel uncomfortable with the amount of duplication inside my tests and also i had this feeling i wasn’t representing “ What i wanted the system to do” but instead was “ showing how the system would do it internally” and therefore was adding a lot of noise to the tests. Finally i also understood that there would be a lot more scenario based testing around user state coming up in the near future and therefore this situation would continue to degrade if i didn’t take action now. 

Options :

  • I could use either fixture or test set up to initialise some sort of hidden user set up code
  • I could write private methods for each user state
  • I could initialize some sort of user dictionary in a base class

What did i Do :

I started to think about how i would explain what each user was doing to someone , and i started to think actually i needed something more semantic and i thought well i have a development team who have to understand my code so based on that i wasn’t happy with the solutions above, i also felt like we needed to pull out and highlight the fact that this was a user in a given state.

So i decided to introduce Actors into the test domain

What is a Actor :

An Actor is a user with a name and properties it is meant to represent a real person using the system for instance

  • Danielle is a logged in user and she is 32 and therefore she is a adult, she has ordered on the site before and has a profile.
  • John is 14 and is new to the site he has registered but hasn’t verified his email address

It could be argued that i have expressed properties of state in the examples above which are not true properties on a actor as they are only constants once they have been applied by the system , i would answer that i find these to be useful design mechanics and therefore i take licence to make use of them in this fashion but i understand the potential objection.

How did you represent this in code :

Well first of all i produced a set of tests to drive out the framework,  but the end result i have detailed below:

 

The code in use in a production test :

t

Commentary

Above we are looking at a ASP MVC model called User Registration with a extension method called PopulateWithUser , we then see a Actor selected form a Enum called FemaleTestUserWithGoodData, we also see a dictionary of optional override values passed into set the Email address on the actor changing it form the pre-potted data.

The Extension Method:

t[11]

Commentary

Above we see the two public extension methods the first takes our ASP MVC model which it extends and the selected Actor [User], the second also takes the dictionary of override values this dictionary has another Enum UserValues which defines the overridable fields the Enums are below:

t[13]

And

3

We then see both extension methods delegate to functions code below:

9

Commentary

We can see above that we create the Type from a known folder and we append the name of the selected Actor , we then use the Activator to create a instance we then call a mapping function let us first look at the mapper and them move onto the Actors.

4

Commentary

I do not think the mapper deserves much comment other than to say that it maps between the Actor and the ASP MVC Model there are a number of way this could of been done and perhaps this will change to another extension method but for the moment I’m happy to leave it like this.

The Actor Classes:

The actor classes are in the form of a base class and some children i will show below the base class and 2 of the children to highlight the overrides and use:

6

We can see above in the base class that we have 2 options for customization the first is the members are virtual with protected setters this was done to give flexibility which i will probably refactor out as it proved not to be needed  , this was superseded by the SetupValues Operation which gives the capability for the object field values to be overridden form a dictionary of values you might remember this piece of code from earlier:

 t

The object values initialized values are set up , by the child object like so :

 9[8]

There is opportunity within this code for further refactoring – but i think the code itself is relatively self explanatory i have included a blow up of the code below.

image

The last areas of interest on the class are the constructors which complete the story

image

Summary and Concept:

The concept behind this code is to supply a set of users with different states set and descriptive names so that we can express intent within the test encourage reuse and still be able to hide code that adds no functional value with out diluting the value of the tests.

By the numbers:
  1. We add a descriptive name to the TestUsers Enum
  2. We add a child Actor inheriting from the DefaultUser Class adding a couple of friendly constructors and setting the data values we want for the object
  3. We pass in any override values as a dictionary to the extension method which we call by creating an ASP MVC User Model and using the “.” syntax

I hope this has been helpful

 

Rebecca