thoughts on coding

March 26, 2010

StoryQ: scenario enhancements

Filed under: BDD, StoryQ, Uncategorized — Frantisek @ 11:04 am

Thankfully to Rob who inspired me from the comments in my previous post with the easy way how to create the scenario description from the test method name, I decided to share my StoryQ enhancements.

Rob wrote about using a StoryTestBase class with the property Scenario which creates the scenario with the text/name created based on the called method. I extended it little bit. My base class is called StorySpecBase and it contains a property

    1         protected virtual Scenario Scenario

    2         {

    3             get

    4             {

    5                 return WithScenario(StoryQHelper.ConvertTestMethodAsScenario());

    6             }

    7         }

and the helper class called StoryQHelper contains few methods which I use also in Run extension method, now.

    1         public static MethodBase GetTestMethod()

    2         {

    3             var trace = new StackTrace();

    4             for (int i = 0; i < trace.FrameCount; i++)

    5             {

    6                 var methodBase = trace.GetFrame(i).GetMethod();

    7                 bool isTestMethod = methodBase.GetCustomAttributes(true).Any(

    8                     attribute =>

    9                         {

   10                             var name = attribute.GetType().Name;

   11                             if (name == "TestAttribute" || name == "TestMethodAttribute") return true;

   12                             return false;

   13                         });

   14 

   15                 if (isTestMethod) return methodBase;

   16             }

   17             return null;

   18         }

   19 

   20         public static string GetTestMethodName()

   21         {

   22             var method = GetTestMethod();

   23             if (method == null) return null;

   24 

   25             return method.Name;

   26         }

   27 

   28         public static string Uncamel(string methodName)

   29         {

   30             return Regex.Replace(methodName, "[A-Z_]", x => " " + x.Value.ToLowerInvariant()).Trim();

   31         }

   32 

   33         public static string ConvertTestMethodAsScenario()

   34         {

   35             var methodName = GetTestMethodName();

   36             if (methodName == null) return "Nonamed scenario!";

   37 

   38             return Uncamel(GetTestMethodName());

   39         }

The method GetTestMethod uses StackFrames and it tries to find the caller with the attribute Test (Nunit) or TestMethod(MSTest) so I dont have specified fixed stack frame index.

All my tests are derived from StoryQSpecBase and I wrote the tests like:

    1         [Test]

    2         public void ShouldBuildNewStructure()

    3         {

    4             WithScenario("Building new structure")

    5                     .Given(TheModelContainsThaStructureDataWithId_, 0)

    6                     .When(BuildingANewStructure)

    7                     .Then(NewStructureIsFullyBuilt)

    8             .Run();

    9         }

The scenario is named the same way as the test method name :o), which is not very nice.

Now I write them as following:

    1         [Test]

    2         public void ShouldBuildNewStructure()

    3         {

    4             Scenario

    5                     .Given(TheModelContainsThaStructureDataWithId_, 0)

    6                     .When(BuildingANewStructure)

    7                     .Then(NewStructureIsFullyBuilt)

    8             .Run();

    9         }

Nicer, isn’t it? I avoided the string …

Advertisements

March 25, 2010

NBehave out, StoryQ in

Filed under: BDD, NBehave, StoryQ, TDD, Uncategorized — Tags: , — Frantisek @ 10:39 am

I use Behavior Driven Development (BDD) style of the development for last few years. Just for the explanation as I see BDD, BDD is Test-Driven development (TDD) with the description of the tests.

I used TDD in past but I found out that I wrote many comments in the code. Then I started to extract the commented code into the methods whose name was exactly that comment. BDD enables to translate the method names into the text and export that text while running the test. You can find very nice example of this here or exactly the steps I described here. Please note fluent style of the naming the methods and basically all the stuff.

By the way, you can read about the core BDD syntax here.

