Search And Destroy

Look out honey, ’cause I’m using technology!

Archive for the ‘QuickDotNetCheck’ Category

QuickDotNetCheck 0.2 Released

Posted by kilfour on June 28, 2011

Available here.

Still trying to get things working, but I’m allready prefering this to the old quicknet way.

Recently I ported the Agatha tests to use quickdotnetcheck and I’m particularely happy with the RequestDispatcher tests.

Here’s how the tests are currently run, though it is certain this will change in the future :

public class RequestDispatcherSuite : Suite
{
    public RequestDispatcherSuite() : base(50, 20) { }

    [Fact]
    public void Verify()
    {
        Using(() => new RequestDispatcherTestsState());
        Register(() => new AddRequest(() => Get<RequestDispatcherTestsState>().RequestDispatcher));
        Register(() => new AddRequestArray(() => Get<RequestDispatcherTestsState>().RequestDispatcher));
        Register(() => new AddRequestWithKeys(Get<RequestDispatcherTestsState>));
        Register(() => new Clear(Get<RequestDispatcherTestsState>));
        Run();
    }
}

The Suite class is a ‘test runner’ class.

The numbers in the call to the base constructor defines the amount of tests and fixtures to run, similarely to how quicknet handled this.

The Using and Get calls, is just a silly way to pass state around, … still thinking about this part.

The Register calls they, well, … register which fixtures to run, and finally, Run starts the test.

Here’s a simple fixture :

public class AddRequest : RequestDispatcherFixture
{
    private Request input;

    public AddRequest(Func<RequestDispatcher> requestDispatcher)
        : base(requestDispatcher) { }

    public override void Arrange()
    {
        input = new RequestGenerator().One<Request>();
    }

    protected override void Act()
    {
        requestDispatcher().Add(input);
    }

    public Spec TheRequestExistsInTheRequestCollection()
    {
        return new Spec(() => Ensure.True(requestDispatcher().SentRequests.Any(src => src == input)))
            .If(() => RequestTypeNotYetUsed(input.GetType()));
    }

    public Spec ThrowsExceptionIfRequestTypeAllreadyUsed()
    {
        return new Spec(Ensure.Throws<InvalidOperationException>)
            .If(() => RequestTypeAllreadyUsed(input.GetType()));
    }

    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.AppendLine(GetType().Name);
        sb.AppendFormat("    input : {0}", input.GetType().Name);
        return sb.ToString();
    }
}

In the Arrange part we supply the input : a random request.

The act part is the method under test and in this case we use the input request and add it to the request dispatcher.

As this is a pretty simple method we’re testing, there’s only two Specs defined :
One that ensures that the request is known to the dispatcher if all goes well.
And another one that ensures an exception is thrown if we try to add the same request type twice.

Overriding the ToString Method is done for reporting issues.

On a side note :
Just as quicknet, quickdotnetcheck forces you to write ‘complete’ specs.
If one were to ommit the spec that ensures the exception, qdnc will tell you about it, like so :

Test 'Tests.RequestDispatcherTests.RequestDispatcherSuite.Verify' failed: QuickDotNetCheck.RunReport : 
Ran 1 test, 4 fixtures.

--------------------Simplest Fail Case--------------------
1 : AddRequest
    input : FirstRequest
2 : AddRequest
    input : FirstRequest
----------------------------------------------------------

---- QuickDotNetCheck.Exceptions.UnexpectedException : Act threw : 
System.InvalidOperationException: A request of type Tests.RequestProcessorTests.FirstRequest has already been added. Please add requests of the same type with a different key.

You can have a look at the other fixtures and all here.

One other thing …
…that made me smile during all this porting stuff, is that qdnc uncovered a (very small) bug.

Here’s the report I got :

Ran 1 test, 5 fixtures.
Spec 'AddRequestWithKeys.TheKeyedRequestExistsInTheRequestCollection' does not hold.
--------------------Simplest Fail Case--------------------
1 : AddRequest
    input : SecondCachedRequest
