Recently I wanted to run a web UI test across multiple different browsers using WatiN. WatiN supports FireFox, IE and Chrome so that wasn’t a problem, however in order to test the application on difference browsers I would have to duplicate the logic multiple times. This harms readability and maintainability of your tests and is just pain wrong. As such, I created a very similar xUnit Browser Attribute, code can be found on my GitHub repository along with the binaries.
The concept is simple, have the instance of the browser created for you outside of your test and provided the instance as a argument during execution. By using attributes, you can define multiple different browsers, each one will generate a separate test. The advantage of having the tests in this fashion means that if a test one particular browser fails then you can quickly see the problem and the results form the other browsers. If they where just a single test, if one part of test failed, you wouldn’t be able to see the results for the other part. This can make identify where the problems lies much more difficult. An example of the attribute and a test is below.
public class Example
{
[Theory]
[Browser("IE")]
[Browser("FireFox")]
[Browser("Chrome")]
public void Should_Click_Search_On_Google_And_Return_Results_For_AspNet(Browser browser)
{
browser.GoTo("http://www.google.co.uk");
browser.TextField(Find.ByName("q")).Value = "asp.net";
browser.Button(Find.ByName("btnG")).Click();
Assert.True(browser.ContainsText("The Official Microsoft ASP.NET Site"));
}
}
This example is made possible by taking advantage of the xUnit Extensibility model and being able to create objects dynamically in C#. The attribute code is below, as WatiN has a clean namespace structure creating an object based off the string of the name is easy.
public class BrowserAttribute : DataAttribute
{
public string Browser { get; set; }
public BrowserAttribute(string browser)
{
Browser = browser;
}
public override IEnumerable
With this attribute, you can now quickly and easily define the browsers you want the test to run against, without having to duplicate the test itself.
One of the most important considerations when writing automated tests, especially customer acceptance tests is readability. I have been looking at how you could potentially create more readable tests targeted against C# applications. While I have spoke before about IronRuby and RSpecCucumber as customer acceptance tests for C# applications, this combination still has some performance issues together with an initial ‘fear factor’ for some users.
One of the reasons why I created this framework was based on previous experiences of introducing new concepts. Attempting to introduce too many new concepts to a team unfamiliar with the idea can be a huge challenge. Team members focus too much on the amount of information they have to learn instead of focusing on the concept and how it can be applied.
In an attempt to combat this, I have created a prototype which approaches the topic of creating customer acceptance tests in a similar fashion to cucumber, however in the familiarity of C#. While you could successfully write your tests like this, my aim is to use this as a gateway to move people onto other frameworks such as Cucumber via IronRuby.
The code for this can be found on my GitHub repository. For those of you following me on twitter, you will be aware that this code has been available for a while – I’ve only just managed to find time the time to write a post about the framework. If you want to stay up to date, I recommend to stay up to date is follow me on twitter, GitHub and of course my blog.
Back on to the prototype. It is called xUnit.GWT and builds on top of the amazing extensibility model xUnit has in place.
Example
[Feature("As a user... I want to... So that I...")] public class This_is_my_story : This_is_my_story_Base { [Scenario] public void when_transferring_between_two_accounts() { Given("both accounts have positive balances"); When("transfer money from a to b"); Then("a should have the total balance of b", () => a.Balance.ShouldBe(3)); Then("balance of b should be 0", () => b.Balance.ShouldBe(0)); } }
The above code is an example of how a test would look with this prototype. This can be executed using TestDriven.NET, ReSharper and the xUnit.Console itself.
First, lets focus on the class. The class has an attribute called Feature. This should define the feature which the various different scenarios relate to. The scenarios are methods within the class. These methods has been flagged with the attribute Scenario so xUnit can detect and execute them.
Each scenario is then broken down into three different stages. Each of the Given, When, Then statements are in fact method calls with two overloads. One just accepts a string, while the other accepts a string and a delegate.
The reason we can simply pass in a string, is because the associated delegate has already been set within a base class. An example base class is shown here.
public class This_is_my_story_Base : Story { protected Account a; protected Account b;
public This_is_my_story_Base() { SetGiven("both accounts have positive balances", () => { a = new Account(); a.Balance = 1; b = new Account(); b.Balance = 2; });
SetWhen("transfer money from a to b", () => { a.Balance += b.Balance; b.Balance = 0; }); } }
The use of SetGiven or SetWhen allows us to store re-usable blocks of code. Using the string as a key, in our subclass we can use the same key to indicate which block of code should be executed. The aim is that these blocks of code should be reusable enough to allow different scenarios to make use of them and as such improve the readability of our tests.
While playing around, I found this sometimes caused too much overhead which is why you can simply pass in the delegate to execute within the method call. Using the explicit approach when defining your Then’Assertions can actually improve the readability.
With this structure in place, we can now start becoming more flexible. One thing I found when working on test harnesses at Red Gate is that you want to write the boiler plate test while it is fresh in your head, even if the actual implementation is not in place. Having these in place can also provide a good indication of the state of the project. If the test is still pending – it isn’t done.
To cope, you can pass in a delegate called Pending. When you execute the scenario the test will be skipped and not executed.
[Scenario] public void test_marked_as_pending() { Given("one pending block", Pending); Then("it should be marked as pending in the report"); }
The same applies in case you haven’t provided an implementation for anyone of the blocks you are attempting for use.
[Scenario] public void pending_block() { Given(“a block which has been defined”); When(“no action assigned”); Then(“it should be marked as pending”); }
Yet, this is not the whole story. Another problem I commonly experienced was with the NUnit report embedded into CCNet. Even if you have take the effort to make your namespaces, classes and methods make sense I still found it difficult to read.
Taking advantage of the more readable tests, I have created a custom XSLT which can be applied to the xUnit report.
With a bit of styling and bold text in the right place, the report can be extremely readable. When the above examples are executed and the transform has been applied, the report looks like this.
You can easily see which scenarios are passing, failing or pending while also taking advantage of the readable blocks of code to provide more context about what was executed.
This is just a prototype. It is only one possible syntax which you could use. As such, I would be really interested to hear your feedback on this. The framework is fully usable, the binaries can be downloaded here. If your interested in the actual implementation, all the code is available on GitHub. If you have any questions, then please contact me via twitter.
Last night I was doing some experiments with xUnit and TeamCity. TeamCity has a nice UI for reporting tests, however by default it only supports NUnit. Luckily, extending this to support other tests is easy as it just listens for MSBuild outputs in the right format (##teamcity[testStarted name=’Test1′]).
This worked and my tests where appearing in the report.
On the other side of the ocean, Brad was actually working on extending the existing xUnit MSBuild runner for TeamCity integration.
The advantage of Brad’s runner is that you don’t need to edit your MSBuild script, as long as your using the xunit msbuild task it will know when TeamCity executed the build and log to the correct place. Otherwise, it will log to the standard MSBuild output – very cool!
If you want to use this today, download the source code from CodePlex and build it yourself (Get3rdParty.cmd is a great script to run before you build), but I suggest you wait for the next release (1.0.0.4), where support will be included.
Documentation on how to use the MSBuild task can be found here, as I mentioned, using it via TeamCity is no difference.
So far, I have discussed XUnit and the XUnit Extensions but in this post I wanted to discuss how to create your own extensions. Building your own custom extensions is a very useful as it can make your tests much more readable and maintainable. Especially if you have a lot of tasks which need to be performed before or after your tests are executed.
XUnit provides five main base classes which you can build your extensions upon.
FactAttribute
The Fact attribute is the main attribute used in XUnit to identify a method to execute and return the result of. By creating a subclass of FactAttribute we can modify how the test runner should treat the method and allow for customisation. For example, the Theory attribute, which allows for data driven tests, is based on this attribute. The theory attribute customizes how the framework should execute the tests as it creates a separate test to execute based on each DataAttribute added to the test method – this is how TD.net can identify separate passing/failing tests.
If you want to create your own subclass of FactAttribute then the most common scenario will be to subclass from the FactAttribute class, and then override the EnumerateTestCommands method. This is used to enumerate over the test commands system the test object and it returns an instance of ITestCommand per execution of a test method. By overriding this method, you take control of the test methods to be executed.
ITestCommand is the interface of test execution to be returned, which will be executed by the runner. The interface has three items, a name property for the name of the test, a parameters property for all the properties of the test and a Execute method which accepts a testClass object. The Execute method is called in order for the method to be executed. If you just want the standard test execution, then the base concrete class is TestCommand.
Let’s have a look at a real example. Within the Samples project (downloadable from codeplex site) there is a RepeatAttribute class. The attribute on a method would look like this:
[RepeatTest(5)] public void RepeatingTestMethod()
The implementation of the attribute overrides the EnumerableTestCommands method, and for the repeatCount (set in constructor) it returns a new TestCommand object to be executed.
protected override IEnumerable EnumerateTestCommands(MethodInfo method) { for (int index = 0; index < repeatCount; index++) yield return new TestCommand(method); }
In summary, EnumerateTestCommands defines what tests to execute. ITestCommand allows you to define what happens then they are executed.
BeforeAfterTestAttribute
The BeforeAfterTestAttribute is a very interesting attribute which allows for a lot of interesting attributes. This attribute allows us to hook into the execution of the tests before and after they have been executed. Its very simply to implement aswell, BeforeAfterTestAttribute is an abstract class with two virtual methods – before and after. Implement either or both in your attribute, add it to your test/fact and it will be executed.
Again, in the samples solution there is an example of how to use this. It includes a TracingSplicerAttribute which outputs the name. The test looks like this:
[Fact, TracingSplicer] public void TestThis() { Console.WriteLine(“I’m inside the test!”); }
The attribute code is this:
public class TracingSplicerAttribute : BeforeAfterTestAttribute { public override void Before(MethodInfo methodUnderTest) { Console.WriteLine(“Before : {0}.{1}”, methodUnderTest.DeclaringType.FullName, methodUnderTest.Name); }
Before : Example.TestThis I’m inside the test! After : Example.TestThis
This method allows for implementation of Rollback and RestoreDatabase (MbUnit) as they are required to be executed before and after the test but don’t interact with the actual execution.
DataAttribute
The DataAttribute allows us to set data providers for use with the Theory attribute. DataAttribute is an abstract class which has a single method, IEnumerable