tdd
Generator pattern in C# .NET
Boo language has nice code pattern called Generator:
// Generator expressions are defined through the pattern:
<expression> for <declarations> in <iterator> [if|unless <condition>]
// Generator expressions can be used as return values:
def GetCompletedTasks():
return t for t in _tasks if t.IsCompleted
// Generator expressions can be stored in variables:
oddNumbers = i for i in range(10) if i % 2
This pattern simply creates some IEnumerable object via the syntax transformation. We can not have this sugar in C# yet, but that’s how we can leverage the concept:
// Simple syntax
var customerList = new List<Customer>();
for (int i = 0; i < 40; i++)
{
customerList.Add(new Customer
{
Name = "Customer_" + i
});
}
// generator + LINQ syntax
var customers = Generator.For(40).Select(i => new Customer
{
Name = "Customer_" + i
});
The power of simplicity
Answer to a comment by Jeremy Gray has started getting really long, so I’m putting the primary idea in a separate post.
As we all know, NUnit is one of the first unit testing frameworks for .NET. It is old, stable and quite conservative. At the same time, it’s feature set is inferior to the functionality provided by some newer frameworks (or even frameworks for handling unit testing frameworks, like Gallio).
However, I’m still trying to stick to NUnit in my projects. Reasons for that are:
- It does not make reading tests challenging for new devs (unit tests are normally point of entry into the code, if they are present)
- Unit tests are often considered to be usage samples for the code they test. We’d prefer to keep these simple, would not we?
- The most important reason for me: simple unit testing framework forces developer to write unit tests that are easily testable (just like TDD forces some good logical separation between the components)
Imagine some really complex method that accepts quite a number of arguments and performs some black-box magic inside. If you have a data-driven unit testing framework at hand, you can simply create CSV file with valid entries and test this method against that. But if you do not have this functionality at hand, then you’d need to refactor the method to make it more simple and testable.
I like the last scenario. Even if it is not fun at the very start, it does pay off in the long term.
NUnit introduces the concept of row tests
Latest version of NUnit unit-testing framework for .NET has finally got support for the row tests. They are implemented by Andreas Schlapsi as an extension that now comes bundled with the NUnit 2.4.7.
Basically, row test is a test that could be run multiple times with different parameters (in other words, it is a simple data-driven test, where the data is provided by the attributes). Consider the following C# code snippet:
[TestFixture]
public sealed class Test_InterceptorCompiler : DslTests
{
[RowTest]
[Row("Chained Interceptions.boo")]
[Row("ConsoleWriter.boo")]
[Row("IWriter.boo")]
[Row("Multiple Classes.boo")]
[Row("Complex Writer.boo")]
public void Interception_Dsl_Compiles(string name)
{
var step = new InterceptorCompilerStep()
.Intercept<ComplexWriter>()
.Intercept<ConsoleWriter>()
.Intercept<IWriter>();
CompileDslToMemory(step, name);
}
}
Upon the execution in the NUnit GUI it will produce the following output:

Note, how every Row is treated as a separate unit test, and you can see which parameters have caused the failure.
Disadvantage of this new feature of NUnit is - JetBrains test runner (it comes with the R#) does not recognize them, yet. You would need to fire up NUnit GUI or use some other VS integration like TestDriven.NET in order to “run this test from the code”.
PS: there is an interesting podcast on the topic - The Past, Present and Future of .NET Unit Testing Frameworks.
Search
Archives
Recent Comments
- aCoder on Extension methods for interfaces
- Requirements for the Photon .NET project | Rinat Abdullin on IRepository, cross-cutting concerns and flexibility
- Nicholas Blumhardt on Extension methods for interfaces
- aCoder on IRepository, cross-cutting concerns and flexibility
- Rinat Abdullin on Blog upgraded
- Rinat Abdullin on Extension methods for interfaces
- IRepository, cross-cutting concerns and flexibility | Rinat Abdullin on Extension methods for interfaces
- Bill Pierce on Blog upgraded
- aCoder on Extension methods for interfaces