Until now we used NBehave to define the stories but … I think the biggest disadvantage of this library is the string-adidtive style.

    1          WithScenario("text ......")

    2                 .Given("a text describing give ", "arg", arg => {/* some code*/ })

    3                 .When("a text describing when operation", () => {/* some code*/ })

    4                 .Then("a text describing then operation with expectation", "expectation",  arg => {/* some code*/ })

In case of having 2 tests which share the same test step, i.e. …… it’s recommended (in order to follow DRY principle) to extract the code to the method and use this method in the test.

Example:

    1             WithScenario("text ......")

    2                    .Given("a text describing give ", "arg", TextDescribingGiven)

    3                    .When("a text describing when operation", () => {/* some code*/ })

    4                    .Then("a text describing then operation with expectation", "expectation", arg => {/* some code*/ });

    5 

    6             WithScenario("text 2......")

    7                    .Given("a text describing give ", "arg", TextDescribingGiven)

    8                    .When("a text describing when operation", () => {/* some code*/ })

    9                    .Then("a text describing then operation with expectation", "expectation", arg => {/* some code*/ });

   10 

   11        

   12         private void TextDescribingGiven(string arg)

   13         {

   14             /* some code*/

   15         }

It was usual that we changed the code in the step, so we changed the method name, too (using refactoring). But we were too lazy to change also the strings which described the step name. This resulted into wrongly named step decriptions => test description is useless. The developers have to follow very strict rules and you know how hard it is. This functionality was used in NBehave v0.3 and v0.4.

NBehave team released new version 0.4.5 which makes all the above mentioned usage obsolete and dictates us to write the stories in the external file in text form! and then map it (via strings!!!) against the  code! It’s strange step for me because many .NET community stuff tries to avoid using string (i.e. Expressions, etc.) This is hardcore step, I would say. I hate strings and it’s to avoid them as much as possible.  That was the reason why I tried to find out some another library which could create the step description from the method name (methods were named fluently) or we will try to write our own.

We used NBehave for 3 years and we tried to integrate them into NUnit tests with using Resharper to run the tests but …


WE ARE HAPPY THAT WE FOUND STORYQ!

StoryQ is another BDD library you can use to write the BDD tests but it has the following cooooooool features:

  1. step description is created from the method name, i.e. .Given(IHaveTypedMyCreditCardNumberIntoTheCheckoutPage) => translates to => Given I have typed my credit card number into the checkout page
  2. Nice posibility to add ParameterFormatAttributes
  3. Nice/painless integration into pure NUnit/MSTests testing => integrated into Resharper/VS.NET IDE
  4. Sexy exports into the reports (using XML, XSLT) nicely integrated with continous integration i.e. TFS build server
  5. amazing StoryQ Converter GUI which enables you to write the stories and translate them into the code – it creates testing code envelope!

Check all these features on their web. There is qood documentation.


My comments and enhancements to StoryQ
After using StoryQ for some time I found out that it would good (at least fro my point of the view) the following extensions/changes (we did few of them):

  1. we used to write 1 story in 1 class but with several scenarios. Each scenario is the separated test method. Because there are several strings (again used), I would suggest:
    • scenario description should be created based on the method name
    • story name could be created based on the whole class name

    This extentions/change could avoid using strings. The question is how this could be integrated into NUnit without any pain in order to get the textual representation of the tests.

  2. calling the method  .ExecuteWithSimpleReport(MethodBase.GetCurrentMethod()); we changed to .Run(); using the following extentions method:
  3.    11 public static void Run(this Outcome outcome)

       12         {

       13             StackTrace st = new StackTrace();

       14             outcome.ExecuteWithReport(st.GetFrame(1).GetMethod());

       15         }

  4. Empty String-typed arguments are displayed as ” – nothing – so I created EmptyStringParameterFormatAttribute:
  5.     5 public class EmptyStringParameterFormatAttribute : ParameterFormatAttribute     6     {     7         public override string Format(object value)     8         {     9             if (value != null)    10             {    11                 var str = value as string;    12                 if (str == null || str.Length != 0)    13                 {    14                     return value.ToString();    15                 }    16                 return "empty string";    17             }    18             return "{NULL}";    19     20         }    21     }
  6. It’s big shame that StoryQ Converter doesn’t use T4 templates to generate the code because it would be good to extend/change the default code generation which is currently hard-coded.
  7. It would be good if it would be possible to specify in StoryQ Converter also the argument names, i.e.  when building the shared component with $id:1 => could create a code (BuildingTheSharedComponentWithId, 1) and the method signature could be BuildingTheSharedComponentWithId(int id). It’s just a nice to have feature 😮

