SpecFlow Step Definition with Optional Parameter

by Oliver13. May 2013 11:41

Today, this question came up on the SpecFlow Google Group:

Assuming I would like to define in Gherkin the following:

1. When I send some argument xxx with parameter aaa and another parameter bbb

2. When I send some argument xxx with parameter aaa

And I would like to have only one reusable function, something like this:

[When(@"I send some argument (.*) with parameter (.*) and another parameter (.*)")]

public void foo(string arg, string paramA, string paramB)

{

  // check if paramB is null and do something

}

I am aware of the table feature (pipe separated values) but I would like to stick with this text-alike syntax.

We've encountered this use case several times in the past (also avoiding the table syntax) and used to solve it by delegating the shorter version to the longer one but I decided to go see if I can find a more elegant solution.

Matching the steps

The first step at matching both steps was to simply match the first step. Since version 1.9 SpecFlow has this wonderful syntax highlighting in .feature files which helps identify unbound steps:

image

We can see, that our first pattern is too greedy and matches the second step but not the way we need.

Changing the regular expression for the first parameter to something more restrictive, allows us to restrict the match to only the first step (notice that the second step has been colored purple to notify us of the fact that there is no matching step definition, yet):

image

The regex ([^ ]*) we use here means that we match all characters that are not spaces 0 to n times, thus denying the match of the second step because of the space character following the argument aaa. Sometimes, though, you also need to match spaces in arguments and that's when we use a slightly modified version like this:  "([^"]*)"  which means: match a quote, then match everything but a quote 0 to n times and save this match as a reference, and then match another quote. In a verbatim string (prefixed by the @ sign) this will look like this:

image

Note, that now you'll have to enclose your spaced string value in quotes, though, but you can still use the same method to put that step attribute on.

Now, let's go for the second argument.

Using a .NET Optional Parameter

My first try was to add an optional parameter to the method we already have and provide it with a default argument like this:

image

Unfortunately, SpecFlow complains that for the first step with only one argument the matching method needs to have only one parameter. I thought that the compiler would generate two methods here, one with and one without the optional parameter so that at runtime it could pick the right one depending on which parameters were provided with a  value. It turns out that this is not so. Seems that IL code for a method with optional parameters contains only one method, as well, as per this article:

Intermediate language for optional parameter method: IL
.method private hidebysig static void Method([opt] int32 'value', [opt] string name) cil managed
{
.param [1] = int32(1)
.param [2] = string('Perl')
.maxstack 8
L_0000: ldstr "value = {0}, name = {1}"
L_0005: ldarg.0
L_0006: box int32
L_000b: ldarg.1
L_000c: call void [mscorlib]System.Console::WriteLine(string, object, object)
L_0011: ret
}
That's why SpecFlow complains.

Solution: Use Two Methods

It looks like there is not direct solution to the problem that would require only a single method. The solution we employ seems to be all you can do about it, at least right now with SpecFlow 1.9. Which would be to use (at least) two separate methods, one of which delegates its execution to the other, more general one:

image

Happy spec'ing!

Revoke Access to Applications using Google OpenID

by Oliver9. May 2013 12:20

During automatic frontend testing, some of our tests recently broke, which were trying to connect a Google account to our new TeamReview application using OpenID. Those tests used to make sure that on Google's confirmation page the checkbox to remember my choice was unchecked. I'd like to show a screenshot of what it used to look like, but unfortunately, it seems as if that old page has died.

On the new confirmation page, no such checkbox is available. This means that during a test run I cannot temporarily accept access to our application and later revoke that access by simply deleting my Google cookies.

I now have to go to Google's Authorizing Applications & Sites page and revoke access manually.

Just for the record.

Sport frei – Spartakiade 2013

by Anton25. March 2013 15:56

Letzten Samstag fand in Berlin-Kreuzberg die zweite Spartakiade statt. Es kamen etwa 50 Interessierte zusammen, die an den Workshops teilnehmen wollten.

Domain-Driven Design (DDD)

