Tags: ,

A tip: collect all cards from your Scrum board and at the end of project you will get such nice box full of warm memories =)

User Stories

Visual Studio Express does not support the test driven developers. The Express editions do not have any integrated testing framework like MSBuild and you cannot add-in one, as addins/plugins are disallowed. Also there is a limitation to attach the debugger to a process, so you cannot easily debug an external test runner like Gallio or NUnit.

Fortunately, there are some workarounds. Here is the summarized result of my research on the topic of running and debugging tests with Visual Studio Express.

  • To run tests you can
    • use a standalone test runner and execute it against an assembly with your tests;
    • configure the Visual Studio to execute a test runner through the Tools menu like Martijn Dijksterhuis suggested.
  • To debug tests you can
    • convert your test library project into console or Windows Form application and point it to your favorite test runner as it shown in Steve Dunn's blog post;
    • manually edit the project file to specify a test runner as external program in the Start Action for your test assembly in a similar way as Pål Fossmo or Jeremy Tammik described.

I prefer the last workaround, modification of the msbuild project file. The following piece of .csproj file allows me to integrate MbUnit test runner into Microsoft Visual C# 2010 Express.


<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  <DebugSymbols>true</DebugSymbols>
  <DebugType>full</DebugType>
  <Optimize>false</Optimize>
  <OutputPath>bin\Debug</OutputPath>
  <DefineConstants>DEBUG;TRACE</DefineConstants>
  <ErrorReport>prompt</ErrorReport>
  <WarningLevel>4</WarningLevel>
  <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
  <StartAction>Program</StartAction>
  <StartProgram>$(MSBuildProjectDirectory)\..\Tools\MbUnit\Gallio.Echo.exe</StartProgram>
  <StartArguments>$(MSBuildProjectDirectory)\$(OutputPath)\$(AssemblyName).dll /runner:IsolatedAppDomain /report-type:Text /show-reports</StartArguments>
  <StartWorkingDirectory>$(MSBuildProjectDirectory)\$(OutputPath)</StartWorkingDirectory>
</PropertyGroup>

The StartAction, StartProgram, StartArguments and StartWorkingDirectory are related to the Start Action feature hidden in the Express edition. The StartProgram specifies the console test runner, Gallio Echo; the StartArguments property includes what to test, and how to run the test runner (note the "/runner:IsolatedAppDomain" argument that allows to debug the tests) and report type.

It is also possible to use GUI test runner, Gallio Icarus. Just for debugging it is necessary to manually set the IsolatedAppDomain (Gallio Control Panel > Preferences tab > Icarus > Runner > Test Runner Factory) as it is not possible to specify through the command line.


<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  ...
  <StartAction>Program</StartAction>
  <StartProgram>$(MSBuildProjectDirectory)\..\Tools\MbUnit\Gallio.Icarus.exe</StartProgram>
  <StartArguments>$(MSBuildProjectDirectory)\$(OutputPath)\$(AssemblyName).dll</StartArguments>
  ...
</PropertyGroup>

Press F5 and enjoy this free solution.

Updates

  1. Removed spaces in XML values. (20.4.2011)

I have encountered an issue running a batch-file as administrator on Vista/Windows 7. Running a script with evaluated privileges, the system executes it under the System32 directory. It caused a wrong interpretation of relative paths in my script. Fortunately, there is an elegant solution to fix this issue.

In order to return to a directory the batch-file was run, it is enough to include the following command at the top of your script:

cd %~dp0

"%~dp0" contains a local path of executing file. The "Using batch parameters" article explains how it works.

Tags: , ,

Scrum is great in its flexibility. You are free to tune the process to best fit your needs. It is completely normal that the process is varying in different organisations and even in teams in the same organisation.

At my new work, we also use Scrum and I picked up one useful technique. At the beginning of each sprint retrospective meeting we draw a timeline of key events happened during the last sprint. The technique is especially useful in case of long sprints (like one month long in our case) and helps to remember what the team did, what good and bad happened during each week.

Tags:

Last Saturday about 50 people learnt something new at Knetlik conference. The conference was not about Czech cuisine, but about .NET; however, I believe, there are some analogies in the name with popular Czech food — knedlík.

The conference was very fast and full of caloric information. There were 10 short talks 10 minutes each! Such short talk is enough for the introduction and can spark good appetite to learn more.

The format of the conference was quite new for me, but it was not the last thing that surprised me. An organizer of the conference, Andrew Kazyrevich, managed to bring two virtual presenters: Patrick Smacchia (author of NDepend) and Gil Zilberfeld (technology evangelist at Typemock), whom were talking and presenting slides via Skype's screen sharing feature. Neat idea!

