c#

For the love of…

This post is inspired from a code review with a colleague, covering the many ways we, as c# developers, can write code to simply call a method three times.

Simplicity

You want to perform an action three times. You could just call the statement three times

Console.WriteLine("Hello Reader");
Console.WriteLine("Hello Reader");
Console.WriteLine("Hello Reader");

Chances are, this may make you twitch a little. It’s not DRY and not very scalable – you might chose to do something like this

public void DoSomething(int count)
{
    for (int i = 0; i < count; i++)
    {
        Console.WriteLine("Hello Reader");
    }
}

What’s wrong with this? Nothing as far as the compiler is concerned and it will of course call your method three times (when a 3 is passed into the function). The picky part of me thinks this isn’t good enough though.
In particular, we wanted to call a method three times, so for this simple task why do we have to declare an integer? Why is it called ‘i’? Surely those days belong to the days of a fax machine?

C# is a pretty rich language. We can do better.

Who doesn’t love ForEach?

If I had a collection with three items, I could simply call ForEach, right?

private static void EnumerableRangeForEach(int count)
{            
    foreach (var number in Enumerable.Range(1, count))
    {
        Console.WriteLine("Hello Reader");
    }
}

Looks a bit better, but I don’t need an ordered collection of integers really, just a collection with (3) things in it. Like this:

private static void EnumerableRepeatForEach(int count)
{
    foreach (var item in Enumerable.Repeat(typeof(bool), count))
    {
        Console.WriteLine("Hello Reader");
    }
}

At least our code doesn’t declare an ordered integer array now; now we have a collection of three booleans. However, we still have the annoyance of needing to declare var item to please the for loops gods. We can do away with the named variable (ish) if we add in the additional expense of converting it to a List

  Enumerable.Repeat(typeof(bool), count)
                      .ToList()
                      .ForEach(item => Console.WriteLine("Hello Reader"));

Everyone loves a one liner. At least the author of it does, reading someone else’s isn’t always such a joy. My main concern is that we had to create a collection, then convert it to a list in order to iterate over it, using List’s .foreach extension.

Please the recursive gods