Da der Architekturworkshop erst am Nachmittag anfing, schaute ich am Vormittag in DDD rein. Es dauerte eine Weile bis an jedem Tisch die Beispielanwendung (brownfield) zum Laufen gebracht wurde. Es war ein Fahrrad-Online-Shop, den wir zunächst begutachteten. Wir arbeiteten die Bestandteile der bestehenden Software heraus. Danach definierten wir die Domäne und die Subdomänen (Aspekte) der Anwendung. Dabei sollte uns klar werden, was die Kernkompetenz des Programms sein würde, also worauf wir uns konzentrieren würden. Das war der Shop an sich (samt Warenkorb). Dinge wie Bezahlung und Versand würden Nebenaspekte bleiben, da wir sie möglicherweise auch auslagern könnten, oder bestehende gute Lösungen finden würden.

Architektur

Nach dem Baguette zum Mittag ging ich dann zum Architekturworkshop bei Sergey Shishkin. Ich weiß also nicht, wie der DDD-Workshop ausging, aber sie wollten sich am Nachmittag mehr um die Umsetzung konkreter Patterns in Zweierteams kümmern.

Sergey erzählte zunächst ein wenig darüber, wie er sich Architektur vorstellt. Dann sollten wir eine Grafik für eine Anwendung erstellen. Das war eine Vermisste-Tiere-Anwendung, in der man auch Sichtungen melden könnte. Innerhalb von 30 Minuten stellten wir etwas fertig, was die Funktionalitäten und Datenflüsse beinhaltete. Wir waren uns sehr unsicher, ob dies das Richtige sei. Immerhin sollten wir aus dieser Grafik ableiten, was für Kosten (insbesondere laufende) auf den Kunden zukämen.

Nach der Besprechung des ersten Fallbeispiels, gab uns Sergey ein komplexeres Problem, welches ich jetzt hier im Einzelnen nicht besprechen werde. Auch hier zeigten alle Gruppen unterschiedliche Ergebnisse, wobei wir kaum über die strukturierte Erfassung der Usecases hinauskamen.

Als letztes zeigte uns Sergey, wie man am besten mit solchen komplexen Anforderungen umgeht: indem man iterativ vorgeht. Man nimmt erst einen Usecase und modelliert ihn, und fügt dann nach und nach die weiteren Usecases hinzu. Dadurch muss man nicht die Gesamtanwendung auf ein Mal verstehen.

Fazit

Insgesamt hat sich die Teilnahme gelohnt. Ich hätte mir gewünscht, dass Sergeys Workshop den ganzen Tag gedauert hätte, so wie es eigentlich auch gedacht war. Die Workshopplanung könnte die Organisation ein wenig verbessern. Die Räumlichkeiten waren gut, das Catering auch. Die Stimmung war auch sehr angenehm, wie beim Developer Open Space.

enjoyed the post?

Tags:

Sport frei – Spartakiade 2013

by Anton25. March 2013 15:56

Letzten Samstag fand in Berlin-Kreuzberg die zweite Spartakiade statt. Es kamen 30 bis 40 Interessierte zusammen, die an den Workshops teilnehmen wollten.

Domain-Driven Design (DDD)

Da der Architekturworkshop erst am Nachmittag anfing, schaute ich am Vormittag in DDD rein. Es dauerte eine Weile bis an jedem Tisch die Beispielanwendung (brownfield) zum Laufen gebracht wurde. Es war ein Fahrrad-Online-Shop, den wir zunächst begutachteten. Wir arbeiteten die Bestandteile der bestehenden Software heraus. Danach definierten wir die Domäne und die Subdomänen (Aspekte) der Anwendung. Dabei sollte uns klar werden, was die Kernkompetenz des Programms sein würde, also worauf wir uns konzentrieren würden. Das war der Shop an sich (samt Warenkorb). Dinge wie Bezahlung und Versand würden Nebenaspekte bleiben, da wir sie möglicherweise auch auslagern könnten, oder bestehende gute Lösungen finden würden.

Architektur