2 : AddRequestWithKeys
    input : 
        key : KeyOne
        request : SecondCachedRequest
----------------------------------------------------------

A small change to the requestdispatcher made all pass.

-      AddRequest(request, true);	 	
-      keyToTypes[key] = request.GetType();

+      keyToTypes[key] = request.GetType(); 	
+      AddRequest(request, true);

As I said a small bug, and one that has never surfaced in the wild.
Probably because no-one is using the AddRequest and AddRequestWithKey methods in this way.

Property based testing makes sure that whichever assumption you hold about the way your program behaves, is justified.

Posted in QuickDotNetCheck | Leave a Comment »

QuickDotNetCheck 0.1 Released

Posted by kilfour on April 23, 2011

Available here.

There’s a couple of examples included :

1. The ListDeleteTests.

This one’s carried over from quicknet.
Here’s the requirement :

Write a function which takes a list of values and a value to remove as arguments, and return a copy of the inputlist that does not contain the value to remove.

Here’s the unit-test :

public class UnitTesting
{
    [Fact]
    public void Result_Does_Not_Contain_Removed_Value()
    {
        var inputList = new List<int> {1, 2, 3, 4, 5};
        var resultList = new ListDeleter().DoingMyThing(inputList, 4);
        Assert.DoesNotContain(4, resultList);
    }
}

Here’s a first implementation :
public class ListDeleter
{
    public IList<int> DoingMyThing(IList<int> theList, int iNeedToBeRemoved)
    {
        var result = theList.ToList();
        result.Remove(iNeedToBeRemoved);
        return result;
    }            
}

Unit test output :
1 passed, 0 failed, 0 skipped, took 1,21 seconds (xunit).

Here’s the (still quite verbose) QuickDotNetCheck test :
public class PropertyBasedTesting : Fixture
{
    private readonly ListDeleter listDeleter = new ListDeleter();
    private readonly IntGenerator intGen = new IntGenerator(1, 50);

    private IList<int> inputList { get; set; }
    private IList<int> resultList;
    private int toRemove;

    public override void Arrange()
    {
        toRemove = intGen.GetRandomValue();
        inputList = new DomainGenerator().With(() => intGen).Many<int>(1, 10).ToList();
    }

    protected override void Act()
    {
        resultList = listDeleter.DoingMyThing(inputList, toRemove);
    }

    [Spec]
    public void Result_Does_Not_Contain_Removed_Value()
    {
        Ensure.False(resultList.Contains(toRemove));
    }

    [Fact]
    public void VerifyAll()
    {
        new Suite(100, 20)
            .Register(() => new PropertyBasedTesting())
            .Run();
    }

    public override void Shrink(Func<bool> runFunc)
    {
        new ListShrinkingStrategy<PropertyBasedTesting, int>(
            this, e => e.inputList, new[] { -1, 0, 1 })
                .Shrink(runFunc);
    }

    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.AppendLine(GetType().Name);
        sb.Append("inputList : ");
        inputList.ForEach(i => sb.AppendFormat("{0}, ", i));
        sb.Remove(sb.Length - 2, 2);
        sb.Append(".");
        sb.AppendLine();
        sb.AppendFormat("toRemove : {0}.", toRemove);
        return sb.ToString();
    }
}

Which outputs (f.i.) :
Test 'QuickDotNetCheck.Examples.PropertyBasedTesting.VerifyAll' failed: QuickDotNetCheck.RunReport : 
--------------------Simplest Fail Case--------------------
1 : PropertyBasedTesting
inputList : 45, 45.
toRemove : 45.
----------------------------------------------------------

