Jan 01 2010
BDD in .NET with Cucumber, Cuke4Nuke and TeamCity
At the Oresund Developer conference in Sweden about two months ago, Aslak Hellesoy talked about recent changes to his Cucumber Behaviour-Driven Development tool, aimed at providing better support for platforms other than Ruby. Instead of using the tool through slow Ruby ports, .NET and Java developers got a chance to benefit from much quicker native integrations using a new wire protocol that allows Cucumber to talk to external systems. Richard Lawrence and Matt Wynne were very kind to work on a native .NET integration for Cucumber, called Cuke4Nuke, which recently got up to speed with Cucumber Ruby features. In this article, I’ll show you how to set up and use Cuke4Nuke to use Cucumber for .NET BDD development.
Basic Software
- If you don’t already have Ruby installed, install it using the new one-click Ruby Installer. You don’t have to know Ruby to write Cuke4Nuke tests, but you still need it to run Cucumber. Install the Ruby development kit as well. Alternatively use the old 1.86 installer which comes with the development kit.
- Add GemCutter.org to the list of Ruby Gem sources. Execute the following command from the command line:
gem sources -a http://gemcutter.org/
- Install the Cuke4Nuke gem. Execute the following command from the command line:
gem install cuke4nuke
- Install the Win32Console gem to get colour reports in the windows console window:
gem install win32console
You might also need WAC to work around console colour problems so download that Exe and put it somewhere on the disk.
- If you don’t already have NUnit, grab the latest version from NUnit.org. We’ll need this later as Cuke4Nuke uses NUnit assertions.
To verify that the system is set up, execute Cuke4Nuke from the command line. You should see a help screen with Cuke4Nuke options. If you see an error that the command Cuke4Nuke isn’t found, check if there is a Cuke4Nuke.bat executable in your Ruby bin folder (C:\Ruby\bin if you accepted the default installation options for Ruby), whether that folder is on your executable path and whether Cuke4Nuke gem exists in the gems folder (C:\Ruby\lib\ruby\gems\1.8\gems\cuke4nuke-0.3.0 on my system).
Project setup
Create a normal C# class library project and add a Features folder to it. This is where your Cucumber scenarios will go. Add a step_definitions subfolder to that and create a file called cucumber.wire, with the following content:
host: localhost port: 3901
This tells Cucumber to connect to an external system on port 3901, the default port for Cuke4Nuke. Now let’s add a test scenario to make sure that everything is working correctly. Create a file called basic.feature in the Features folder, with the following content:
Feature: Hello World In order to ensure that my installation works As a Developer I want to run a quick Cuke4Nuke test Scenario: Hello World Given The Action is Hello When The Subject is World Then The Greeting is Hello, World.
At this point, your project structure should look as on the picture below:
Now let’s run Cuke4Nuke for the first time. Build the project, open the console, go to your project folder and run the following command:
Cuke4Nuke bin\debug\Cuke4NukeExample.dll -q
(replace the DLL path with your project output DLL). You should see the Cucumber output telling you that there is one scenario with three steps, all of which are undefined. If you do not see the colours, add the -c flag and pipe the output to WAC.exe, making the command similar to the following:
Cuke4Nuke bin\debug\Cuke4NukeExample.dll -q -c | d:\apps\wag.exe
In any case, the command result should be similar to one on the picture below:
Now let’s add the step definitions that help Cucumber talk to our project code. Create a C# class file (say Steps.cs) and paste the following code:
using System;
using System.Text;
using Cuke4Nuke.Framework;
using NUnit.Framework;
namespace Cuke4NukeExample
{
public class HelloWorldSteps{
private String action;
private String subject;
[Given("^The Action is ([A-z]*)$")]
public void ActionIs(String action)
{
this.action = action;
}
[When("^The Subject is ([A-z]*)$")]
public void SubjectIs(String subject)
{
this.subject = subject;
}
[Then(@"The Greeting is ([^\.]*).")]
public void CheckGreeting(String greeting)
{
Assert.AreEqual(greeting, action + ", "+subject) ;
}
}
}
Add a reference to NUnit.Framework.dll (from your NUnit installation) and Cuke4Nuke.Framework.dll (you’ll find it in C:\Ruby\lib\ruby\gems\1.8\gems\cuke4nuke-0.3.0\dotnet\Cuke4Nuke.Framework.dll). Now build the project again, go to the console and re-run the Cuke4Nuke command. The output should now say that the steps passed.
When it runs the feature specification, Cuke4Nuke will look for methods marked with Given, When and Then attributes that match steps by regular expression. Any capture groups in the regular expression are passed to the method as arguments (they don’t have to be Strings, you can use other .NET types as well). So, for example, the line “When The Subject is World” matches the following method:
[When("^The Subject is ([A-z]*)$")]
public void SubjectIs(String subject)
{
this.subject = subject;
}
Our simple script will set the subject and the action and then verify the greeting using the standard NUnit assertion Assert.AreEqual. Just to see it when it fails, modify the CheckGreeting method or feature source so that they don’t match and re-run Cuke4Nuke.
Of course, for a proper project this code would talk to our domain classes but let’s keep it simple.
Build integration
We can add Cuke4Nuke as a post-build step so that all the specifications get executed after every build. Open your project .csproj file and add this just above the closing tag:
<PropertyGroup> <PostBuildEvent>cuke4nuke $(TargetPath) $(ProjectDir)features -q </PostBuildEvent> </PropertyGroup>
You can now inspect the results of Cuke4Nuke in your output window every time a project is built.
Continuous Integration
To complete the project setup, let’s run Cucumber tests within a continuous integration environment and store test outputs next to project build results. I use TeamCity even for .NET projects, so I’ll use it in this tutorial as well. (Setting up TeamCity is outside the scope of this tutorial, but it is fairly easy to do. Grab it from jetbrains.com). TeamCity 5 should support Cucumber out of the box but I haven’t been able to make it work. Cucumber/ANT docs for TeamCity suggests that a few environment variables should do the trick for ANT/Java builds but this doesn’t work for Cuke4Nuke. The Cucumber Teamcity template uses a deprecated API and fails to build with the latest Cucumber version, and the only other blog post I found on TeamCity and Cucumber uses the same (broken) API. However, Cucumber can export a JUnit XML test report file, which is more than enough to get us nicely integrated with TeamCity (even with the previous versions). We’ll make Cucumber save the test results into the test subfolder of our project folder, and tell TeamCity to monitor that. First, let’s change the .csproj project file. Modify the PropertyGroup block you just added to the following:
<PropertyGroup>
<PostBuildEvent>cuke4nuke $(TargetPath) $(ProjectDir)features -q
-f junit -o$(ProjectDir)test</PostBuildEvent>
<PreBuildEvent>del $(ProjectDir)test\*.xml</PreBuildEvent>
</PropertyGroup>
This will save test output in the JUnit format (-f junit) into the test subfolder of our project directory (-o$(ProjectDir)test). It will also delete any previous test results from that folder when the build starts. Now set up your TeamCity project as normal. On the Build Runner configuration screen, select “ANT Junit” in the “XML Report Processing” section and set the import path as test/*xml (if you are working without a version control system, this will probably have to be a full path to your project folder rather than a relative path):
Everything should now be set up. You should be able to run the TeamCity build and get the “Tests passed:1″ message in TeamCity.
That’s it. Now continue writing feature specifications and implementing them in nice little iterations. Good luck! If you’re interested in this topic, you might also be interested in my new BDD with Cucumber workshops.
- BDD in .NET with Cucumber part 2: Making scenarios easier to read with tables
- BDD in .NET with Cucumber part 3: Scenario outlines and tabular templates
- Download source code
![]() |
![]() |



Thanks for the great tutorial, Gojko.
One note for your readers: If you use the new Ruby installer, you have to install the development kit per the instructions here: http://wiki.github.com/oneclick/rubyinstaller/development-kit. This gives gem the ability to build native extensions, which Cucumber’s dependencies need. (This extra step is why I haven’t changed the Cuke4Nuke wiki to recommend the new installer yet.)
[...] BDD in .NET with Cucumber, Cuke4Nuke and TeamCity – Gojko Adzic runs through the setup and workings of a Behaviour Driven Development environment for .NET Projects using Cucumber, Cuke4Nuke and the TeamCity CI server. [...]
I’m getting a Gem::GemNotFoundException when I run the “gem install cuke4nuke”
Richard, will the development kit install solve this?
You need to add gemcutter to the list of your gem sources
Hi Gojko. Thanks for the quick response.
Thanks for this post, too. It has inspired me to finally try cuke4nuke. I’m looking forward to getting past this little snag.
Yes, I did add gemcutter as instructed in the post and got confirmation that it was added to sources. However, I still get:
ERROR: While executing gem … (Gem::GemNotFoundException)
Could not find cuke4nuke (> 0) in any repository
BTW installing the development kit didn’t help this issue (but you knew that
.
I’m running:
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
gem 0.9.4
Any other thoughts?
Problem is with my gem install. I can’t install any gems and I can’t even query gems. I’ll post back if/when I solve.
Thanks.
OK. Got it working using Ruby 1.8.6-p383 (RC1). Thanks Gojko.
Next issue is that the modification to the .csproj file is not producing any results in the output window.
Randy – Sorry you had an issue installing Cuke4Nuke. I’ve seen this a couple times with the older Ruby installer but I’m not sure why it only happens for some people. The fix is what you discovered: use the new Ruby installer, including the dev kit.
The cukes Google group is the best place to post Cuke4Nuke questions. There are several people there who can respond, and the answers will help others who have the same issues in the future.
Thanks,
Richard
Hi
Great article, I have wanted to try cucumber with dot net, and having tried with Iron Ruby with little success I liked the sound of this solution.
however everyting is installed correctly, but when I run the initial cuke4nuke bin\debug\…. etc, I get a message box saying the servier has stopped with a problem and an in error,
any ideas, as I am new to the whole ruby enviroument, and still hacking my way around
Thanks
Duncan
ok solved the first problem, with the win32console, this is a known (bug) with 1.9 version of ruby, simply adding the line
# encoding: ISO-8859-1
to the ansi.rb and deleting or renameing Console.so as detailed at
http://rubyforge.org/tracker/index.php?func=detail&aid=23987&group_id=157&atid=691
now I am getting a server timeout error when I run the command line! any thoughts anyone
Thanks
Duncan
Getting same issue as everyone else (unable to connect to wire server is the message I get in the console session) – though tests did run first time.
ansi.rb fix did not work on my work machine
I also was getting the “unable to connect to wire server” error. I had to explicit start the server process at %RUBY_HOME%\lib\ruby\gems\1.8\gems\cuke4nuke-0.3.1\dotnet\Cuke4Nuke.Server.exe.
Still after doing this, each time I run I get a dialog box which states, “Server has encountered a problem and needs to close.” Any way to make this go away?