Search And Destroy

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

Archive for the ‘Checking Stuff Out’ Category

Fasterflect

Posted by kilfour on April 13, 2011

Through the ditto project, which I haven’t really tried out in the wild, but I must say, I do like the approach outlined, I came across Fasterflect.

Really nice lib.
It works (i.e. : it has automated tests).
It’s clean.
It’s fast.

Expect some QuickDotNetCheck updates in a month or so.
One of the main reasons that has been holding me back, regarding quickdotnetcheck, is having to write nasty reflection heavy methods.

Fasterflect really makes that kind of stuff a breeze.

And the DeepClone method truly helps out when writing properties involving pre- or postconditions.

Experiments are going on as we speak ;-) .

Posted in C# Musings, Checking Stuff Out | Leave a Comment »

QuickGenerate Tests : Part II

Posted by kilfour on February 23, 2011

As I said in previous post : ‘reasonably painless’.

When I first decided to write a quickdotnetcheck test for quickgenerate, I figured I’d test something where I smelled something fishy going on.

In the code posted before, notice how the OneToMany declarations have a minimum value of 1.

The test I first wrote initialized this to zero and, ‘lo and behold’, the spec failed.

Well, actually the entire thing just went kaboom, which is why I didn’t post the results in the first place ;-) .

Still, this simple idea (property based testing), exposed a bug that I wasn’t able to smoke out using unit tests.
Because I hadn’t written a use case for an empty one to many.
Because I didn’t think about it.
Because I didn’t have enough time to switch hats maybe (KB), or whatever.

And probably, yes, I should have thought about all this when I wrote the unit tests.

But I didn’t.

Writing the spec really required me to put on the testing hat.
And testing for an empty list is an obvious case when you’re wearing the right hat.

Posted in Checking Stuff Out, Property Based Testing, Rants | 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 »

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 »

On What’s On My Mind, Data Access

Posted by kilfour on November 27, 2010

I really like the ‘NHibernate – ConfOrm – Migrator – QuickGenerate’ combo.

If we need to add a persistent entity to our model, these are the steps :

Define the entity :

public class StarShip : Entity
{
    public virtual string SuperMan { get; set; }
    public virtual string MaryPoppins { get; set; }
    public virtual string God { get; set; }
}

Write the CrudTest :
public class StarShipCrudTest : CrudTest<StarShip> { }

Run the test and watch it fail :
Test 'IntegrationTests.StarShipCrudTest.CrudTest`1.AddEntity_EntityWasAdded' failed: NHibernate.Exceptions.GenericADOException : could not insert: [Core.StarShip][SQL: INSERT INTO StarShip (SuperMan, MaryPoppins, God) VALUES (?, ?, ?); select SCOPE_IDENTITY()]
  ----> System.Data.SqlClient.SqlException : Invalid object name 'StarShip'.
....
0 passed, 4 failed, 0 skipped, took 2,48 seconds (NUnit 2.5.5).

Add a migration :
[Migration(004)]
public class M004_StarShip : Migration
{
    private static string TableName = "StarShip";

    public override void Up()
    {
        Database
            .AddTable(
                TableName,
                new Column("Id", DbType.Int64, ColumnProperty.PrimaryKeyWithIdentity),
                new Column("SuperMan", DbType.String, 255, ColumnProperty.Null),
                new Column("MaryPoppins", DbType.String, 255, ColumnProperty.Null),
                new Column("God", DbType.String, 255, ColumnProperty.Null));
    }

    public override void Down()
    {
        Database.RemoveTable(TableName);
    }
}

Rerun the crudtest and watch it pass :
4 passed, 0 failed, 0 skipped, took 1,93 seconds (NUnit 2.5.5).

Done !

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

On What’s On My Mind, QuickPlanner, Setup So Far

Posted by kilfour on November 25, 2010

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

On What’s On My Mind, QuickPlanner, Story Seven, Reusing Test Code

Posted by kilfour on November 23, 2010

Story seven :
– Monthly View should allow the user to change a ‘vacation’ to working day.

Here’s the acidtest :

public class GoToWorkAcidTest : MonthViewAcidTest, IDisposable
{
    public void Dispose()
    {
        ReportSpecsTested();
    }

    [SpecFor(typeof(GoToWorkTransition))]
    public Spec ChangeWorkingDay_ShouldBeWorkingDay(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("workingday", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type == "workingday");
    }

    [SpecFor(typeof(GoToWorkTransition))]
    public Spec ChangeVacation_ShouldBeWorkingDay(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("workingday", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type == "vacation");
    }

    [SpecFor(typeof(GoToWorkTransition))]
    public Spec ChangeNotWeekend_ShouldBeWorkingDay(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("workingday", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type != "weekend");
    }

    [SpecFor(typeof(GoToWorkTransition))]
    public Spec WeekendsCannotBeChangedtoWorkingday(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("weekend", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type == "weekend");
    }
}

As you can see, it is pretty much a mirror image from the TakeTheDayOff one.
Except this test outputs something like :
Test 'Registered Spec not evaluated' failed: QuickNet.Exceptions.UnregisteredPropertiesException : GoToWorkTransition ChangeVacation_ShouldBeWorkingDay

	C:\Projects\quicknet\ quicknet\QuickNet\Reporting\TestRunReport.cs(58,0): at QuickNet.Reporting.TestRunReport.CheckForRegisteredButUntestedSpecs()

Output from Registered Spec not evaluated:
  733 : GoToWorkTransition ChangeWorkingDay_ShouldBeWorkingDay.
  733 : GoToWorkTransition ChangeNotWeekend_ShouldBeWorkingDay.
  267 : GoToWorkTransition WeekendsCannotBeChangedtoWorkingday.
  ------------------------------------------------------------
  Registered but untested : 
  GoToWorkTransition ChangeVacation_ShouldBeWorkingDay
  ------------------------------------------------------------

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

