The past few days, I’ve been working on getting a Mono-environment up and running in Ubuntu 11.10. The reason for this is that I have two projects I believe would benefit greatly from being able to run on Mono. I also reckoned this would be a perfect time to refresh my Linux knowledge, learn something new, and have some fun. My requirements were pretty basic, and they were as following:
- Use latest stable Ubuntu
- Use latest Mono and MonoDevelop
- Use SpecFlow for my scenario tests
- Use NUnit for my unit tests
I started on these requirements, trying to solve them one-by-one. But after having tons of issues, especially getting my tests to run with the latest version of MonoDevelops NUnit integration, I shouted out my frustration on twitter. That’s when Greg replied with the following message:
Yes, why didn’t I even think of that? I’ve used Mighty Moose with Visual Studio before, while working on some small projects, and it’s a great product. Also, I actually knew there was a cross platform standalone client available. Silly me! The first thought I had; Why even bother getting MonoDevelop’s NUnit integration to work, since that has only been failing me so far! Instead, let’s go all-in for the Mighty Moose approach!
I quickly extended my requirements
- Use Mighty Moose to run all my tests. Continuously!
Getting these last three requirements running together wasn’t as easy as I first had hoped, and it took me a couple of evenings of resolving issues while trying to configure NUnit, SpecFlow and Mighty Moose! I thought perhaps others might be interested in how to get this working without spending the amount of time I did, hence I decided to write this blog post. I hope you will find it useful, but if not, at least it will be available to me the next time I need to configure a Mono-environment!
I created a VHD with VirtualBox and installed Ubuntu on it, which will allow me to boot Ubuntu natively, and use it as a VM. It took me some time to get it configured, and set up the way I want it, as it has been like 10 years since I last used any kind of Linux distribution for my desktop. I won’t go into depths of how to install Ubuntu, other than mentioning that I downloaded Ubuntu 11.10, installed it, and upgraded it with all the latest packages. There are tons of information on the internet about these things, go Google it if you get stuck here!
One thing worth mentioning though is that you should definitely install Compiz, which will help you resolve key-binding issues. If you are like me, and have a Visual Studio background, keys like F10 to -Step Over- while debugging is something you might not want to re-learn. Using Compiz you can resolve these issues with certain keys being assigned to functions in the Unity desktop, making them unavailable to applications like MonoDevelop.
Getting the latest versions of Mono and MonoDevelop
The Ubuntu repository provides older versions of Mono and MonoDevelop, but I wanted to get my hands on more recent versions. Badgerports.org is a repository that provides recent builds of Mono and MonoDevelop, as well as other related packages. Currently, they have MonoDevelop 18.104.22.168, which isn’t the cutting-edge-latest, but so far I find it rather stable, and it’s recent enough. To set up badgerports.org, please follow the steps here.
Caveat: Upgrading MonoDevelop may break MonoDevelop’s built-in NUnit test runner. This blog post will not deal with how to fix that issue, as we will use Mighty Moose to run all tests. If you rely on this integration, then don’t upgrade to MonoDevelop 2.8.
After you’ve setup badgerports.org according to the instructions. Open a terminal window and issue the following commands.
sudo apt-get update
sudo apt-get upgrade –t lucid mono-complete
sudo apt-get dist-upgrade
sudo apt-get install –t lucid monodevelop
There are other mono related packages you may want to install, but the above ones are enough to fulfill the requirements.
Installing SpecFlow at first seemed like a rather easy task, but confusion caused by weird crashing errors from SpecFlow’s generator threw me for a loop, a long loop. However, what for some time looked quite hopeless, did in fact have a quite easy solution. Here’s how to get it installed. Launch MonoDevelop and head into the Add-in manager under the Tools menu. Check the gallery and search for SpecFlow. You should find SpecFlow Support under IDE extensions. Mark it and click Install.
Now we need the latest SpecFlow binaries, download the zip archive from here (I used version 1.8.1). Extract the archive and head into the tools folder, and then execute the following commands to install all the required SpecFlow assemblies into the Mono GAC, and also make the command-line utility available by typing, yes that’s right: specflow
sudo gacutil –i Gherkin.dll
sudo gacutil –i IKVM.OpenJDK.Core.dll
sudo gacutil –i IKVM.OpenJDK.Security.dll
sudo gacutil –i IKVM.OpenJDK.Text.dll
sudo gacutil –i IKVM.OpenJDK.Util.dll
sudo gacutil –i IKVM.Runtime.dll
sudo gacutil –i TechTalk.SpecFlow.dll
sudo gacutil –i TechTalk.SpecFlow.Generator.dll
sudo gacutil –i TechTalk.SpecFlow.Parser.dll
sudo gacutil –i TechTalk.SpecFlow.Reporting.dll
sudo gacutil –i TechTalk.SpecFlow.Utils.dll
sudo mv specflow.exe /usr/bin/specflow
sudo chown root:root specflow
sudo chmod 755 specflow
Voila! SpecFlow can now generate code-behinds correctly in MonoDevelop! Also, remember to add a reference to TechTalk.SpecFlow.dll in your assembly containing your specifications.
As SpecFlow uses the NUnit framework, we now need to get NUnit running somehow.
Installing and configuring NUnit for Mono/.NET4
This was probably the most annoying part of it all. MonoDevelop’s NUnit integration is compiled against a certain version of NUnit, which it expects in the Mono GAC. When I actually got the correct version installed, MonoDevelop started throwing errors about needing an even earlier version of NUnit, sigh! I also got a bunch of weird errors that I didn’t actually know how to solve, like missing methods and classes within NUnit core, which also seemed like typical version issues. The other issue was that I just couldn’t get any NUnit test runner to run tests written in Mono/.NET4.
As I decided to use Mighty Moose, the solution was to break free from all test runners I’ve been trying to configure so far. Instead, to get Mighty Moose running our tests, we can focus on the nunit-console runner. If we get that working properly, we can configure Mighty Moose to use it.
NUnit may or may not be installed on your system, but issuing the following command will make sure you have it installed.
sudo apt-get install nunit
Then head into the configuration located at /usr/lib/nunit/, and edit the nunit-console.exe.config file. Just under the <configuration> tag, add the following lines:
And then add the following two lines under the <runtime> tag (the first one might already be there).
<legacyUnhandledExceptionPolicy enabled="1" />
<loadFromRemoteSources enabled="true" />
Now you should be able to use the nunit-console test runner on a Mono/.NET4 unit-test project.
Installing and configuring Mighty Moose
You have reached the last part of this guide, and hopefully you haven’t had any troubles so far. Mighty Moose is what will tie the knot, and I won’t keep you any longer. Download the cross platform standalone client and extract the files somewhere and head into that location, then issue the following commands:
sudo mkdir /usr/bin/continuoustests
sudo cp –R . /usr/bin/continuoustests/
find -name "*.exe"|sudo xargs chmod +x
sudo touch mightymoose
sudo chmod +x mightymoose
Now open the mightymoose file we just created in a text editor and paste these lines in it.
exec /usr/bin/mono /usr/bin/continuoustests/ContinuousTests.exe $(pwd)
Before we can move on, we need Mighty Moose to create a config file for us. Just issue these commands below, fill in the information and configure Mighty Moose to your liking. Also, remember to close Mighty Moose afterwards. (You may receive errors here, but just ignore them)
cd <your solution directory>
As already mentioned, we now need to switch test runner in Mighty Moose, and preferably use the nunit-console runner we got working with Mono/.NET4. Locate your AutoTest.config under ~/.local/share/MightyMoose/ and open it in a text editor. Add these tags within the <configuration> tag.
What these three lines do is, first switch of the built-in test runner, then tell Mighty Moose to use nunit-console for NUnit tests. The last line will allow Mighty Moose to be notified when you save files. So instead of having your tests run when you compile your solution, Mighty Moose will now run affected tests when you save a file.
Now we are done! Each time you want to start Mighty Moose, you can just issue the following two commands to start having continuous tests of your project.
cd <your solution directory>
If you have followed all the steps above, you should now have a working MonoDevelop environment, with MightyMoose running all your SpecFlow/NUnit tests, each time you save a file. I’ve been using this for a couple of days now, and it works great so far. Although, what I really miss now is my favorite isolation framework, FakeItEasy, as it sadly doesn’t work on Mono. But, Rhino.Mocks works right out of the box, and will do for now.
Last but not least
I want to send out my best regards to Svein A. Ackenhausen and Greg Young for their awesome 24/7 support while I’ve been working on this environment. Without your help this would have taken ages, had it succeed at all.
Continuous Tests (Mighty Moose)