---- QuickDotNetCheck.Exceptions.FalsifiableException : 
Expected : False.
Actual : True.

	Suite.cs(151,0): at QuickDotNetCheck.Suite.Run()
	ListDeleteTests.cs(63,0): at QuickDotNetCheck.Examples.PropertyBasedTesting.VerifyAll()
	----- Inner Stack Trace -----
	Ensure.cs(34,0): at QuickDotNetCheck.Ensure.False(Boolean flag)
	ListDeleteTests.cs(57,0): at QuickDotNetCheck.Examples.PropertyBasedTesting.Result_Does_Not_Contain_Removed_Value()
	Fixture.cs(58,0): at QuickDotNetCheck.Fixture.AssertSpec(MethodInfo info)
	Implementation\EnumerableForEachExtension.cs(12,0): at QuickDotNetCheck.Implementation.EnumerableForEachExtension.ForEach[T](IEnumerable`1 enumerable, Action`1 action)
	Fixture.cs(63,0): at QuickDotNetCheck.Fixture.Assert()
	Suite.cs(138,0): at QuickDotNetCheck.Suite.Run()

0 passed, 1 failed, 0 skipped, took 1,78 seconds (xunit).

Or :
Test 'QuickDotNetCheck.Examples.PropertyBasedTesting.VerifyAll' failed: QuickDotNetCheck.RunReport : 
--------------------Simplest Fail Case--------------------
1 : PropertyBasedTesting
inputList : 18, 18.
toRemove : 18.
----------------------------------------------------------

---- QuickDotNetCheck.Exceptions.FalsifiableException : 
Expected : False.
Actual : True.

	Suite.cs(151,0): at QuickDotNetCheck.Suite.Run()
	ListDeleteTests.cs(63,0): at QuickDotNetCheck.Examples.PropertyBasedTesting.VerifyAll()
	----- Inner Stack Trace -----
	Ensure.cs(34,0): at QuickDotNetCheck.Ensure.False(Boolean flag)
	ListDeleteTests.cs(57,0): at QuickDotNetCheck.Examples.PropertyBasedTesting.Result_Does_Not_Contain_Removed_Value()
	Fixture.cs(58,0): at QuickDotNetCheck.Fixture.AssertSpec(MethodInfo info)
	Implementation\EnumerableForEachExtension.cs(12,0): at QuickDotNetCheck.Implementation.EnumerableForEachExtension.ForEach[T](IEnumerable`1 enumerable, Action`1 action)
	Fixture.cs(63,0): at QuickDotNetCheck.Fixture.Assert()
	Suite.cs(138,0): at QuickDotNetCheck.Suite.Run()

0 passed, 1 failed, 0 skipped, took 1,76 seconds (xunit).

1. The BugHouseTest.
Also carried over from quicknet.
The BugHouse :

public class BugHouse
{
    private int count;
    public bool Run(int a)
    {
        if (count++ >= 3 && a == 6)
            throw new Exception();
        return true;
    }
}

Here’s the test code :
public class BugHouseTest
{
    [Fact]
    public void VerifyAll()
    {
        var suite = new Suite(50, 20);
        suite
            .Using(() => new BugHouseFixtureState())
            .Register(() => new BugHouseFixture(suite))
            .Run();
    }
}

public class BugHouseFixtureState
{
    public BugHouse BugHouse { get; private set; }
    public BugHouseFixtureState()
    {
        BugHouse = new BugHouse();
    }
}

public class BugHouseFixture : Fixture
{
    private readonly Suite suite;
    private int input { get; set; }
    private bool output;

    public BugHouseFixture(Suite suite)
    {
        this.suite = suite;
    }

    public override void Arrange()
    {
        input = new IntGenerator(0, 20).GetRandomValue();
    }

    protected override void Act()
    {
        output = suite.Get<BugHouseFixtureState>().BugHouse.Run(input);
    }

    private SimpleValuesShrinkingStrategy<BugHouseFixture> shrunk;

    public override void Shrink(Func<bool> runFunc)
    {
        shrunk =
            new SimpleValuesShrinkingStrategy<BugHouseFixture>(this, e => e.input);
        shrunk.AddValues(new object[] { -1, 0, 1 });
        shrunk.Shrink(runFunc);
    }

    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.AppendLine(GetType().Name);
        if(!shrunk.Shrunk())
            sb.AppendFormat("input : {0}.", input);
        return sb.ToString();
    }

    [Spec]
    public void Always_Returns_True()
    {
        Ensure.True(output);
    }
}