In order to get quicknet to test that spec and thus pass, we need to setup some vacation days.

Decorating the acidtest with the following :

[Using(typeof(TakeTheDayOffTransition))]

solves the issue and the test now outputs something like :
Output from VerifyAll:
  334 : GoToWorkTransition ChangeWorkingDay_ShouldBeWorkingDay.
  12 : GoToWorkTransition ChangeVacation_ShouldBeWorkingDay.
  346 : GoToWorkTransition ChangeNotWeekend_ShouldBeWorkingDay.
  128 : GoToWorkTransition WeekendsCannotBeChangedtoWorkingday.
  ------------------------------------------------------------

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

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

On What’s On My Mind, QuickPlanner, Doing The Dishes

Posted by kilfour on November 22, 2010

By which I mean refactoring, removing redundant code, clarifying intent, …

In the test code aswell.

Apply DRY, remove redundant tests, clarify why tests are there, …

public class TakeTheDayOffAcidTest : MonthViewAcidTest, IDisposable
{
    public void Dispose()
    {
        ReportSpecsTested();
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec ChangeWorkingDay_ShouldBeVacation(DateTime inputdate, Null nothingness)
    {
        return
            new Spec(() => Ensure.Equal("vacation", GetInputDayFromMonthview(inputdate).Type))
                .If(() => GetInputDayFromMonthview(inputdate).Type == "workingday");
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec ChangeVacation_ShouldBeVacation(DateTime inputdate, Null nothingness)
    {
        return
            new Spec(() => Ensure.Equal("vacation", GetInputDayFromMonthview(inputdate).Type))
                .If(() => GetInputDayFromMonthview(inputdate).Type == "vacation");
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec ChangeNotWeekend_ShouldBeVacation(DateTime inputdate, Null nothingness)
    {
        return
            new Spec(() => Ensure.Equal("vacation", GetInputDayFromMonthview(inputdate).Type))
                .If(() => GetInputDayFromMonthview(inputdate).Type != "weekend");
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec WeekendsCannotBeChangedtoVacation(DateTime inputdate, Null nothingness)
    {
        return
            new Spec(() => Ensure.Equal("weekend", GetInputDayFromMonthview(inputdate).Type))
                .If(() => GetInputDayFromMonthview(inputdate).Type == "weekend");
    }
}

Outputs :
Output from VerifyAll:
  672 : TakeTheDayOffTransition ChangeWorkingDay_ShouldBeVacation.
  47 : TakeTheDayOffTransition ChangeVacation_ShouldBeVacation.
  719 : TakeTheDayOffTransition ChangeNotWeekend_ShouldBeVacation.
  281 : TakeTheDayOffTransition WeekendsCannotBeChangedtoVacation.
  ------------------------------------------------------------

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

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

On What’s On My Mind, QuickPlanner, Acidifiying

Posted by kilfour on November 22, 2010

By which I mean : organizing one’s tests.

Or in the case of quicknet, transforming functional style tests into oop style tests.
The first style is quicker to write, harder to read, but allows for some extra tricks.
The second more closely resembles a unit test, is much more maintainable and allows for better reuse across tests.

So Transitions become classes, f.i. :

public class TakeTheDayOffTransition : MetaTransitionSut<DateTime, Null, TakeTheDayOffHandler>
{
    public TakeTheDayOffTransition()
    {
        CreateSutFunc = () =>
            new TakeTheDayOffHandler(
                NHibernateHelper.GetCurrentSession(),
                new FindDayOffByDate(NHibernateHelper.GetCurrentSession()));

        SutExecute = (sut, i) => { sut.Handle(i); return null; };

        Generator(() => new DateGenerator());

        ReportInput(i => i.ToString("dd/MM/yyyy"));
    }
}

And specs get organized in AcidTests :
public class TakeTheDayOffAcidTest : AcidTest
{
    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec ShouldBeVacation(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("vacation", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type != "weekend")
                .Message(() => string.Format(
                    "{0} should have been marked as vacation, but wasn't.",
                    i.ToString("dd/MM/yyyy")));
    }

    [SpecFor(typeof(TakeTheDayOffTransition))]
    public Spec WeekendsCannotBeChangedtoVacation(DateTime i, Null o)
    {
        return
            new Spec(() => Ensure.Equal("weekend", GetInputDayFromMonthview(i).Type))
                .If(() => GetInputDayFromMonthview(i).Type == "weekend")
                .Message(() => string.Format(
                    "{0} should have been marked as weekend, but wasn't.",
                    i.ToString("dd/MM/yyyy")));
    }
}

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

On What’s On My Mind, QuickPlanner, Story Five, Making It Pass

Posted by kilfour on November 21, 2010

Leading to more unit-tests, domain classes, …

Also this story implies, for the first time, that we need to persist something.
In walks nhibernate.
This I believe must be tested against a real database.
So we write some integration tests :

public class DayOffCrudTest : CrudTest<DayOff>
{
    protected override DayOff BuildEntity()
    {
        return  DayOff.On(new DateTimeGenerator().GetRandomValue());
    }
}

This uses a technique I’ve talked about before and results in :
4 passed, 0 failed, 0 skipped, took 2,06 seconds (xunit).

The tests are defined in the base class, specifically :
– SelectQueryWorks
– AddEntity_EntityWasAdded
– UpdateEntity_EntityWasUpdated
– DeleteEntity_EntityWasDeleted
We test CRUD operations for each entity against a real db in this way.

Posted in Checking Stuff Out, QuickPlanner | Leave a Comment »

 
Follow

Get every new post delivered to your Inbox.