-
Notifications
You must be signed in to change notification settings - Fork 84
Added StepExecutor class to allow users to add custom logic before/after each step. #169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| namespace TestStack.BDDfy.Tests.Configuration | ||
| { | ||
| public class EmptyScenario | ||
| { | ||
| public void GivenSomething() { } | ||
| public void WhenSomething() { } | ||
| public void ThenSomething() { } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| using System; | ||
| using System.Text; | ||
| using NUnit.Framework; | ||
| using TestStack.BDDfy.Configuration; | ||
|
|
||
| namespace TestStack.BDDfy.Tests.Configuration | ||
| { | ||
| [TestFixture] | ||
| public class StepExecutorTests | ||
| { | ||
| private class TestStepExecutor : StepExecutor | ||
| { | ||
| readonly StringBuilder _builder = new StringBuilder(); | ||
|
|
||
| public string Results | ||
| { | ||
| get { return _builder.ToString(); } | ||
| } | ||
|
|
||
| public override object Execute(Step step, object testObject) | ||
| { | ||
| try | ||
| { | ||
| _builder.AppendLine(string.Format("About to run step '{0}'", step.Title)); | ||
| return base.Execute(step, testObject); | ||
| } | ||
| finally | ||
| { | ||
| _builder.AppendLine(string.Format("Finished running step '{0}'", step.Title)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Test] | ||
| public void CustomizingStepExecutionByOverridingStepExecutor() | ||
| { | ||
| try | ||
| { | ||
| var testStepExecutor = new TestStepExecutor(); | ||
|
|
||
| Configurator.StepExecutor = testStepExecutor; | ||
|
|
||
| new EmptyScenario() | ||
| .Given(s => s.GivenSomething()) | ||
| .When(s => s.WhenSomething()) | ||
| .Then(s => s.ThenSomething()) | ||
| .BDDfy(); | ||
|
|
||
| string expected = | ||
| @"About to run step 'Given something' | ||
| Finished running step 'Given something' | ||
| About to run step 'When something' | ||
| Finished running step 'When something' | ||
| About to run step 'Then something' | ||
| Finished running step 'Then something' | ||
| "; | ||
|
|
||
| Assert.AreEqual(expected, testStepExecutor.Results); | ||
|
|
||
| } | ||
| finally | ||
| { | ||
| Configurator.StepExecutor = new StepExecutor(); | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| namespace TestStack.BDDfy | ||
| { | ||
| public interface IStepExecutor | ||
| { | ||
| object Execute(Step step, object testObject); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| using System; | ||
| using System.Security; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace TestStack.BDDfy.Processors | ||
| { | ||
| public static class AsyncTestRunner | ||
| { | ||
| public static void Run(Func<object> performStep) | ||
| { | ||
| var oldSyncContext = SynchronizationContext.Current; | ||
| try | ||
| { | ||
| var asyncSyncContext = new AsyncTestSyncContext(); | ||
| SetSynchronizationContext(asyncSyncContext); | ||
| var result = performStep(); | ||
| var task = result as Task; | ||
| if (task != null) | ||
| { | ||
| try | ||
| { | ||
| task.Wait(); | ||
| } | ||
| catch (AggregateException ae) | ||
| { | ||
| var innerException = ae.InnerException; | ||
| ExceptionProcessor.PreserveStackTrace(innerException); | ||
| throw innerException; | ||
| } | ||
| } | ||
| else | ||
| { | ||
| var ex = asyncSyncContext.WaitForCompletion(); | ||
| if (ex != null) | ||
| { | ||
| ExceptionProcessor.PreserveStackTrace(ex); | ||
| throw ex; | ||
| } | ||
| } | ||
| } | ||
| finally | ||
| { | ||
| SetSynchronizationContext(oldSyncContext); | ||
| } | ||
| } | ||
|
|
||
| [SecuritySafeCritical] | ||
| private static void SetSynchronizationContext(SynchronizationContext context) | ||
| { | ||
| SynchronizationContext.SetSynchronizationContext(context); | ||
| } | ||
| } | ||
| } |
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this cause your deadlock again? I thought the idea was to swap out the async run with the custom one
Haven't fully thought through this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JakeGinnivan No actually, it's the reverse - the deadlock only happens if we were to call the AsyncTestRunner from the UI thread (meaning, if it was called from within the StepExecutor itself). This way, the StepExecutor can choose to marshal the actual execution to whatever thread they like, and the AsyncTestRunner successfully waits for it to finish.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah understand. Possibly it's a good idea to turn off captured sync context stuff as well as this change.
i.e
Not needed for this PR but do you think that could be useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It sounds like that would be a good idea, but to be honest I'm not sure I understand the way the async void use-case works well enough to comment. If it helps, I've uploaded an initial sample of the Visual Studio integration Test assembly that uses the code in this pull request. Here is a sample test and the aforementioned BDDfy configuration. You'll need VS2013SDK if you want to run this locally.