Showing posts with label NUnit. Show all posts
Showing posts with label NUnit. Show all posts

Sunday, 27 May 2012

Code Contracts

I started writing a blog post about Code Contracts that I believe will end up working its way into all future .NET software, particularly APIs.  Then I came across this excellent write up that I highly recommend:

http://devjourney.com/blog/code-contracts-part-1-introduction/

Code Contracts in action

using System;
using System.Diagnostics.Contracts;

namespace CodeContracts
{
public interface IRandomGenerator
{
int Next(int min, int max);
}

public class RandomGenerator : IRandomGenerator
{
private readonly Random _random = new Random();

public int Next(int min, int max)
{
return _random.Next(min, max);
}
}

public class Randomizer
{
private readonly IRandomGenerator _generator;

public Randomizer(IRandomGenerator generator)
{
_generator = generator;
}

public int GetRandomFromRangeContracted(int min, int max)
{
Contract.Requires<ArgumentOutOfRangeException>(
min < max,
"Min must be less than max"
);

Contract.Ensures(
Contract.Result<int>() >= min &&
Contract.Result<int>() <= max,
"Return value is out of range"
);

return _generator.Next(min, max);
}
}
}

The above code Post build

public class Randomizer
{
// Fields
private readonly IRandomGenerator _generator;

// Methods
public Randomizer(IRandomGenerator generator)
{
this._generator = generator;
}

public int GetRandomFromRangeContracted(int min, int max)
{
int Contract.Old(min);
int Contract.Old(max);
__ContractsRuntime.Requires<ArgumentOutOfRangeException>(min < max, "Min must be less than max", "min < max");
try
{
Contract.Old(min) = min;
}
catch (Exception exception1)
{
if (exception1 == null)
{
throw;
}
}
try
{
Contract.Old(max) = max;
}
catch (Exception exception2)
{
if (exception2 == null)
{
throw;
}
}
int CS$1$0000 = this._generator.Next(min, max);
int Contract.Result() = CS$1$0000;
__ContractsRuntime.Ensures((Contract.Result() >= Contract.Old(min)) && (Contract.Result() <= Contract.Old(max)), "Return value is out of range", "Contract.Result<int>() >= min && Contract.Result<int>() <= max");
return Contract.Result();
}
}


Unit tests with Moq and NUnit test cases

using System;
using Moq;
using NUnit.Framework;

namespace CodeContracts.Tests
{
[TestFixture]
public class Given_mocked_RandomGenerator
{
private Mock<IRandomGenerator> _randomMock;
private Randomizer _randomizer;

[SetUp]
public void Setup()
{
_randomMock = new Mock<IRandomGenerator>();
_randomizer = new Randomizer(_randomMock.Object);
}

[TestCase(1, 0)]
[TestCase(2, 1)]
[TestCase(100, 10)]
[TestCase(0, -1)]
[TestCase(-1, -2)]
[TestCase(-10, -100)]
public void When_min_is_greater_than_max_Then_should_throw_exception(int min, int max)
{
Assert.Catch<Exception>(() => _randomizer.GetRandomFromRangeContracted(min, max));
}

[TestCase(0, 0)]
[TestCase(1, 1)]
[TestCase(10000, 10000)]
[TestCase(-1, -1)]
[TestCase(-10000, -10000)]
public void When_min_is_equal_to_max_Then_should_throw_exception(int min, int max)
{
Assert.Catch<Exception>(() => _randomizer.GetRandomFromRangeContracted(min, max));
}

[TestCase(1, 2, 0)]
[TestCase(10, 100, 7)]
[TestCase(-100, -10, -107)]
public void When_return_value_is_less_than_min_Then_should_throw_exception(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

Assert.Catch<Exception>(() => _randomizer.GetRandomFromRangeContracted(min, max));
}

[TestCase(10, 100, 102)]
public void When_return_value_is_more_than_max_Then_should_throw_exception(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

Assert.Catch<Exception>(() => _randomizer.GetRandomFromRangeContracted(min, max));
}

[TestCase(0, 2, 1)]
[TestCase(10, 100, 50)]
[TestCase(-100, 10, 5)]
[TestCase(int.MinValue, int.MaxValue, 1)]
[TestCase(int.MinValue, int.MaxValue, 0)]
[TestCase(int.MinValue, int.MaxValue, -1)]
public void When_min_is_less_than_max_Then_should_equal_expected_result(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

var actual = _randomizer.GetRandomFromRangeContracted(min, max);

Assert.AreEqual(expected, actual);
}

[TestCase(0, 2, 0)]
[TestCase(10, 100, 10)]
[TestCase(-100, 10, -100)]
[TestCase(int.MinValue, int.MaxValue, int.MinValue)]
public void When_min_is_less_than_max_and_result_equals_min_Then_should_equal_expected_result(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

var actualResult = _randomizer.GetRandomFromRangeContracted(min, max);

Assert.AreEqual(expected, actualResult);
}

[TestCase(0, 2, 2)]
[TestCase(10, 100, 100)]
[TestCase(-100, 10, 10)]
[TestCase(int.MinValue, int.MaxValue, int.MaxValue)]
public void When_min_is_less_than_max_and_result_equals_max_Then_should_equal_expected_result(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

var actualResult = _randomizer.GetRandomFromRangeContracted(min, max);

Assert.AreEqual(expected, actualResult);
}
}
}

