"Working on the complexity that is always indirectly implied by simpilicity."

Gallio and Mb-Unit release v3.0.4

You can find many of the new features over at Jeff Brown's blog.  Some of the cooler features of note is the integration with the visual studio testing system, wrapping testing for exceptions into a delegate, and data store called Ambient, in which you can store state for your tests.  I've integrated this into amplify which is again, now on GitHub. I did run into a few lil issues when setting this up though....

The biggest issue was finding out how to turn a project into a test project in order to get the visual studio integration working for Gallio. Basically you need to make modifications to the .csproj file and add an XML element of <ProjectTypeGuids> into the first <PropertyGroup> of the file. 

<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};
{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 
</ProjectTypeGuids>

After this, I could get the Gallio tests showing up in visual studio.

Gallio-Test-View

Now this coupled with really helps with the testing process especially since with certain versions of Visual Studio, Test Driven .Net will let you run visual studio's code coverage with Gallio.

CodeCoverage

Again, one of the cooler features was the improvements to Mb-Unit's Asserts (which did change the API, but its all good, cause I wrap the Asserts that I use in BDD style mixin Methods, so I just need to change them in one place). The one really change of note would be adding Assert.Throw and Assert.Throw<T>, to which you can wrap throwing an exception into a delegate.

WrappingExceptions

All in all nice improvements to both Gallio and Mb-Unit, which are now incorporated into amplify.

Labels: , , , , , , , , ,

Gallio & Mb-Unit 3 With BDD style tests, I mean specs

Only sky is the limitBDD, Behavior Driven Development, is basically a fusion of Domain Driven Design and Test Driven Development (what is with you developers and your love for acronyms, I'll never know, maybe it comes from developing software in the government sector?). The basic premise has to do with business value of handing over code that is maintainable and readable specific to their domain, versus an over all process/methodology change like going from Agile to Waterfall. Granted projects like Rspec have added much to the overall terminology that Dan North first came up with (Given, When, and Then). BDD is an attempt at having a Domain Specific Language for code and having a mechanism that supplies the company, business, client, or whoever that must maintain that application, with what the application "should" do given in a certain context, i.e. specifications written in code.

Following to what I previously posted on the OSC blog...with ramping up .net for BDD, and spending time working with and MB-Unit 3.0, and time in thought about BDD in general and how it relates to .Net, I've come to some conclusions as I want to set the standard for writing tests/specifications for both Amptools and .

The obvious one is, c# is not ruby. can add keywords to ruby since ruby is a dynamic language and you can pre parse a file that is code, then execute it. C# is heavily tied to the default IDE Visual Studio for most developers and it would be a pain to create your own keywords, but at the same time, typing long sentences and having underscores in your method names that should be Pascal cased according to MS standards is just ugly.

Gallio makes good use of meta Attribute tags such as Mb-Unit's AuthorAttribute, CategoryAttribute, and TestsOnAttribute. Gallio's GUI client, Icarus, lets you sort by these attributes for running tests. The DescriptionAttribute however is only visible when running the reports, though it would be nice if it were readable/visible in the GUI as well.

Rspec has a "Describe" keyword that basically encapsulates description for a spec, which is often related to a class somewhere else. You can rename the TestsOnAttribute to become "Describe" and now you can categorize all your specs/tests that tests on a certain class. You can also Describe something in different contexts, to which the DescriptionAttribute can help you describe in what context you are using writing this specification for, which would replace the nested "describe" keywords in rspec.

Obvious Replacements would be renaming FixtureSetupAttribute to "BeforeAll" for Rspecs "before(:all)", FixtureTearDownAttribute to "AfterAll", SetupAttribute to "BeforeEach", and TearDownAttribute to "AfterEach". Rename the TestAttribute to "It", DescriptionAttribute to "Should", AuthorAttribute to "By", and CategoryAttribute to "Tag" (since we're in that web 2.0 tag everything phase.

What you might end up with is something below, which is a code specification for a "ValidatePresence" class which comes from a localized prototyping version of Amplify that I have on my local drive.

namespace Amplify.Data.Validation
{
	#region Using Statements
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Text;

	using MbUnit.Framework;

	using Describe = MbUnit.Framework.TestsOnAttribute;
	using InContext = MbUnit.Framework.DescriptionAttribute;
	using It = MbUnit.Framework.TestAttribute;
	using Should = MbUnit.Framework.DescriptionAttribute;
	using By = MbUnit.Framework.AuthorAttribute;
	using Tag = MbUnit.Framework.CategoryAttribute;
	#endregion
	
	[
 		Describe(typeof(ValidatePresence)),
 		InContext("should validate the presence of a value."),
 		Tag("Functional"),
 		By("Michael Herndon", "mherndon@amptools.com", "www.amptools.net")
	]
	public class ValidatePresenceObject : Spec
	{
		[It, Should(" have a public default constructor. ")]
		public void InvokeConstructor()
		{
			ValidatePresence obj = new ValidatePresence();
			obj.ShouldNotBeNull();
  			obj.RuleName.ShouldBe("ValidatePresence");
		}

		[It, Should(" validate the value passed to the object. ")]
		public void ValidateValue()
		{
			ValidatePresence obj = new ValidatePresence();
			obj.DefaultValue = "";
			obj.Validate("").ShouldBeFalse();
			obj.Validate("Has Value").ShouldBeTrue();

			obj.If = (value) => !string.IsNullOrEmpty((value as string));
			obj.Validate("").ShouldBeTrue();
		}
	}
}

In case you are wondering where all the ".Should" methods are coming from, they are c# extension methods that I've created that are stemmed from Assert methods found in the typical testing library such NUnit or Mb-Unit. I was using NBehave for the extension methods, but I didn't care for the tight coupling with Rhino Mocks, especially when I'm going to be using Moq as the Mock Object Library.

Now in Icarus, I can sort by TestsOn, Category and Namespace, and in the Reports generated by Gallio, I get all the above, plus the Description. Sooner or later, it would be wise to add a plugin to Gallio to generate a specification type of report, that would generate specifications for anyone would wanted to use Amplify or Amptools.

currently listenting to.. D12 on Devil's Night performing Purple Pills

Labels: , , , , ,