Nach dem Baguette zum Mittag ging ich dann zum Architekturworkshop bei Sergey Shishkin. Ich weiß also nicht, wie der DDD-Workshop ausging, aber sie wollten sich am Nachmittag mehr um die Umsetzung konkreter Patterns in Zweierteams kümmern.

Sergey erzählte zunächst ein wenig darüber, wie er sich Architektur vorstellt. Dann sollten wir eine Grafik für eine Anwendung erstellen. Das war eine Vermisste-Tiere-Anwendung, in der man auch Sichtungen melden könnte. Innerhalb von 30 Minuten stellten wir etwas fertig, was die Funktionalitäten und Datenflüsse beinhaltete. Wir waren uns sehr unsicher, ob dies das Richtige sei. Immerhin sollten wir aus dieser Grafik ableiten, was für Kosten (insbesondere laufende) auf den Kunden zukämen.

Nach der Besprechung des ersten Fallbeispiels, gab uns Sergey ein komplexeres Problem, welches ich jetzt hier im Einzelnen nicht besprechen werde. Auch hier zeigten alle Gruppen unterschiedliche Ergebnisse, wobei wir kaum über die strukturierte Erfassung der Usecases hinauskamen.

Als letztes zeigte uns Sergey, wie man am besten mit solchen komplexen Anforderungen umgeht: indem man iterativ vorgeht. Man nimmt erst einen Usecase und modelliert ihn, und fügt dann nach und nach die weiteren Usecases hinzu. Dadurch muss man nicht die Gesamtanwendung auf ein Mal verstehen.

Fazit

Insgesamt hat sich die Teilnahme gelohnt. Ich hätte mir gewünscht, dass Sergeys Workshop den ganzen Tag gedauert hätte, so wie es eigentlich auch gedacht war. Die Workshopplanung könnte die Organisation ein wenig verbessern. Die Räumlichkeiten waren gut, das Catering auch. Die Stimmung war auch sehr angenehm, wie beim Developer Open Space.

enjoyed the post?

Tags:

Updating Orchard after a long time

by Anton22. March 2013 19:18

Until today we used the CMS Orchard for our homepage. Two years ago we used Orchard version 1.2. Since than we did not update once. Today we updated to version 1.6.

It is not that difficult:

  1. I updated my local version of our site (pulling from our git repository).
  2. I used the “Upgrade Site In-Place” instructions on that local copy.
  3. After that the site was not accessable. Also not the admin dashboard. Here is the bug I got:
    Orchard.OrchardException: Error while loading extension 'Orchard.Lists'. ---> System.TypeLoadException: Inheritance security rules violated while overriding member: 'Orchard.Core.Dashboard.AdminMenu.get_MenuName()'. Security accessibility of the overriding method must match the security accessibility of the method being overriden.
    I could not fix the bug other than deleting the module Orchard.Lists (simply by removing the folder in the Modules directory).
  4. After that only the admin panel works, but that is expected because Orchard 1.4 introduced breaking changes, which can easily be fixed with this instruction.
  5. Then I pushed all the changes to the repository.
  6. I cleared the bin and dependecies folders in the live site.
  7. Our TeamCity configuration then took the changes from the repository and applied them live.
  8. Again there was the bug from step 3. Again I deleted the Orchard.Lists module. But then I got the same bug for Orchard.CodeGeneration. I fixed that by adding the following line to the Assembly.Info of the Orchard.CodeGeneration Project:
    [SecurityRules(SecurityRuleSet.Level2)]
    See this discussion: http://orchard.codeplex.com/discussions/394726
  9. Then I fixed the breaking changes again with step 4.

It took me some trial and error to fix the bug, because at first I did not want to remove the module. But you should not be afraid to remove a module. You can always download it afterwards and install its newest version.

enjoyed the post?

Tags:

Updating Orchard after a long time

by Anton22. March 2013 19:18

Until today we used the CMS Orchard for our homepage. Two years ago we used Orchard version 1.2. Since than we did not update once. Today we updated to version 1.6.