Many years ago, I had no beard and when not sleeping through lectures at university learnt to program, functionally. The lecturers in their wisdom thought functional programming was the way forwards and once upon a time I was proficient in ML (F# has some of its origins here) and Prolog. Naturally I used all these skills, when I started out as VB programmer after graduating…

I digress. Our desire to do something three times, can be written like.

private static void RecursiveLoop(int loopCount)
{
    if (loopCount == 0)
    {
        return;
    }

    Console.WriteLine("Hello Reader");
            
    var nextCount = loopCount - 1;

    RecursiveLoop(nextCount);
}

Granted this isn’t the smallest method here. On the plus side, we are not forced to declare an implicit collection and we don’t have any variables that aren’t doing anything explicit. You can of course argue that we are still declaring a variable (nextCount) to keep track of where we are, similar to our var number sacrifice earlier.

If you are unfamiliar with recursive functions, I should point out that failure to declare a base case (if loopCount == 0 in our case) that will always be hit, will result in a StackOverflow. Similarly in some circumstances if you’re are looking at doing thousands of recursive calls and you are using tail recursion, then current limitations with the c# compiler will also result in a stackoverflow. Lots of posts about this on the web, this one ain’t bad: http://volgarev.me/blog/62412678347

What’s best

As ever in computing, it depends should be the right answer. If the business case strongly suggests that you only ever need to call something three times and it’s unlikely to change, I can see a case for the non dry example at the top. Very efficient and easy to read and I’ve seen code bases a lot worse in terms of dryness.

More realistically, this number three is likely to be changeable, so you want a collection and the ability to iterate over it. Personally I like the style of the recursive function and have some negative opinions on for (int i = 0; i< upperBound; i++) – just seems so primitive and unimaginative. However, the compiler’s going to reduce them to basically the same thing so as long as your method is clean, easy to read and easy to test, it’s all good.

What’s your preference?

Performance

Of course there’s a big except to my last paragraph. Not all for loops are the same when you really need to squeeze your method and get it crunching 1000s and every nano second counts. I’ll cover this in my next post.

Advertisement

Write Less, Test More (part 2)

In my previous post I blogged about Xunit Theories, which provided a neat way to pass multiple test scenarios into one test method. Why I’m liking Xunit these days is due to its extensibility. In particular Adam Ralph and friends have extended it and come up with Xbehave.Net.

A popular pattern when testing is Given (my input), When (I test this), Then (expect this outcome). See Cucumber scenarios for more info. One of the problems with my last post is that the [Fact] didn’t use this language. The test output didn’t use this language. Wouldn’t it be nice if it did?

If we wrote that test with xBehave it would. This post revisits the problem from the first post and shows how we could test it using xBehave.Net.

Problem Recap

I want a class that, when given a sentence, will return a collection of strings containing all words in lowercase. This collection should only have alpha characters in it – i.e. spaces and punctuation are to be ignored.

To write our test for the zero case, using xBehave it could look like:

[Scenario]
public void FindWordsEmptyStringScenario(string input, IEnumerable output)
{
"Given an Empty String"
   .Given(() => input = string.Empty);

"When I find words in this string"
   .When(() => output = _wordFinder.FindAllWordsInLowerCase(input));

"Then I expect the answer to be an empty list"
   .Then(() => Assert.Empty(output));
}

Cucumber uses scenarios, so does our test. The test method, takes as its inputs an input and output variable. The method cleanly has three calls, each coming off a string describing the action:
Spelling it out, the Given() sets up our input variable.
When(), does the business of calling our method under test, returning the output, into our variable, called output.
Then(), asserts if the output is what we expected.

Talk about readable!

It gets better – run this through reSharper and our output looks like:

zero_xunit

Again very readable I think.

As I’m sure you guessed, this framework supports something very similar to Xunit’s [InlineData]. It has examples.

Our test scenario, with all example inputs and outputs, based on first blog, looks like

[Scenario]
[Example("", new string[0])]
[Example("One", new [] { "one" })]
[Example("One two", new[] { "one", "two" })]
[Example("One...:; - ,two", new[] { "one", "two" })]
public void FindAllWordsInLowerCaseScenario(string input, string[] expectedOutput, IEnumerable output)
{
    "Given the sentence '{0}'"
        .Given(() => { });

    "When I find words in this sentence"
        .When(() => output = _wordFinder.FindAllWordsInLowerCase(input));

    string.Format("Then I expect the answer to be [{0}]", string.Join(",", expectedOutput))
        .Then(() => Assert.Equal(expectedOutput, output));
}

What’s nice here is that if you remember the outputs from the InLine tests – it didn’t output the expected string arrays’ content. Here, as the method name that gets generated for the test runner output is simply a string we can manipulate the string to show the contents of the expected array.

all_xunit

Each example provided effectively creates a new scenario, which are grouped in the output by scenarioNumber.StepNumber.

For the output names to be neatly formatted here (without repetition of the input variables) we are setting the attribute [OmitArgumentsFromScenarioNames] on the class, which suppresses them.

Write Less, Test More (Part 1)

Just like my software development skills, my approach to writing tests over the years has changed, but it’s only recently I’ve started to use more than the basic Assert functionality of testing frameworks.

This post explains an approach I used to test a particular module that came about through TDD and how to test a number of scenarios, by writing just one test method.

The problem

I want a class that, when given a sentence, will return a collection of string containing all words. This collection should only have alpha characters in it – i.e. spaces and punctuation are to be ignored.

My tests

As I’m dealing with a collection I think it makes sense that my method should cope with an empty sentence, a sentence with one word and a sentence with n words. At least one of these n word sentences should be peppered with some non alpha characters.

A reasonable approach might be to setup my test class, then write my first test to test the ‘0’ case. This could look like:

[Fact]
public void GivenAnEmptyStringWhenFindAllWordsExpectAnEmptyList()
{            
    var expectedResult = new string[0]; 

    var result = _wordFinder.FindAllWordsInLowerCase(string.Empty);

    Assert.Equal(expectedResult, result);
}

(Where _wordFinder is the class under test. This test asserts that an empty collection is returned from FindAllWordsInLowerCase method).

Run the test – it’ll fail. Go off create a WordFinder class, with the method FindAllWordsInLowerCase(string input), write the code to return an empty string list

Re-run the test and hopefully the test will pass.

Great. Next test is the scenario with one word. Forget DRY; copy and paste previous test, rename it, change the inputs and expected output and rerun.

[Fact]        
public void GivenOneWordWhenFindAllWordsExpectOneItemInLowerCase()
{
    var expected = new List<string> { "one" };
            
    var result = _wordFinder.FindAllWordsInLowerCase(OneWord);

    Assert.Equal(expected, result);
}

Write some code to get this to pass, then, copy and paste test class again, alter inputs and expected outputs… you get the idea.

This will work and is an approach I’ve used for a while. The outcome is great – we’ll have a class with very high coverage that was developed just as our tests informed it. For me though, I prefer to be a bit more DRY than this.

Cue…. Xunit Theories

In a nutshell, an XUnit Theory, is a means to perform a data driven test. Data is provided in an [InlineData(…)] attribute. Each InlineData attribute applied to a Fact, will result in  a different test.

Define your test method and define your theory’s data and you can run multiple inputs and test the expected outcomes through a lot less methods – one in this case! Putting this into practice, our two previous tests now look like:

 [Theory]
 [InlineData("", new string[0])]
 [InlineData("One", new[] { "one" })]        
  public void FindAllWordsInLowerCaseTheory(string input, IEnumerable<string> expectedOutput)
  {
     var result = _wordFinder.FindAllWordsInLowerCase(input);

     Assert.Equal(expectedOutput, result);
  }

And when run with ReSharper, produces an output that looks like:

resharp21

Unfortunately it can’t output expectedOutputs cleanly when it’s a collection, but we have a test that’s DRY and easier to read from a non technical perspective. Potentially a non developer could even provide these inputs and outputs, lending itself to BDD very nicely.

You can also achieve a similar result with nUnit, using it’s [DataSource] attribute.

As we are using XUnit, I suspect it may be possible to modify the output behavior, so that it can display the expected collection of strings better. Not in scope for this post though.

So finally, when all our test scenarios are created our code looks like:

[Theory]
[InlineData("", new string[0])]
[InlineData("One", new[] { "one" })]
[InlineData("One, two", new[] { "one", "two" })]
[InlineData("ONE,4--;@@ ::tWo", new[] { "one", "two" })]
[InlineData("paulthecyclist tested; PaulTheCyclist failed @#$@! PaulTheCYclist Coded, paulthecyclist tested => PaultheCyclist passed!", new[] { "paulthecyclist", "tested", "paulthecyclist", "failed", "paulthecyclist", "coded", "paulthecyclist", "tested", "paulthecyclist", "passed" })]
public void FindAllWordsInLowerCaseTheory(string input, IEnumerable<string> expectedOutput)
{
    var result = _wordFinder.FindAllWordsInLowerCase(input);

    Assert.Equal(expectedOutput, result);
}

This produces five tests. I think it’s easier to read than having a test class with five separate methods and certainly less code to write/copy and paste.

There is an even more fun way to write your tests using XUnit though, which addresses the readability of the output along with other things, that I’ll cover in part 2.