Resulting in something like :
Test 'QuickDotNetCheck.Examples.BugHouseTest.VerifyAll' failed: QuickDotNetCheck.RunReport : 
--------------------Simplest Fail Case--------------------
1 : BugHouseFixture
2 : BugHouseFixture
3 : BugHouseFixture
4 : BugHouseFixture
input : 6.
----------------------------------------------------------

---- QuickDotNetCheck.Exceptions.FalsifiableException : 
Expected : True.
Actual : False.

	Suite.cs(151,0): at QuickDotNetCheck.Suite.Run()
	BugHouseTest.cs(26,0): at QuickDotNetCheck.Examples.BugHouseTest.VerifyAll()
	----- Inner Stack Trace -----
	Ensure.cs(27,0): at QuickDotNetCheck.Ensure.True(Boolean flag)
	BugHouseTest.cs(85,0): at QuickDotNetCheck.Examples.BugHouseFixture.Always_Returns_True()
	Fixture.cs(58,0): at QuickDotNetCheck.Fixture.AssertSpec(MethodInfo info)
	Implementation\EnumerableForEachExtension.cs(12,0): at QuickDotNetCheck.Implementation.EnumerableForEachExtension.ForEach[T](IEnumerable`1 enumerable, Action`1 action)
	Fixture.cs(63,0): at QuickDotNetCheck.Fixture.Assert()
	Suite.cs(138,0): at QuickDotNetCheck.Suite.Run()

0 passed, 1 failed, 0 skipped, took 1,30 seconds (xunit).

3. The ElaborateExample.
Experiments.
Not quite working at the moment, but interesting nonetheless.

Maintaining consistency :
As promised, the project on google code is up for deletion.

Posted in QuickDotNetCheck | Leave a Comment »

QuickDotNetCheck Moved to GitHub

Posted by kilfour on April 21, 2011

Which is here.

Maintaining consistency :
Seeing as how I’ve never been in favour of looking back, the google code project will be deleted as soon as there’s a new release.

Posted in QuickDotNetCheck | Leave a Comment »

QuickGenerate Tests : Part I

Posted by kilfour on February 23, 2011

I used to have some QuickNet tests in there, but I removed them during a serious refactoring.
It was just easier to unit test stuff, after moving quickgenerate out of quicknet.

As a consequence most of the features recently developed are unit tested.

And today I have arrived at the point where the unit tests are starting to bug me.

Because of the nature of quickgenerate, interactions are very important.
I now have a test case for ‘almost’ every feature of the domain generator, but everytime I release it into the wild, I still have to write some new tests in order to solve bugs.
Bugs which arise mainly because of interactions between the different classes/methods.

Test maintainability is becoming a nightmare.
Not as much as so, as when maintaining something untested, … by several miles, … but still.
There’s even not that many tests in quickgenerate yet, and at the moment it is all still quite managable.

But then again, I do get annoyed quite easily.

So I tried quickdotnetcheck :

public class OneToManyTests : Fixture
{
    private readonly Type[] entities = FromAssembly.Containing<ILevel>().Implementing<ILevel>();
    private DomainGenerator domainGenerator;
    private ILevel result;
    private Func<ILevel> action;

    protected override void Arrange()
    {
        domainGenerator =
            new DomainGenerator()
            .Entities(entities)
            .OneToMany<LevelOne, LevelTwo>(1, 10, (one, many) => { one.NextLevel.Add(many); many.Parent = one; })
            .OneToMany<LevelTwo, LevelThree>(1, 10, (one, many) => { one.NextLevel.Add(many); many.Parent = one; });
        
        action =
            new Func<ILevel>[]
                {
                    () => domainGenerator.One<LevelOne>(),
                    () => domainGenerator.One<LevelTwo>(),
                    () => domainGenerator.One<LevelThree>()
                }.PickOne();
    }

    protected override void Act()
    {
        result = action();
    }