It is not that difficult:

  1. I updated my local version of our site (pulling from our git repository).
  2. I used the “Upgrade Site In-Place” instructions on that local copy.
  3. After that the site was not accessable. Also not the admin dashboard. Here is the bug I got:
    Orchard.OrchardException: Error while loading extension 'Orchard.Lists'. ---> System.TypeLoadException: Inheritance security rules violated while overriding member: 'Orchard.Core.Dashboard.AdminMenu.get_MenuName()'. Security accessibility of the overriding method must match the security accessibility of the method being overriden.
    I could not fix the bug other than deleting the module Orchard.Lists (simply by removing the folder in the Modules directory).
  4. After that only the admin panel works, but that is expected because Orchard 1.4 introduced breaking changes, which can easily be fixed with this instruction.
  5. Then I pushed all the changes to the repository.
  6. I cleared the bin and dependecies folders in the live site.
  7. Our TeamCity configuration then took the changes from the repository and applied them live.
  8. Again there was the bug from step 3. Again I deleted the Orchard.Lists module. But then I got the same bug for Orchard.CodeGeneration. I fixed that by adding the following line to the Assembly.Info of the Orchard.CodeGeneration Project:
    [SecurityRules(SecurityRuleSet.Level2)]
    See this discussion: http://orchard.codeplex.com/discussions/394726
  9. Then I fixed the breaking changes again with step 4.

It took me some trial and error to fix the bug, because at first I did not want to remove the module. But you should not be afraid to remove a module. You can always download it afterwards and install its newest version.

enjoyed the post?

Tags:

HTTP Error 500.19 - Internal Server Error: 0x8007007b Cannot read configuration file

by Oliver20. March 2013 15:24

While setting up a specification tests project for our new TeamReview tool, I was facing an HTTP 500.19 error when hosting our site in IIS Express. There are lots of questions on stackoverflow concerning this error, Microsoft has a whole page on it, but there is a whole bunch of suberrors that this error addresses.

Error 0x8007007b: Cannot read configuration file

Unfortunately, none of the above mentioned links contained or solved the specific error code I was seeing:

Error Code
   0x8007007b

Config Error
   Cannot read configuration file

Config File
   \\?\C:\Projects\_teamaton\teamreview\TeamReview.Specs\bin\Debug\..\..\..\TeamReview.Web\web.config

After some reading, trying, fiddling, it appeared to me that maybe the path to the config file somehow messed up IIS Express. I admit that it was at least a bit unusual to use the parent directory dots. But it came from my test harness code where I wanted to use relative paths and used Path.Combine() to do that:

var webPath = Path.Combine(Environment.CurrentDirectory, "..", "..", "..", "TeamReview.Web");

Pitfall: .. in path

Well, it turns out IIS Express didn't like it. Once I called it with a cleaned up path string, everything just worked:
"C:\Program Files (x86)\IIS Express\iisexpress.exe" /path:"C:\Projects\_teamaton\teamreview\TeamReview.Web" /port:12345 /systray:false

So, watch out for your physical path values when using IIS Express!

Use DirectoryInfo to navigate up your directory tree

To get the correct path without using absolute paths but also avoiding the .. I used the DirectoryInfo class:

var webPath = Path.Combine(
    new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.Parent.FullName, "TeamReview.Web");

HTTP Error 500.19 - Internal Server Error: 0x8007007b Cannot read configuration file

by Oliver20. March 2013 15:24

While setting up a specification tests project for our new TeamReview tool, I was facing an HTTP 500.19 error when hosting our site in IIS Express. There are lots of questions on stackoverflow concerning this error, Microsoft has a whole page on it, but there is a whole bunch of suberrors that this error addresses.

Error 0x8007007b: Cannot read configuration file

Unfortunately, none of the above mentioned links contained or solved the specific error code I was seeing:

Error Code
   0x8007007b

Config Error
   Cannot read configuration file

Config File
   \\?\C:\Projects\_teamaton\teamreview\TeamReview.Specs\bin\Debug\..\..\..\TeamReview.Web\web.config

