PowerShell and .svnignore
Posted by Thorsten Lorenz in PowerShell, Svn on September 4, 2010
I got very tired of manually ignoring “bin”, “obj” folders and various files (e.g. _Resharper*) when using Svn.
So I looked for a better solution – something similar to Git’s .gitignore.
Reading up on some svn documentation resulted in the below function that will look for ignore definitions (similar to .gitignore) in a given .svnignore file and apply these to all folders recursively.
$psd = Split-Path (Get-Variable MyInvocation).Value.MyCommand.Path function Ignore-Svn { param( [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] $path, $svnIgnoreFile = "$psd\.svnignore", [switch] $recurse) $fullPath = (Resolve-Path $path) if($recurse) { $recFlag = "-R" } svn propset svn:ignore $fullPath -F $svnIgnoreFile $recFlag }
*.obj*.exe*.html*.exp*.pdb*.user*.aps*.pch*.vspscc*_i.c*_p.c*.ncb*.suo*.tlb*.tlh*.bak*.cache*.ilk*.log*.htm*.zip*.sdf*.opensdf*.lib*.sbr*.msi*.exe*.orig*.db_ReSharper.*ReleaseDebugbinobj_UpgradeReport_Files
function Add-Svn { svn st | %{ if ($_ -match "\?\s+(.*)") { svn add $matches[1] } } }
Svn and Git enabled PowerShell prompt
Posted by Thorsten Lorenz in Git, PowerShell, Svn on August 15, 2010
After reading this post and integrating it into my $PROFILE script I marveled at the nice git repository prompt.
A few days later I learned, that we will be using subversion on our next project. To remedy my sadness, my colleague Doug Finke pointed out his svn prompt.
That cheered me up, but since I didn’t want to keep changing my script every time I work with either git or subversion repositories, I combined both of them into a prompt, that gives me information about added(+), modified(~), deleted(-) and untracked(!) files.
I also applied few tweaks to make them more consistent.
Here the screenshots for the no repo, git repo and svn repo prompts:
You can find the script here.
In order for the git part to work you will need this gitutils file.
Amend: In the meantime I changed/improved the script a bit, so the prompts will look somewhat different than in the picture.
TDD suggested readings
Posted by Thorsten Lorenz in BDD on May 25, 2010
Lots of books about test driven development are out there.
In this post I will list the ones I found helpful.
- Test Driven Development: By Example by Kent Beck
- great introduction to TDD
- walks you through the process step by step
- most useful when the reader codes along
- xUnit Test Patterns: Refactoring Test Code by Gerard Meszaros
- focuses on test maintainability and efficiency
- is somewhat verbose and repetitive, but still a great book to learn from
- The Art of Unit Testing: With Examples in .Net by Roy Osherove
- great book, useful not only for .Net programmers as the principles apply everywhere
- explains all the details, paying particular attention to stubbing and mocking
- gives insights into good naming patterns and more
Using mockito in BDD
Posted by Thorsten Lorenz in BDD, Flex, mockito on May 25, 2010
This post could also have been titled: How to avoid meta-tag-itis, as the main challenge when using mockito in a BDD approach is to avoid having to adorn every context class with all the mocks that it, or its base context creates.
In order to understand why these tags are even necessary I dug into the source code and came up with the workaround described below.
Mockito under the hood
Mockito is actually build up onto ASMock, another mocking framework.
ASMock in turn uses FLoxy, a dynamic proxy generation library which was created for ASMock originally. In order for FLoxy to generate the byte code, it uses the FLemit libraries.
Unfortunately the created byte code cannot just be added to the AVM (ActionScript Virtual Machine) on the fly. Instead this has to be done asynchronously before any mocks that use it are created.
As far as I could gather, this is how mockito proceeds:
- It reflects on the Test classes to find out for which interfaces/classes it will be required to supply mock objects
- It creates the byte codes for these, providing a success callback which kicks off the testrunner and a failure callback which will be called if something goes wrong
- once all byte code has been prepared, the success callback is invoked and mockito starts running the tests
- if we now request a mock for a certain type, it uses the prepared byte code to supply us with a new mock instance
Why meta-tags aren’t optimal
In order to perform the first of the above mentioned steps, mockito needs us to specify via meta-tags, what mocks we will need.
Unfortunately it is not enough to just put these tags on top of the context class that actually will instantiate them via mock(IDependency)
Instead, every sub context class (the one containing the specs), that inherits from this context class will have to be adorned with it.
Here is an example:
[Mock(type="interfaces.IDependency")]
[RunWith("org.mockito.integrations.flexunit4.MockitoClassRunner")]
public class when_something_is_the_case extends SomeSpecs
{
[ ... ]
}
As you can see, the RunWith attribute also needs to be added.
Here are the disadvantages of doing it in this manner:
- clutters up the code (imagine meta-tags for six mocks on every context class)
- not refactor friendly – as strings and thus meta-tags never are
- not very maintainable – every time I add another dependency that needs to be mocked, I have to add another meta-tag onto each context class
Clearly not the way to go.
The Mockito class
While digging inside the source code, I found the “Mockito” class which contains the following function:
public function prepareClasses(classes : Array, calledWhenClassesReady : Function, calledWhenPreparingClassesFailed : Function = null) : void
The trick is to use this class in our custom ContextsRunner to prepare the necessary mocks before we kick off the FlexUnit test runner.
This is done inside our runWithMockito function:
private function runWithMockito(fakeClasses : Array) : void
{
_allContexts.push(dummy_context_to_initialize_mockito);
new Mockito().prepareClasses(fakeClasses, runContexts, handleFailure);
}
In case you are wondering why I am adding a dummy context. Looking at its code explains what is going on:
/**
* This class is included in the run contexts, to give mockito one test class
* which has the meta-tag that mockito looks for to initialize.
* Alternatively we could put it on one of our context classes, but this is more convenient.
* @author tlorenz
*/
[RunWith("org.mockito.integrations.flexunit4.MockitoClassRunner")]
class dummy_context_to_initialize_mockito
{
[Test]
public function safely_ignore_this_little_hack() : void
{
}
}
Fortunately this workaround is easier to use than to understand.
Using the ContextsRunner with mockito
As described in the previous post, we create an Air application to run our tests with mockito.
Inside the creationComplete handler we create a ContextsRunner instance and invoke its run method with the contexts to run and the mocks that need to be prepared by mockito:
private function onCreationComplete() : void
{
new ContextsRunner().run([context1, context2, ...], [ClassOrInterface1, ClassOrInterface1, ...]);
}
As a result we don’t need to put any meta-tags inside of our test project.
We only need to make sure, that we pass the class or interface of every mock that we will be requesting from mockito along.
As mentioned in the previous post, we also need to add this compiler argument:
- -includes org.mockito.integrations.flexunit4.MockitoClassRunner
And of course we need to reference the mockito library
The dummy test will show up in our test results, but that should not pose a major problem.
BDD with FlexUnit using workarounds
Posted by Thorsten Lorenz in BDD, Flex, mockito on May 24, 2010
We will now improve on the methodology introduced in the previous post.
The source code for this approach is available here.
Make sure to add “-includes org.mockito.integrations.flexunit4.MockitoClassRunner” to the compiler arguments when compiling the test application.
Running specs inside private classes
Most of you will already know that it is indeed possible to include more than one class inside one ActionScript file.
The crux is that only one of them can be made public. The other ones need to be private and outside of any package. They are consequently only visible to classes within that same ActionScript file.
For that reason the FlexUnit test runner has no way of finding them and thus cannot run the contained specifications.
Here is what we need to do:
- find a way to make the private classes accessible outside their containing ActionScript file
- tell the FlexUnit test runner to run the specs inside them – this will require the creation of a custom runner
The first part is rather simple. All we need is a static property on our public class that returns an Array of the private classes contained inside the same ActionScript file.
To show how this works, here is the new and improved EmployeeSpecs class and some of the private classes contained within the same file:
Don’t worry about the mockito related code at this point as it is explained in a separate post.
package bddwithmockito.specs.accounting.company
{
import accounting.company.Employee;
import accounting.interfaces.IBankAccount;
import org.mockito.integrations.mock;
import specutils.base.SpecificationsBase;
public class EmployeeSpecs extends SpecificationsBase
{
public static function get contexts() : Array
{
return [
initially,
when_told_that_he_is_fired,
when_bankaccount_is_connected_and_his_salary_is_1_dollar_paying_him,
when_bankaccount_is_connected_and_his_salary_is_2_dollars_paying_him,
when_bankaccount_is_not_connected_paying_him,
];
}
protected var _bankAccount_Mock : IBankAccount;
protected var _sut : Employee;
override protected function context() : void
{
_bankAccount_Mock = mock(IBankAccount);
_sut = new Employee(_bankAccount_Mock);
}
}
}
import bddwithmockito.specs.accounting.company.EmployeeSpecs;
import org.mockito.integrations.*;
class initially extends EmployeeSpecs
{
[Test]
public function should_not_have_been_paid() : void
{
the(_sut.wasPaid).shouldBeFalse;
}
[Test]
public function should_not_have_been_fired() : void
{
the(_sut.wasFired).shouldBeFalse;
}
[Test]
public function should_have_zero_salary() : void
{
the(_sut.salary).shouldEqual(0);
}
}
class when_told_that_he_is_fired extends EmployeeSpecs
{
override protected function because() : void
{
_sut.fire();
}
[Test]
public function was_fired_should_return_true() : void
{
the(_sut.wasFired).shouldBeTrue;
}
}
class Ctx_BankAccountIsConnected extends EmployeeSpecs
{
override protected function context() : void
{
super.context();
given(_bankAccount_Mock.isConnected).willReturn(true);
}
}
class when_bankaccount_is_connected_and_his_salary_is_1_dollar_paying_him extends Ctx_BankAccountIsConnected
{
private const SALARY : int = 1;
override protected function context() : void
{
super.context();
_sut.salary = SALARY;
}
override protected function because() : void
{
_sut.pay();
}
[Test]
public function sets_wasPaid_to_true() : void
{
the(_sut.wasPaid).shouldBeTrue;
}
[Test]
public function should_update_his_bank_account() : void
{
verify().that(_bankAccount_Mock.updateWithAmount(any()));
}
[Test]
public function should_update_his_bankaccount_with_1_dollar() : void
{
verify().that(_bankAccount_Mock.updateWithAmount(SALARY));
}
}
The function public static function get contexts() : Array passes all specification classes to the outside world.
I called it contexts() to indicate that it actually returns an Array of classes, each containing a context definition and related specifications.
Calling it specifications() would not have been reflective of that fact.
It is important to note, that the class names contain information about the context and the action since now there are no more extra packages to convey part of this information.
Finally we need to find a way to tell FlexUnit to run the tests contained inside each class.
Creating a custom FlexUnit Test Runner
This task is actually easier than it seems. Still I only want to do it once, so I created a ContextRunner class.
It has a run method that takes an Array of context class Arrays (quite a mouthful) and an optional Array of dependencies that need to be prepared by mockito (we’ll get to that in the next post).
The run method collects the individual specifications, sorts them and finally passes them to the runContexts() method.
This method pushes those specifications into a FlexUntit Test runner and instructs it to run.
private function runContexts() : void
{
var testRunner : FlexUnitTestRunnerUI = new FlexUnitTestRunnerUI();
testRunner.runWithFlexUnit4Runner(allContexts, "");
}
Note:
The second argument of the runWithFlexUnit4Runner() method is ideally the test project name.
This name will change for each test project though and passing in some name will throw an error after the test run completes if it doesn’t match the name of the project that contains the tests.
Just passing an empty string avoids this annoyance.
You can to take a closer look at the ContextRunner which is contained inside the SpecUtils project.
Creating an Air test application
Since we have to use our custom test runner, we can no longer use the integrated “Execute FlexUnit tests” functionality as this will just kick off the default FlexUnit test runner, which will fail to find any of our tests.
Instead we transform our application itself into a test runner.
The steps are simple:
- Create an Air Application
- Inside the onCreation Event instantiate the custom ContextsRunner
- pass it our private context classes that we obtain via the static contexts properties from our Specs classes
- optionally pass any dependencies that need to be prepared by mockito
- run in debug mode (F11)
I chose to use an Air application to avoid a tab to be opened inside my browser that presents me with this:
The presented information it is not very helpful in itself and only gets in the way of looking at the detailed information inside the FlexUnit Results tab.
One solution is to close all tabs on a browser which will cause the Flash Player to close the popup automatically, but as soon as I have a browser instance open anywhere, it brings it into view, adds its tab and leaves it open.
By using an Air application to run my tests, I can set the window visibility to false and am never bothered by anything popping up.
Here is the <WindowedApplication> file for our test application.
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
visible="false"
creationComplete="onCreationComplete()">
<fx:Script>
<![CDATA[
import accounting.interfaces.IBankAccount;
import accounting.interfaces.IEmployee;
import bddwithmockito.specs.accounting.company.EmployeeSpecs;
import bddwithmockito.specs.accounting.company.EmployerSpecs;
import mx.controls.Alert;
import specutils.runners.ContextsRunner;
private function get fakes() : Array
{
return [IBankAccount, IEmployee];
}
private function get allContexts() : Array
{
return [
EmployeeSpecs.contexts,
EmployerSpecs.contexts,
];
}
private function onCreationComplete() : void
{
new ContextsRunner().run(allContexts, fakes);
}
]]>
</fx:Script>
</s:WindowedApplication>
Referencing the FlexUnit libraries
When executing flex unit tests as intended by the FlashBuilder IDE, it will automatically add the FlexUnit libraries for you.
When we are using the just described approach instead, we can either add them manually, or trick FlashBuilder into doing it for us.
Just select “Execute FlexUnit Tests” from the menu. At that point the libraries will be added. In case FlashBuilder complains that there are no tests in our project, just add a dummy test inside any public class and try again.
After the libraries have been added, we delete the FlexUnit application that was created and the dummy test case (if we needed one).
Now we are ready to use the FlexUnit libraries in our test classes.
Note:
If we are using the SpecUtils library classes to run our tests and make our assertions, we don’t need to includethe FlexUnit libraries, since then there is no need to directly reference the classes contained in them.
What’s the catch?
There are actually two drawbacks to doing things as described.
- Since we manually collect and run our specifications, we need to make sure to pass the containing classes out through our context property
- if we forget to do this, the test runner will do just fine, but our newly added specs inside it are never executed
- if we are following the Red-Green-Refactor process, this shouldn’t be a problem, as we will notice that nothing failed, after we added another failing test
- this will remind us to include the new context inside the Array that we pass out to the runner
- The other drawback is due to the fact that the FlexUnitResult navigation does not work for private classes
- clicking on a test inside the FlexUnit Results tab will produce an error message instead of navigating to the test
- it’s no biggie though, since all we have to do is to open the main Specs class, look at the classes being passed out, find the one containing our test and press F3 to navigate to it
Summary
Advantages
- As Before:
- ability to convey lots of information without verbose test names
- contexts are built up incrementally and are centralized which makes for easier maintenance
- specific/general contexts clearly communicate what is needed for individual/all specifications
- actions and assertions are clearly separated into because() and [Test] methods
- specifications are easy to read as they are one liners
- no more file/package explosion
- easier to navigate and thus easier to understand and follow for people not familiar with the concept
Disadvantages
- does not integrate fully with the FlexUnit framework and thus requires the creation of custom test runners
- automatic navigation from test results to the related test code does not work
In the next post we’ll look at a way to make mockito part of our workflow in a way that works great with the described approach.
BDD with FlexUnit using separate files
Posted by Thorsten Lorenz in BDD, Flex on May 24, 2010
We will now try to remedy some of the problems of the methodology explained in the previous post.
Source code for this approach is available here.
Contexts, Because and Specifications
Lets first look at how our tests (or specifications as they are called in the behavior driven environment) are organized.
Contexts
- Main Context
- usually we will create a context class that sets up the most general requirements in order to test a class.
- at the least it will instantiate it and more often than not also inject its dependencies.
- I usually name my main context classes after the class I’m testing with a “Specs” suffix e.g. “EmployeesSpecs” in order to communicate that it sets up at least part of the context used by all specifications for the Employee class
- Context
- any time that a sub context needs to be setup I will create a separate class for it and specifications that use it
- this context inherits from the main context
- additionally it sets up requirements needed to test the behavior that the specifications in the containing class need
- there is a maximum of one context per class
Because
- contains the code that acts on the system under test after the context was fully specified
- is optional and will not be present if no action is needed e.g. when some initial criteria need to be checked
- there is a maximum of one because method per class
Specifications
- check the result(s) of the action inside the because method
- there can be numerous specifications in one class
- specifications should not act on or write to the system under test or its dependencies, but only read out the results
- any actions needed should not be part of the specifications, but are performed inside the because method, therefore the specification methods will most likely be one liners
The SpecificationBase class
In order to help in BDD , I created a Specification base class which all my Main Contexts (Specs classes) will inherit from.
Essentially all it does is hide away the FlexUnit4 mechanics of preparing the tests and allows to set them up in a more BDD agnostic way.
It also includes a method which allows to write assertions in BDD lingo.
Don’t worry about the catchError() method for now.
Again, reading the comments will help in understanding how it works.
1 2 package specutils.base 3 { 4 import specutils.extensions.SpecificationExtensions; 5 6 /** 7 * Acts as a base class for all specifications to help with BDD. 8 * 9 * @author tlorenz 10 */ 11 public class SpecificationsBase 12 { 13 14 protected var caughtError : Error; 15 16 [Before] 17 public function setup() : void 18 { 19 context(); 20 because(); 21 } 22 23 /** 24 * 25 * @param actual the object whose value we are testing 26 * @return the actual object wrapped in a SpecificationExtensions class that adds methods like shouldEqual, shouldBeTrue, etc. 27 * 28 */ 29 protected function the(actual : Object) : SpecificationExtensions 30 { 31 return new SpecificationExtensions(actual); 32 } 33 34 /** 35 * Sets up the context for the specs in the current class. 36 * IMPORTANT: Always call super.context(); when overriding this! 37 * 38 * This can be used in the main context to setup things that apply to all specs. 39 * Ideally at that point the dependencies should be prepared and the sut constructed. 40 * 41 * Any more specific setups should be done inside the current context class. 42 * Here we should setup things that are specific to the behavior we are testing. 43 * 44 */ 45 protected function context() : void 46 { 47 } 48 49 /** 50 * After the context has been setup and the sut is thus prepared, we act on it. 51 * e.g. we invoke a method, set a property or cause a dependency (mock) to interact with it. 52 * The results of this action (normally it should be only one) will then be checked inside the test methods. 53 * 54 */ 55 protected function because() : void 56 { 57 } 58 59 /** 60 * 61 * This is a helper that allows to execute a piece of code that will most likely cause an error. 62 * After invoking it, we can examine the caughtError property to validate that the expected type 63 * of error was thrown and that the message contained what we expected. 64 * 65 * This approach is more flexible than putting a meta-tag for the expected error on the test method. 66 * 67 * @param func 68 * the function that will cause the error 69 * 70 */ 71 protected function catchError(func : Function) : void 72 { 73 try 74 { 75 func(); 76 caughtError = null; 77 } 78 catch (e : Error) 79 { 80 caughtError = e; 81 } 82 } 83 } 84 }
As you can see the [Before] method, which is invoked before each test (spec), invokes the context() followed by the because(), consequently setting up the system under test and its dependencies and then acting on it.
We will override these methods in order to specify the contexts and actions.
The “the” method is there to “extend” our objects with “should” methods. It returns a SpecificationExtensions object and injects the value we are trying to check.
Here is the constructor and one of the methods inside the SpecificationExtensions class:
1 public function SpecificationExtensions(actual : Object) : void 2 { 3 _actual = actual; 4 } 5 6 private var _actual : Object; 7 8 public function shouldEqual(expected : Object) : SpecificationExtensions 9 { 10 assertThat(_actual, equalTo(expected)); 11 return this; 12 }
As we can see, calling the(value).shouldEqual(1); is only syntactic sugar for assertThat(value, equalTo(1));.
It reads much nicer though and speeds up coding due to the intellisense that pops up and allows us to choose the appropriate should method.
It is also possible to add these methods to the Object.prototype and that way allowing value.shouldEqual(1); , but of course there will no intellisense support in that case.
Since I am such a code assist junkie that makes it a no go for me.
Here is a little taste of the convenience:
In case you are wondering why it returns itself, it is to allowto code multiple assertions in a fluent style (this is very rare as ideally there should be only one assertion per specification).
Just for kicks, it would allow me to do this:
1 the(_sut.salary) 2 .shouldNotEqual(1) 3 .shouldNotEqual(2);
The Employee tests revisited
For now we have to part with the convenience of having all our tests for one class inside one file.
This is due to the limitation/rule of the Flex compiler that only allows one public class per ActionScript file and the fact that FlexUnit will not be able to find any tests contained in private classes.
In the next part I will show how to work around this.
For now we want to stick to the rules though in order to enjoy all the benefits of the integrated FlexUnit4, including the automated creation of a test runner.
As a starts we have the main context inside the EmployeeSpecs that does what the [Before] setup() method did in the previous example:
1 package bddseparate.specs.accounting.company.employee 2 { 3 import accounting.company.Employee; 4 import bddseparate.fakes.BankAccountMock; 5 import specutils.base.SpecificationsBase; 6 7 public class EmployeeSpecs extends SpecificationsBase 8 { 9 protected var _bankAccount_Mock : BankAccountMock; 10 protected var _sut : Employee; 11 12 override protected function context() : void 13 { 14 _bankAccount_Mock = new BankAccountMock(); 15 _sut = new Employee(_bankAccount_Mock); 16 } 17 } 18 }
Then we have the following two contexts along with more specific sub contexts:
- the bank account is connected
- the salary is 1 dollar
- the salary is 2 dollars
- the bank account is not connected
Since we can only have one context per class, we need to organize our packages/classes in the following way.
It reads nicely from top to bottom e.g. employee.when_bank_account_is_connected.and_salary_is_1_dollar_paying_him.should_update_the_bankaccount
The test results are also very informative. If any test fails, looking at them will give us very detailed information.
Despite all these details the individual test names are not as verbose as before (e.g. “should_update_the_bank_account”) since a lot of information is contained in the package and class names.
The major problem with this approach is obvious though – packages and files exploded right in our face.
Where there was one file containing all employee tests, we now have 7 and need 2 extra packages to get them organized.
Walking the specification path
For completeness sake I’ll explain how it works – if it is too confusing, skip to the next approach which is easier to look at and will make a lot of things clear.
As I said, the main context is set up inside the EmployeeSpecs and all classes containing specs either directly (e.g. initially.as) or indirectly inherit from it.
Lets take our previous example (employee.when_bank_account_is_connected.and_salary_is_1_dollar_paying_him.should_update_the_bankaccount) and follow it all the way through.
Here is the class containing the actual specifications:
1 package bddseparate.specs.accounting.company.employee.when_bank_account_is_connected 2 { 3 4 public class and_salary_is_1_dollar_paying_him extends Ctx_BankAccount_is_connected 5 { 6 private const SALARY : Number = 1; 7 8 override protected function context() : void 9 { 10 // make sure we call the context setup of Ctx_BankAccount_is_connected first 11 super.context(); 12 _sut.salary = SALARY; 13 } 14 15 override protected function because() : void 16 { 17 _sut.pay(); 18 } 19 20 [Test] 21 public function should_set_was_paid_to_true() : void 22 { 23 the(_sut.wasPaid).shouldBeTrue; 24 } 25 26 [Test] 27 public function should_update_the_bank_account() : void 28 { 29 the(_bankAccount_Mock.updateWithAmountWasCalled).shouldBeTrue; 30 } 31 32 [Test] 33 public function should_update_the_bankaccount_with_1_dollar() : void 34 { 35 the(_bankAccount_Mock.updateWithAmountWasCalledWith).shouldEqual(SALARY); 36 } 37 } 38 } 39
As we can see, after setting up the specific context and acting on the system under test via the because method, it makes sure that the three specifications are met.
Note, that it inherits from the Ctx_BankAccount_is_connected class and calls its context() method before further defining its own context.
Here is the Ctx_BankAccount_is_connected class:
1 package bddseparate.specs.accounting.company.employee.when_bank_account_is_connected 2 { 3 import bddseparate.specs.accounting.company.employee.EmployeeSpecs; 4 5 public class Ctx_BankAccount_is_connected extends EmployeeSpecs 6 { 7 override protected function context() : void 8 { 9 // Make sure we build up onto the main context 10 super.context(); 11 _bankAccount_Mock.isConnected = true; 12 } 13 } 14 } 15
As you can see it extends from the EmployeeSpecs class and now it should be clear how the context is created from the most general one inside the EmploySpecs and gets more and more specific as we walk up the inheritance chain until we arrive at our actual specifications.
Summary
Advantages
- ability to convey lots of information without verbose test names
- contexts are built up incrementally and are centralized which makes for easier maintenance
- specific/general contexts clearly communicate what is needed for individual/all specifications
- actions and assertions are clearly separated into because() and [Test] methods
- specifications are easy to read as they are one liners
- also integrates fully with the integrated FlexUnit framework and thus there is no need to create custom test runners
Disadvantages
- file/package explosion
- harder to understand and follow for people not familiar with the concept
In the next post I will explain how to avoid the packages/files explosion and will enter mockito into the picture.
BDD with FlexUnit the traditional TDD way
Posted by Thorsten Lorenz in BDD, Flex on May 24, 2010
Implementing tests the traditional TDD way
Source code for this approach is available at here.
We are now ready to look at the tests that we need for the project created in the previous post.
First of all we have to decide what we will be testing.
In this case I wanted to make ensure two things:
- that the Employee keeps track of its own status correctly (was he paid, fired?)
- that the Employee interacts correctly with the bank account
- that the Employer interacts correctly with the Employee
Note that at this point I am not worried about the functionality of the bank account as this will be implemented later.
The test project
I don’t believe in including test code inside my production code projects, so lets create a separate Flex library project for our tests.
In it we include a fakes package and a tests package.
The fakes package will contain the necessary mocks and stubs.
Inside the tests package we mirror the exact package structure of the project we are testing in order to easily find the classes and their related tests.
For example the Employee.as is inside the accounting.company package and so we put the EmployeeTests.as inside our test project inside the the tests.accounting.company package.
A short excursion into fakes
For a more detailed introduction please read the mock Wikipedia page.
I will just mention some core points.
- Mocks vs. Stubs
- mocks help decide if a test will pass by having things verified, while stubs just stub out properties or method return values
- as a general rule if a fake is not used in a verification it is a stub, otherwise it is a mock
- adhering to strict naming conventions makes it easier to see how a fake object is used in the tests
- fakes and top down development
- fakes help in developing our application test driven and top down
- in our example, I can test the interactions of the Employee with the bank account without having implemented the latter. All I need is its interface and a mock that implements it. This way I can flesh out, what it needs to be able to do, before starting with the actual implementation. That way I avoid implementing behaviors that will not be needed after all. The design will also be improved because I see how it a class will be used while I am creating it.
- fakes, dependency injection and interfaces
- it is good practice to create an interface for every dependency and inject it as an interface (instead of as a concrete class) into the dependent class either via the constructor or its properties
- while this is just good design, it makes testing much easier as it allows replacing the dependencies with fakes while testing the dependent class
As I said, his is a very brief look at the advantages of using fakes. For further reading consult the books in the suggested readings or the above mentioned wiki page.
The BankAccount Mock
Here is the code of the BankAccount interface inside the Accounting project:
package accounting.interfaces
{
public interface IBankAccount
{
function updateWithAmount(amount : Number) : void;
function get isConnected() : Boolean;
}
}
The mock implements the interface, but has no real functionality:
package traditional.fakes
{
import accounting.interfaces.IBankAccount;
/**
* This class is just keeping track of what is done to it.
* It will be injected instead of the real thing and afterwards I can check if the System under Test
* interacted with it in the desired way.
* e.g. did it tell the BankAccount to update with the correct amount.
*
* @author tlorenz
*
*/
public class BankAccountMock implements IBankAccount
{
public var updateWithAmountWasCalled : Boolean;
public var updateWithAmountWasCalledWith : Number;
private var _isConnected : Boolean;
public function updateWithAmount(amount : Number) : void
{
updateWithAmountWasCalled = true;
updateWithAmountWasCalledWith = amount;
}
public function get isConnected() : Boolean
{
return _isConnected;
}
public function set isConnected(value : Boolean) : void
{
_isConnected = value;
}
}
}
Notice, that we added a setter for the isConnected property (not required by the interface), in order control the state of the bank account in our tests.
The Employee tests
Make sure to read the comments inside the following snippet, to get an idea of how it works and why we end up with these long test names.
package traditional.tests.accounting.company { import accounting.company.Employee; import accounting.interfaces.IEmployee; import org.flexunit.assertThat; import org.flexunit.asserts.*; import org.hamcrest.object.equalTo; import traditional.fakes.BankAccountMock; /** * * @author tlorenz * quoting from this nice tutorial (with comments added): * http://www.insideria.com/2009/05/flashbuilder4-will-support-fle.html * * • [Before] - Replaces the setup() method in FlexUnit 1 and allow using multiple methods. Supports async, timeout, order and ui attributes. * - is executed before each test * * • [After] - Replaces the teardown() method in FlexUnit 1 and allow using multiple methods. Supports async, timeout, order and ui attributes * - is executed after each test * - good unit tests should not need to undo anything after a test * * • [BeforeClass] - allow running methods before test class. Supports order attribute. * - is executed once before all tests * * • [AfterClass] - allow running methods after test class. Supports order attribute. * - is executed once after all tests * - good unit tests should not need to undo anything after a test */ public class EmployeeTests { // This will be injected instead of a real BankAccount and allows verification of interaction. private var _bankAccount_Mock : BankAccountMock; // _sut is System Under Test (what I am testing - in this case Employee) // this naming convention is taken from the in depth book: "xUnit Test Patterns: Refactoring Test Code" private var _sut : IEmployee; [Before] public function setup() : void { _bankAccount_Mock = new BankAccountMock(); _sut = new Employee(_bankAccount_Mock); } [Test] public function Initially_WasPaidIsFalse() : void { assertFalse(_sut.wasPaid); } [Test] public function Initially_WasFiredIsFalse() : void { assertFalse(_sut.wasFired); } [Test] public function Initially_SalaryIsZero() : void { assertThat(_sut.salary, equalTo(0)); } [Test] public function WhenToldThatHeIsFired_WasFiredIsTrue() : void { _sut.fire(); assertTrue(_sut.wasFired); } // The following Testnames follow the pattern suggested by Roy Osherove in his "The Art of UnitTesting" // // [Test] // public function Situation_Action_Result // // As can be seen further down, this can result in very verbose testnames when the situation is a little complex[Test] public function BankAccountIsConnected_Paying_SetsWasPaidToTrue() : void { _bankAccount_Mock.isConnected = true; _sut.pay(); assertTrue(_sut.wasPaid); } [Test] public function BankAccountIsConnected_Paying_UpdatesBankAccount() : void { _bankAccount_Mock.isConnected = true; _sut.pay(); assertTrue(_bankAccount_Mock.updateWithAmountWasCalled); } [Test] public function BankAccountIsNotConnected_Paying_SetsWasPaidToFalse() : void { _bankAccount_Mock.isConnected = false; _sut.pay(); assertFalse(_sut.wasPaid); } [Test] public function BankAccountIsNotConnected_Paying_DoesNotUpdateBankAccount() : void { _bankAccount_Mock.isConnected = false; _sut.pay(); assertFalse(_bankAccount_Mock.updateWithAmountWasCalled); } [Test] public function SalaryIs1DollarAndBankAccountIsConnected_Paying_UpdatesBankAccountWith1Dollar() : void { const SALARY : Number = 1; _sut.salary = SALARY; _bankAccount_Mock.isConnected = true; _sut.pay(); assertThat(_bankAccount_Mock.updateWithAmountWasCalledWith, equalTo(SALARY)); } [Test] public function SalaryIs2DollarsAndBankAccountIsConnected_Paying_UpdatesBankAccountWith2Dollars() : void { const SALARY : Number = 2; _sut.salary = SALARY; _bankAccount_Mock.isConnected = true; _sut.pay(); assertThat(_bankAccount_Mock.updateWithAmountWasCalledWith, equalTo(SALARY)); } } }
Running these tests produces the following output:
The long test names are necessary for us to know right away what went wrong when a test fails. Ideally we don’t even want to look at the test code, but go right to the production code to fix the problem.
Obviously a test name like “testingWasFired” won’t accomplish that goal. Instead we include the Context (Situation), what we did (Act/Because) and what result we were expecting. In BDD terms the test name takes on this format: Context_Because_ExpectedResult. This maps to the TDD naming: Situtaion_Action_ExpectedResult.
From looking at some of the resulting test names like:
SalaryIs1DollarAndBankAccountIsConnected_Paying_UpdatesBankAccountWith1Dollar
or as found inside the Employer tests (part of the downloadable source code):
EmployeeWasNotFiredSalaryIsGreaterZeroAndWasNotPaid_PayEmployee_PaysHim
we can see that this could become a problem once we are dealing with more complex contexts and/or actions.
Note: the first 4 tests names deviate from this pattern, as there is either no context to be setup and/or nothing is done to the system under test.
Lets look closer at one of the Employee tests to show the naming convention in an example:
[Test]
public function BankAccountIsConnected_Paying_SetsWasPaidToTrue() : void
{
_bankAccount_Mock.isConnected = true;
_sut.pay();
assertTrue(_sut.wasPaid);
}
The test name has the three parts which correspond to a line of code each:
- Context: BankAccountIsConnected
_bankAccount_Mock.isConnected = true; - Because: Paying
_sut.pay(); - Expected Result: SetsWasPaidToTrue
assertTrue(_sut.wasPaid);
Test maintenance
There is one more very important disadvantage to the described approach.
Once the functionality of the system under test grows, we need to prepare more things in order to run our tests. The problem is though, that preparations needed by test2 may not be necessary for test1 and vice versa.
As a result if we setup everything that is needed by either test inside the [Before] method, it becomes hard to see which preparation each test actually needs, which makes troubleshooting a failed test that much harder.
If , on the other hand, we put these individual preparations inside the test methods itself, we will pay for it later, when the class under test changes.
For example lets say 10 tests setup the system under test by calling a method on it that takes currently one parameter. If we now change it to take another (non-optional) parameter, we have to change the invocation in all these 10 tests.
This can become a huge problem and make changes to our code a lengthy process, which is of course not desirable in an agile environment.
Another way around these is to factor out the commonalities into separate methods e.g. prepareInvocatorTests(). At this point though it becomes difficult again to understand each test because in order to do so, we have to navigate to an extra method.
On the other hand, there are clear advantages to writing our tests in this way, as I will mention inside the summary section which will close the discussion of each of the three different approaches I am presenting.
Summary
Advantages
- easier to understand for people new to BDD/ TDD than the approaches shown next
- fully integrates with FlexUnit and doesn’t require the creation of custom test runners
- all tests for a class are contained inside one ActionScript file
Disadvantages
- verbose test names can become a problem
- when contexts become more complex and need to be different for each test, they either become less readable or a maintenance nightmare
We’ll take a first stab at solving these issues in the next part.
BDD with FlexUnit and mockito Introduction
Posted by Thorsten Lorenz in BDD, Flex, mockito on May 23, 2010
Introduction
Coming from a .Net background with strong emphasis on best practices, one of my first missions when learning Flex, was to figure out how I could implement Behavior Driven Development in this environment.
I tried a lot of different approaches and will show three of them in the following posts.
I will not explain what is meant by BDD – there are numerous blogs out there and a good starting point is this wikipedia article.
At this point a simple comparison to TDD (Test Driven Development) shall suffice:
- Arrange in TDD corresponds to a Scenario/Context in BDD and is usually expressed inside a “Context”, “EstablishContext” or a “Given” codeblock
- Act in TDD corresponds to an action done to the system under test and is expressed in BDD inside a “Because” or “When” codeblock
- Assertions in TDD correspond to “should” methods in BDD like shouldEqual, shouldBeTrue etc.
The details of this correlation will become clear in the examples.
Choosing a testing framework
Although there are numerous Flex testing frameworks out there, none of them lend themselves particularly well to BDD.
Note:
I gave fluxunit – modeled after Rspec , a testing framework for Ruby – a drive.
It’s architecture would be very BDD enabling, but at this point it is still missing a lot of needed aspects.
For example it presents all test results as panels inside the browser window, marking the failed ones as red, which would require the developer to go hunt for the failures by scrolling through all of them.
That and the fact that no stack traces of the failures are given, make it not mature enough to be used in a serious project at this point.
Unfortunately it seems to be a dead, since it wasn’t updated for over a year.
Other testing frameworks are not offering anything very different to what is offered by FlexUnit4 which additionally has the following advantages:
- it is fully integrated into Adobe’s FlashBuilder and allows running the tests and inspecting the results inside the IDE
- it is supported by Adobe and will most likely be evolved in the future
- a lot of frameworks related to testing (e.g. the mocking framework mockito) integrate with FlexUnit
- there is a lot of good documentation out there like this “getting up and running” tutorial
FlexUnit4 is not designed to be used as a BDD framework though and a few hurdles will need to be overcome.
What we’ll be testing
The source code for this application is available here.
To get started, I implemented a sample application following the traditional TDD style as explained in part 2.
The application I created has 3 components – an employer, an employee and a bank account:
- BankAccount
- is either connected or not
- can be updated
- Employee
- can get fired
- can get paid only if the bank account is connected
- will show if he did good work or not
- Employer
- handles the Employee
- evaluates the Employee and fires him if he didn’t do any good work
- should only pay the Employee when his salary is greater zero, he wasn’t paid before and was not fired either
Road map
I will show three different ways to test the above mentioned classes.
- The traditional way – TDD, using manually created mocks.
- BDD in a way that fully integrates with the FlexUnit4 framework and FlashBuilder and thus can use the automatically created test runner, but requires a lot of classes. We will use manually created mocks here as well.
- BDD in a way that requires us to create a custom test runner, but only two classes for our tests. We will use mockito to supply our mocks. This is in my opinion the most efficient way in order to get things done.
- A look at using mockito in a way that seamlessly integrates with the approach described above.