Source


http://stevenhollidge.com/blog-source-code/CodeContracts.zip

Wednesday, 4 April 2012

Continuous Testing

Various software vendors have produced some useful Visual Studio tooling to help TDD and BDD for developers.

They range from automatic build and running of affected tests on save to showing you the location of failing tests and code coverage figures within the coding IDE.

If you would like a demo project with tests to try out some of these tools you can download the following solution:

http://stevenhollidge.com/blog-source-code/LibrarySystem.zip

And, (for me) the winner is…

NCrunch for Visual Studio 2010

NCrunch is an automated parallel continuous testing tool for Visual Studio .NET. It intelligently takes responsibility for running automated tests so that you don't have to, and it gives you a huge amount of useful information about your tests (such as code coverage and performance metrics) inline in your IDE while you work.

ncrunch

Here are the rest:

Continuous Testing for Visual Studio 2010

  • MSTest for Visual Studio 2010
  • NUnit v2.5 or later
  • XUnit v1.5 or later

Continuous Testing for Visual Studio auto-detects your unit tests and runs them each time you build your solution. It adds an error to your error list for each test that fails, allowing you to navigate to the line of the test that failed, just like you would navigate from a compile error.

Continuous Testing removes a manual step for you, making your workflow far more efficient. 

There is a free version and a professional paid version with various enhancements such as auto ordering tests and aborting a test run on a first test failure.

Link: http://visualstudiogallery.msdn.microsoft.com/c074d3c6-71e2-4628-9e7c-7690e706aef4

vs-integration

Demon from RedGate

demon

Demon takes over the Visual Studio build to compile and run tests only for code that has changed.  See the nice green bar down the left side gutter (to the right of the collapse +/-)?  That’s what Demon adds to show your changes are all good.  If your changes result in tests breaking it changes to red.  It’s still in beta and doesn’t seem to be successful all the time but hopefully by the time it comes out of beta this may well become a must have tool.

Link:  http://www.red-gate.com/products/dotnet-development/dotnet-demon/

Mighty Moose from Continuous Tests

continuoustests

Again, this tool runs tests on build only for code that has changed.  You also get code coverage numbers in the left hand side gutter to give you a heads up on how many tests cover the overall method.

Link:  http://continuoustests.com/

And, here’s some old school tooling

Here is a few quick screenshot reminders for anyone that hasn’t already used ReShaper, TestDriven.NET and NCover tools:

ReSharper from JetBrains

You get a nice visual test runner with ReSharper, plus the nice icons next to each test in the coding IDE to allow individual running or debugging of tests or test cases.  Test cases are where you use the same test with multiple attributes above the method signature to pass in different test cases.

resharper

image

UnitTest-results

Coverage

coverage2

NCover

coverage1

Link: http://www.ncover.com

Performance

perf

Saturday, 18 February 2012

TryExecute with timeout and maxAttempts

A nice piece of code for calling services with a timeout and maximum attempts, in case the service should cause an exception.

It follows the standard practise for "Try" in .Net, like TryParse, of returning a boolean to indicate success and the result as an out parameter. Should you wish to find out the exception that may have occurred this is also passed as an out parameter.

I've also included an Execute mthod that will raise an exception should the service request timeout or fail more than the maximum number of attempts,

The source code solution includes unit tests in MBUnit, NUnit, xUnit and MSTest:

http://stevenhollidge.com/blog-source-code/TryExecute.zip