    [Fact]
    public void VerifyAllSpecs()
    {
        new Suite(100, 10)
            .Register(() => new OneToManyTests())
            .Run();
    }

    [Spec]
    public void TotalNumberOfThingsInHierarchy_Equals_NumberOfGeneratedObjects()
    {
        Ensure.Equal(GetTotalNumberOfThingsInHierarchy(), domainGenerator.GeneratedObjects.Count());
    } 
}

Reasonably painless.

Posted in Checking Stuff Out, Property Based Testing, QuickDotNetCheck | Leave a Comment »

State of the Assemblies

Posted by kilfour on February 18, 2011

QuickGenerate :
Is coming along nicely.
Here’s the one of the latest tests f.i. (slightly modified) :

public class ReplacingPrimitiveGeneratorsTests
{
    private readonly DomainGenerator domainGenerator;

    public ReplacingPrimitiveGeneratorsTests()
    {
        domainGenerator =
            new DomainGenerator()
                .Entities(typeof(SomethingToGenerate))
                .With(42);
    }

    [Fact]
    public void Tadaaaaa()
    {
        Assert.Equal(42, domainGenerator.One<SomethingToGenerate>().SomeInt);
    }

    public class SomethingToGenerate
    {
        public int SomeInt { get; set; }
    }
}

It is already being used in production code quite extensively and as a consequence rapidly ‘growing up in public’.
An evolution I obviously fully support.

QuickDotNetCheck :
In end user computing apps, property based testing (these days) is rarely a good investement.
As that is what I have been writing lately, QuickDotNetCheck has not evolved.
I expect this to change in the near future though.

QuickNet :
Has been abandoned. No updates will be done and as soon as QuickDotNetCheck delivers, the QuickNet project will be deleted.

Posted in QuickDotNetCheck, QuickGenerate, QuickNet | Leave a Comment »

QuickDotNetCheck on Google Code

Posted by kilfour on January 5, 2011

Here.

It is a truly, _truly_ slimmed down version of quicknet.
Focus this time is on _usability_, whilst still keeping the QuickCheck principles working.

Posted in QuickDotNetCheck, QuickNet | Leave a Comment »

QuickDotNetCheck : Preview

Posted by kilfour on December 28, 2010

Considering :

public class ListDeleter
{
    public void DoingMyThing(IList<int> theList, int iNeedToBeRemoved)
    {
        theList.Remove(iNeedToBeRemoved);
    }            
}

We define the following Spec :
public class ListDeleterSpecs : ListDeleterFixture
{
    [Spec]
    public void List_Does_Not_Contain_Removed_Value()
    {
        Ensure.False(list.Contains(toRemove));
    }
}

And implement a QuickDotNetCheck Fixture :
public class ListDeleterFixture : Fixture
{
    private readonly ListDeleter listDeleter = new ListDeleter();
    private readonly IntGenerator intGen = new IntGenerator(1, 20);

    protected IList<int> list;
    protected int toRemove;

    public override void Arrange()
    {
        toRemove = intGen.GetRandomValue();

        list = 
            new GeneratorRepository()
                .With<int>(intGen)
                .Randoms<int>(1, 100)
                .ToList();
    }

    protected override void Act()
    {
        listDeleter.DoingMyThing(list, toRemove);
    }

    [Fact]
    public void VerifyAll() // Assert is already spoken for by BaseFixture
    {
        new Suite(1, 1000)
            .Register(() => new ListDeleterFixture())
            .Run();
    }
}

Resulting in something like :

  Falsifiable after 1 test(s), 375 Transition(s).
  ListDeleterSpecs.List_Does_Not_Contain_Removed_Value failed.
  --------------------Simplest Fail Case--------------------
  ListDeleterFixture
  theInt : System.Int32 : 52
  theList: List Of System.Int32 : 
      52
      52

Posted in Checking Stuff Out, QuickDotNetCheck, QuickNet | Leave a Comment »

 
Follow

Get every new post delivered to your Inbox.