Skip to content

Commit

Permalink
reworked how the test state is maintained for mstest scenarios, got r…
Browse files Browse the repository at this point in the history
…id of the hackiness added to the common library.
  • Loading branch information
copypastedeveloper committed Oct 14, 2014
1 parent 12d2317 commit 1b91586
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 28 deletions.
28 changes: 14 additions & 14 deletions Given.Common/TestInitializer.cs
Expand Up @@ -29,60 +29,60 @@ void DetermineFields()
_fields.InsertRange(0, currentType.GetFields(TestRunManager.FieldsToRetrieve));
}

public void ProcessDelegates(bool invoke = true)
public void ProcessDelegates()
{
ProcessBefore(invoke);
ProcessGiven(invoke);
ProcessWhen(invoke);
ProcessThen(invoke);
ProcessAfter(invoke);
ProcessBefore();
ProcessGiven();
ProcessWhen();
ProcessThen();
ProcessAfter();
}

void ProcessBefore(bool invoke)
void ProcessBefore()
{
//execute all before items found.
_fields.Where(fieldInfo => fieldInfo.FieldType == typeof(before))
.Select(fieldInfo => new { Delegate = (before)fieldInfo.GetValue(_testClass), Field = fieldInfo }).ToList()
.ForEach(x =>
{
if (invoke) x.Delegate.Invoke();
x.Delegate.Invoke();
});
}

void ProcessGiven(bool invoke)
void ProcessGiven()
{
//execute all given items found.
_fields.Where(fieldInfo => fieldInfo.FieldType == typeof(given))
.Select(fieldInfo => new { Delegate = (given)fieldInfo.GetValue(_testClass), Field = fieldInfo }).ToList()
.ForEach(x =>
{
if (invoke) x.Delegate.Invoke();
x.Delegate.Invoke();
_testStateManager.AddGiven(x.Field.Name, x.Delegate);
});
}

void ProcessWhen(bool invoke)
void ProcessWhen()
{
//execute all when items found.
_fields.Where(fieldInfo => fieldInfo.FieldType == typeof(when))
.Select(fieldInfo => new { Delegate = (when)fieldInfo.GetValue(_testClass), Field = fieldInfo }).ToList()
.ForEach(x =>
{
if (invoke) x.Delegate.Invoke();
x.Delegate.Invoke();
_testStateManager.AddWhen(x.Field.Name, x.Delegate);
});
}

void ProcessThen(bool invoke)
void ProcessThen()
{
_typeToProcess
.GetMethods()
.Where(TestRunManager.TestRunConfiguration.ThenIdentificationMethod).ToList()
.ForEach(x => _testStateManager.AddThen(x.Name, x));
}

void ProcessAfter(bool invoke)
void ProcessAfter()
{
_fields
.Where(fieldInfo => fieldInfo.FieldType == typeof(after)).ToList()
Expand Down
28 changes: 14 additions & 14 deletions Given.MSTest/Scenario.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Given.Common;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Expand All @@ -9,9 +10,8 @@ namespace Given.MSTest
[TestClass]
public abstract class Scenario
{
readonly TestInitializer _initializer;
readonly TestStateManager _testStateManager;
static readonly ConcurrentDictionary<Type,bool> AlreadyRanDelegates = new ConcurrentDictionary<Type, bool>();
static readonly ConcurrentDictionary<Type, TestStateManager> AlreadyRanDelegates = new ConcurrentDictionary<Type, TestStateManager>();
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
Expand All @@ -21,14 +21,16 @@ public abstract class Scenario

protected Scenario()
{
_testStateManager = new TestStateManager(this);
_initializer = new TestInitializer(this, _testStateManager);
var firstRun = !AlreadyRanDelegates.TryGetValue(GetType(), out _testStateManager);

bool alreadyRan;
var addToDictionary = !AlreadyRanDelegates.TryGetValue(GetType(), out alreadyRan);
if (firstRun)
{
_testStateManager = new TestStateManager(this);
var initializer = new TestInitializer(this, _testStateManager);
initializer.ProcessDelegates();

_initializer.ProcessDelegates(invoke:!alreadyRan);
if (addToDictionary) AlreadyRanDelegates.TryAdd(GetType(), true);
AlreadyRanDelegates.TryAdd(GetType(), _testStateManager);
}
}

[TestInitialize]
Expand All @@ -41,7 +43,6 @@ public void Setup()
public void RecordState()
{
TestState state;

switch (TestContext.CurrentTestOutcome)
{
case UnitTestOutcome.Error:
Expand All @@ -61,12 +62,11 @@ public void RecordState()
}

_testStateManager.SetThenState(TestContext.TestName, state, Message ?? string.Empty);
}

[ClassCleanup]
public static void Cleanup()
{
TestRunManager.CurrentTestRun.CurrentTest.Cleanup();
if (_testStateManager.Thens.All(x => x.Value.State !=TestState.Unknown))
{
_testStateManager.Cleanup();
}
}

protected void then(Action action)
Expand Down

1 comment on commit 1b91586

@copypastedeveloper
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was largely done in order to fix issues with the mstest test fixture lifecycle. the life of the test state needs to live for a long time due to the multiple times the test fixture gets constructed. to facilitate that we statically cache the test state by scenario. this enables us to know when all 'thens' have been run, as well as when to invoke the context setup.

Please sign in to comment.