I must say StoryQ is really coool library with amazing Converter. Btw, it was really nice to read and know how SrotyQ team developed this library – usign Flit (Fluent Interface toolkit in conjuction with Irony and Dot/GraphViz) which is really coool way and it’s worth another blog posts.

That’s all for now …

March 11, 2010

StructureMap v2.6.1 released!

Filed under: .NET, Di Factory, StructureMap, Uncategorized — Frantisek @ 9:30 pm

There is new version of really usefull library used for DI, IoC – called StructureMap – released. You can find more about that new version on the blog from Jeremy Miller, here

Jeremy explains what was changed there and what’s new but … we miss the up-to-date documentation ….

It’s really cool library, we use it quite much on our projects and it’s really a killer against other similar libraries (I’ll write a post about it later).  I was looking forward to check the new version and use it but here are my comments:

1) API was changed quite massively and there were made obsolete many methods and few were removed. I must say, that the comments used on the Obsolete attribute are not usefull in all situations the old version was able to be used (see example bellow).

2) The release is missing an up-to-date documentation describing how to migrate from old version to the latest version. The migration to the new version is not very straightforward, IMHO. The package (binaries), which you can download from here contains only binaries ;o), no documentation, no tests (which can act as a kind of the document as well), etc.

Solution

I think the NUnit tests are very good source of the documentation and explanation how to use the explored library and it should be UP-TO-DATE. So for all who wants to migrate to new version of Structure and dont want to wait for the documention or Jeremy’s blogs I propose the following:

download the full package which includes also NUnit tests 😮 from here (scroll down and take the latest commit, it includes more than 11MBs of data) and spend some time with analyzing code and NUnit tests.

My feedback

I really support the libraries with Fluent approach. Structure map has it but I think, some changes, which should be more fluent in the newer version are less fluent now.

Example: AsSingleton() construct replaced with Singleton(), as following:

I think, more fluent version would be:

I think it’s more fluent. I must say it took me a while to find it out, especially when old construct was completely different with AsSingleton() at the end ;o  I know, my suggestion i’s small change, but I would say, it would bring more fluent voice.

Another, but I think, bigger change was related to situation when we want to add the named instances to the container. It’s connected to the class IInstanceExpression<T> and its OfConcreteType<PLUGGEDTYPE>() method like on the following:

The obsolete attribute advice what to use is nice but useless in the situation when we use AddInstances() construct.

In this case we are not able to avoid using OfConcreteType<T>(). There are 2 possible solutions:

The first is to use the For<T1>().Add<T2>.Named(“name”) like on the following picture:

OR

the old way which was used in 2.5.4 version:

and live with the fact that there will be warnings.

I checked the NUnit tests from StructureMap because I wanted to know how to use this construct correctly and I was disappointed that the there is used the OLD version of the solution (the obsolete methods with the warnings) like the following:

Summary

It’s a shame that the release 2.6.1 contains API changes but MANY NUnit tests uses old, Obsolete version of the API. So the documentation is not up-to-date nor the tests.

I think, the team shouldn’t change the API without changing the unit tests to use that new API and thus providing us a solution how to migrate from old  version to the new version.

Anyway, StructureMap is really nice library with many very useful features, going hand in the hand with TDD, Mocking, Plugins, etc. and the biggest advantage is the implementation of Convention over Configuration approach which is unique!

I hope Jeremy will have more free time to blog more about the newest version.

Blog at WordPress.com.