After some reading, trying, fiddling, it appeared to me that maybe the path to the config file somehow messed up IIS Express. I admit that it was at least a bit unusual to use the parent directory dots. But it came from my test harness code where I wanted to use relative paths and used Path.Combine() to do that:

var webPath = Path.Combine(Environment.CurrentDirectory, "..", "..", "..", "TeamReview.Web");

Pitfall: .. in path

Well, it turns out IIS Express didn't like it. Once I called it with a cleaned up path string, everything just worked:
"C:\Program Files (x86)\IIS Express\iisexpress.exe" /path:"C:\Projects\_teamaton\teamreview\TeamReview.Web" /port:12345 /systray:false

So, watch out for your physical path values when using IIS Express!

Use DirectoryInfo to navigate up your directory tree

To get the correct path without using absolute paths but also avoiding the .. I used the DirectoryInfo class:

var webPath = Path.Combine(
    new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.Parent.FullName, "TeamReview.Web");

Test Driving AppHarbor – A Walkthrough and Review

by Oliver15. March 2013 20:50

For some time now, I've wanted to check out AppHarbor, a cloud service to host .NET applications that includes a build environment, executes tests and deploys successful builds to one or more app servers. They use Amazon's cloud computing infrastructure as their backend. The smallest package is free so there's no good reason not to check it out.

Getting my first application up and running

First, you need to Sign up, confirm the link in the confirmation email, and log in. This part took about 2 minutes. (Created a new KeePass entry with an uncrackable password on the way.)

Then, create an application, entering a name and the geographical region you want your application to be hosted at:

image

Once you're done with that, you can choose where your code is hosted – this assumes you version control your source code using e.g. BitBucket, CodePlex, or Git. They also have a solution for the situation where you don't host your code anywhere, using a built-in Git repository. I didn't use that option, though, since I have an account at GitHub.

image

Clicking on "Configure GitHub to deploy to AppHarbor" directs you to the GitHub logon screen (if you're logged out) where you simply sign in.

Now, the following dialog was a bit spooky:

image

What I read between the lines is something like: all your base are belong to us! I mean, it basically says that they can do to all of my projects … well, anything, really.

Since I didn't want to create a new account just to try out AppHarbor and, honestly, because I somehow felt that they wouldn't destroy all of my work, I clicked "Authorize app". Phew!

Remark: You might choose to use a different GitHub account for your deployments, using e.g. copies of your repositories locally where you just copy everything you need from your dev repo. Then you can grand AppHarbor access to that account without much ado.

Now, the AppHarbor app took over and I chose a repository for the application I created earlier:

image

Once I chose a repo for my first app, I got to see the first Build status message – here AppHarbor is building my app for the first time:

image

A few seconds after AppHarbor was done building, and testing, and deploying my app after I had clicked the Deploy button, my app was ACTIVE :-)

image

Under the Hostnames link I found that they had given it http://mathie.apphb.com/ and after a couple of seconds I saw my app online on AppHarbor.

That was easy – how about deploying a new version?

I'm quite surprised at how easy (and fast!) it was to get my first app up and running. For completeness, I wanted to check how AppHarbor would handle my pushing some changes to the master branch of my repo. Here we go:

image

The commit was picked up within seconds! Another click on Deploy gets the new version out there.

Remark: On their homepage they say that apps get automatically deployed once build and test runner finish successfully. This was not the case here, and I didn't find any setting to enable this. If you know how that works, please leave a comment.

Update: Looks like this works out of the box, you just need to wait a minute or two for their deployment agent to pick up the new version. I updated my app just now and it got deployed by itself :-)

Go back in time – it's easy, too

Now, this is a nice feature: you can deploy any version of your application with a click of a button! So, if for some reason, you discover that the new version has some flaw, go back to an older one:

2013-03-15_16h00_02

What else do they offer?

AppHarbor contains an add-on infrastructure and already offers several add-ons that you can install with your application. Most of them charge an extra monthly fee, some of them also offer a free plan.

There are mostly analytics add-ons and DB engines, including dedicated MS SQL Server, RavenDB, MySQL, a PostgrSQL flavor, and a few more.

