Search And Destroy

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

Archive for the ‘QuickPlanner’ Category

On Apologies

Posted by kilfour on December 17, 2010

To all those that were following the ‘On What’s On My Mind’ series with interest.

I started writing the series when I was in between jobs.

I’m currently involved with a project were a lot of the ideas of the ‘On What’s On My Mind’ series are being used.
Only excluding the property-based testing part.

I always prefer seeing how an idea performs in the wild over an academic example, so I’m going to spend some time seeing where this project goes, but I will consolidate, and continue the On What’s On My Mind’ series at a later date.

For now though, …, happy holidays ;-) .

Posted in QuickPlanner, Rants | 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 »

On What’s On My Mind, QuickPlanner, Story Five, Acceptance Test, Second Try

Posted by kilfour on November 19, 2010

//Monthly View should allow the user to change a 'working day' to vacation.
//No confirmation required, change in the gui => save.
//Avoid page reloads !
public class Story5
{
    [Fact]
    public void ChangeToVacation()
    {
        new TakeTheDayOffHandler().Handle(15.January(2010));

        var monthViewDto =
                new GetDataForMonthViewHandler()
                    .Handle(MonthOf.January(2010));

        Assert.NotNull(monthViewDto);

        These.Days(15)
            .ShouldBeMarkedAsVacationIn(monthViewDto);

        AllButThese.Days(15)
            .ShouldNotBeMarkedAsVacationIn(monthViewDto);
    }

    [Fact]
    public void ChangeToVacationSpecs()
    {
        TakeTheDayOffHandler handler = null;
        new TestRun(5, 10)
           .Setup(() => handler = new TakeTheDayOffHandler())
           .Add(
               With
                   .Execute<DateTime>(i => handler.Handle(i))
                   .ReportInput(i => i.ToString("dd/MM/yyyy"))
                   .Generator(() => new DateTimeGenerator())
                   .RegisterSpec(
                        (i, o) => new Spec(() =>
                        {
                            Ensure.Equal(
                                "vacation",
                                new GetDataForMonthViewHandler()
                                    .Handle(new Month(i.Month, i.Year))
                                    .AllDays()
                                    .First(d => d.Day == i.Day && d.Type != "othermonth")
                                    .Type);
                        })
                        .Message(() =>
                            i.ToString("dd/MM/yyyy")
                            + " should have been marked as vacation, but wasn't.")
                   ))
           .Verify();
    }

    [Fact(Skip="UNTESTED")]
    public void Avoid_Page_Reloads()
    {
    }
}

public static class MonthViewDtoTestExtensions
{
    public static IEnumerable<DayDto> AllDays(this MonthViewDto month)
    {
        return
            month.Weeks.SelectMany(
            w => new[]
            {
                w.Monday, 
                w.Tuesday,
                w.Wednesday,
                w.Thursday,
                w.Friday,
                w.Saterday,
                w.Sunday
            });
    }
}

Supposing someone implemented the hack mentioned in the previous post, using testdriven on this class would give you something like this :
Output from QuickPlannerTests.AcceptanceTests.Story5.ChangeToVacationSpecs:
  ----------------------------------------------------------
  MetaTransition`2 <ChangeToVacationSpecs>b__0 
    20/05/1999 should have been marked as vacation, but wasn't.
  
  Expected : vacation.
  Actual : workingday.
  
  Falsifiable after 1 test(s), 1 Transition(s).
  --------------------Simplest Fail Case--------------------
  1 : Transition : MetaTransition`2, Output : null
  20/05/1999
  ----------------------------------------------------------

1 passed, 1 failed, 1 skipped (see 'Task List'), took 0,57 seconds (xunit).

Everytime.

Except ofcourse on the fifthteenth of january of two thousand and ten.

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

On What’s On My Mind, QuickPlanner, Story Five, Initial Acceptance Test

Posted by kilfour on November 19, 2010

//Monthly View should allow the user to change a 'working day' to vacation.
//No confirmation required, change in the gui => save.
//Avoid page reloads !
public class Story5
{
    [Fact]
    public void ChangeToVacation()
    {
        new TakeTheDayOffHandler().Handle(15.January(2010));

        var monthViewDto =
                new GetDataForMonthViewHandler()
                    .Handle(MonthOf.January(2010));

        Assert.NotNull(monthViewDto);

        These.Days(15)
            .ShouldBeMarkedAsVacationIn(monthViewDto);

        AllButThese.Days(15)
            .ShouldNotBeMarkedAsVacationIn(monthViewDto);
    }

    [Fact(Skip="MANUAL TESTING")]
    public void Avoid_Page_Reloads()
    {
    }
}

Of course just adding a well placed :

if (day.Date == new DateTime(2010, 1, 15))
    return "vacation";

in one of the handlers mapping methods would make this test pass.

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

On What’s On My Mind, QuickPlanner, The Stories So Far

Posted by kilfour on November 19, 2010



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

 
Follow

Get every new post delivered to your Inbox.