As a conclusion, I would like to say that Knetlik is definitely worth to attend next time.

I found myself a bit lazy programming another custom configuration section manually. To my surprise, quick googling brought really cool time-saver Visual Studio add-in —
Configuration Section Designer. In a nutshell, it allows:

  • Create a custom configuration section in a visual designer in Visual Studio. After you designed your configuration section, it is a matter of seconds to update it or even radically change the whole shape.
  • Access your custom configuration settings via generated strongly typed object model. The tool generates partial classes, so you can easily extend them with your code.
  • Use intelli-sense in Visual Studio while editing your custom configuration section in a .config file. It is possible, because the tool also generates a corresponding XSD schema for the configuration section.

Mike Taulty wrote a good introductory post about the Configuration Section Designer.

P.S. Sloth is stimulus to progress.

Tags: ,

If your team is not experienced in estimating in story points — try estimating in T-shirt sizes! =)

Working in agile team I found at the beginning it is quite difficult for some people to switch from estimating in man-days to estimating in story points. The main complexity is to understand two things:

  1. story points express the size, not duration;
  2. and the size is relative, not absolute.

If you notice, your team-mates say "story points", but they mean/discuss/refer to man-days/man-hours — it is time to give a try the T-shirt sizes. The technique is to abstract the numbers and instead use the terms like Small, Medium, Large, eXtra Large. As you can see the T-shirt sizes better correspond to estimation in relative size.

After such estimation session you can convert the sizes back to numbers and send to the business. Hope it will help.

If you belong to Microsoft camp and you have to deal with web services written on non-Microsoft technologies, there is a chance you get an error saying something like "Version number '1.1' is invalid. Line 1, position 16". The bad news is using MS technologies you cannot communicate with web services returning content in XML version 1.1

Microsoft does not support XML 1.1

One of possible workarounds is to convert xml response on the fly and you may find this article helpful.

If you are a decision maker and consider what version of XML to use, please read this short port and especially this long one, and also this thread.

The reality is you cannot create a web service that will be consumed on various platforms if your web service uses XML 1.1

It is 2010 now and while we are enjoying new presentation technologies like Silverlight, nobody can guarantee us we won't deal with more then three years old bugs in WinForms.

Recently I was working on one small desktop application that displays dynamically created content in the FlowLayoutPanel control. In some cases, when you add two controls and the first one has FlowBreak set to true, the FlowLayoutPanel can add unwanted space between the controls.

It seems the height of the gap is the same as the height of the second control following after the flow break. And the workaround to get rid of the gap is to add an additional panel of zero size just after the flow break.

I found this workaround in the Windows Forms General forum.

In my previous post I mentioned how to specify an association between POCO objects in RIA Services. In that post I did not mention that you will get an error as soon as you try to do some operations on associated objects. The error might look like this: "EntitySet of type 'Option' does not support the 'Add' operation".

There are two ways to solve the issue. First of all, it is necessary to decide what type of association you have. In case of composition you just need to use a new CompositionAttribute (read more in Mathew Charles' post):

// "Master" domain entity class.

public class Parameter {
    [Key]
    public long Id { get; set; }

    public string Name { get; set; }

    [Include]
    [Composition]
    [Association("Parameter_Options", "Id", "ParameterId")]
    public List<Option> Options { get; set; }
}

// "Details" domain entity class.

public class Option {
    [Key]
    public long Id { get; set; }

    public long ParameterId { get; set; }

    public string Name { get; set; }
}

If you do not have the compositional association, you have to specify operations in the corresponding domain service.

[EnableClientAccess]
public class ParametersDomainService : DomainService
{
    [Query]
    public IEnumerable<Parameter> GetParameters() { ... }
    [Insert]
    public void AddParameter(Parameter parameterWithOptions) { ... }
    [Update]
    public void UpdateParameter(Parameter parameterWithOptions) { ... }
    [Delete]
    public void DeleteParameter(Parameter parameterWithOptions) { ... }

    [Insert]
    public void AddOption(Option option) { ... }
    [Update]
    public void UpdateOption(Option option) { ... }
    [Delete]
    public void DeleteOption(Option option) { ... }
}

In the AddParameter, UpdateParameter and DeleteParameter methods you will receive the parameter object with associated options. It is up to you whether to perform operations on option objects together with operations on parameters or to do it in the corresponding methods. Note that AddOption, UpdateOption and DeleteOption should exist, but they could remain empty.