Interesting platform with big ease of setup and a free plan

Should be good for any smallish app that you just want to set up and forget about! For $10/month you can also assign your own host names which makes this a viable solution. It saves you from installing and maintaining a separate build server with something like TeamCity or CruiseControl running and is also almost easier to set up. Where are you gonna host your next app?

Test Driving AppHarbor – A Walkthrough and Review

by Oliver15. March 2013 20:50

For some time now, I've wanted to check out AppHarbor, a cloud service to host .NET applications that includes a build environment, executes tests and deploys successful builds to one or more app servers. They use Amazon's cloud computing infrastructure as their backend. The smallest package is free so there's no good reason not to check it out.

Getting my first application up and running

First, you need to Sign up, confirm the link in the confirmation email, and log in. This part took about 2 minutes. (Created a new KeePass entry with an uncrackable password on the way.)

Then, create an application, entering a name and the geographical region you want your application to be hosted at:

image

Once you're done with that, you can choose where your code is hosted – this assumes you version control your source code using e.g. BitBucket, CodePlex, or Git. They also have a solution for the situation where you don't host your code anywhere, using a built-in Git repository. I didn't use that option, though, since I have an account at GitHub.

image

Clicking on "Configure GitHub to deploy to AppHarbor" directs you to the GitHub logon screen (if you're logged out) where you simply sign in.

Now, the following dialog was a bit spooky:

image

What I read between the lines is something like: all your base are belong to us! I mean, it basically says that they can do to all of my projects … well, anything, really.

Since I didn't want to create a new account just to try out AppHarbor and, honestly, because I somehow felt that they wouldn't destroy all of my work, I clicked "Authorize app". Phew!

Remark: You might choose to use a different GitHub account for your deployments, using e.g. copies of your repositories locally where you just copy everything you need from your dev repo. Then you can grand AppHarbor access to that account without much ado.

Now, the AppHarbor app took over and I chose a repository for the application I created earlier:

image

Once I chose a repo for my first app, I got to see the first Build status message – here AppHarbor is building my app for the first time:

image

A few seconds after AppHarbor was done building, and testing, and deploying my app after I had clicked the Deploy button, my app was ACTIVE :-)

image

Under the Hostnames link I found that they had given it http://mathie.apphb.com/ and after a couple of seconds I saw my app online on AppHarbor.

That was easy – how about deploying a new version?

I'm quite surprised at how easy (and fast!) it was to get my first app up and running. For completeness, I wanted to check how AppHarbor would handle my pushing some changes to the master branch of my repo. Here we go:

image

The commit was picked up within seconds! Another click on Deploy gets the new version out there.

Remark: On their homepage they say that apps get automatically deployed once build and test runner finish successfully. This was not the case here, and I didn't find any setting to enable this. If you know how that works, please leave a comment.

Update: Looks like this works out of the box, you just need to wait a minute or two for their deployment agent to pick up the new version. I updated my app just now and it got deployed by itself :-)

Go back in time – it's easy, too

Now, this is a nice feature: you can deploy any version of your application with a click of a button! So, if for some reason, you discover that the new version has some flaw, go back to an older one:

2013-03-15_16h00_02

What else do they offer?

AppHarbor contains an add-on infrastructure and already offers several add-ons that you can install with your application. Most of them charge an extra monthly fee, some of them also offer a free plan.

There are mostly analytics add-ons and DB engines, including dedicated MS SQL Server, RavenDB, MySQL, a PostgrSQL flavor, and a few more.

Interesting platform with big ease of setup and a free plan

Should be good for any smallish app that you just want to set up and forget about! For $10/month you can also assign your own host names which makes this a viable solution. It saves you from installing and maintaining a separate build server with something like TeamCity or CruiseControl running and is also almost easier to set up. Where are you gonna host your next app?

About Oliver

shades-of-orange.com code blog logo Oliver is a c#, mvc and jquery developer at teamaton

About Anton

shades-of-orange.com code blog logo Anton is a software developer at teamaton and head of finances