Skip to content

Commit 19ce553

Browse files
committed
Resolve #238 - Update docco to refer to Reqnroll
1 parent 33125cb commit 19ce553

13 files changed

Lines changed: 62 additions & 51 deletions

File tree

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
{
2-
"cucumberautocomplete.steps": [ "Tests/CSF.Screenplay.SpecFlow.Tests/StepDefinitions/**/*.cs" ],
2+
"cucumberautocomplete.steps": [
3+
"Tests/CSF.Screenplay.SpecFlow.Tests/StepDefinitions/**/*.cs",
4+
"Tests/CSF.Screenplay.Reqnroll.Tests/StepDefinitions/**/*.cs"
5+
],
36
"cucumberautocomplete.strictGherkinCompletion": true,
47
}

CSF.Screenplay.Docs/docs/bestPractice/SuitabilityAsATestingTool.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# Where Screenplay is suitable for testing
22

33
The Screenplay pattern is a recommended tool for writing automated tests for application software.
4-
Unlike [NUnit] or [SpecFlow] (or many others) Screenplay is not a complete testing framework.
4+
Unlike [NUnit] or [Reqnroll] (or many others) Screenplay is not a complete testing framework.
55
Rather, Screenplay integrates with your chosen testing framework to assist in the writing of test logic.
66

77
_Screenplay is not a silver bullet_; some kinds of tests could benefit from Screenplay and others will not.
88
Some testing scenarios are listed below, along with a brief consideration as to whether Screenplay is likely to be relevant.
99
Terminology can differ between developers, so each type of test begins with a short definition.
1010

1111
[NUnit]: https://nunit.org/
12-
[SpecFlow]: https://specflow.org/
12+
[Reqnroll]: https://reqnroll.net/
1313

1414
## Ideal: System tests
1515

@@ -65,6 +65,6 @@ This is particularly true if the test/sample scenarios would be recognisable to
6565
## Recommended: Use BDD-style tests
6666

6767
Screenplay is a great tool when used alongside [Behaviour Driven Development] (BDD).
68-
Whilst the use of a BDD framework such as [SpecFlow] is not at all mandatory, those familiar with BDD will quickly see the synergies with Screenplay.
68+
Whilst the use of a BDD framework such as [Reqnroll] is not at all mandatory, those familiar with BDD will quickly see the synergies with Screenplay.
6969

7070
[Behaviour Driven Development]: https://en.wikipedia.org/wiki/Behavior-driven_development

CSF.Screenplay.Docs/docs/bestPractice/WritingTests.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Rather than using many performables at the top-level of your tests, create [high
1111
When using a method-driven testing framework, such as NUnit, five performables in a single test method is a reasonable number.
1212
More than approximately ten performables is too many.
1313

14-
When using a binding-driven testing framework like SpecFlow, each binding should ideally correspond to at-most one performable.
14+
When using a binding-driven testing framework like Reqnroll, each binding should ideally correspond to at-most one performable.
1515

1616
[performables]: ../../glossary/Performable.md
1717
[high-level tasks]: ../../glossary/Task.md

CSF.Screenplay.Docs/docs/dependencyInjection/InjectingServices.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ Which of these depends upon the nature and paradigm of the test framework.
1717
For frameworks which are based on **test methods** such as [NUnit], services are typically injected via _method parameter injection_ into the test methods.
1818
[If Screenplay were to be extended] to work with frameworks such as xUnit or MSTest then this is likely to be the technique used.
1919

20-
For frameworks which are based on **binding classes** such as [SpecFlow], services are constructor-injected into binding classes.
20+
For frameworks which are based on **binding classes** such as [Reqnroll], services are constructor-injected into binding classes.
2121

2222
Use dependencies injected in this way to get access to [commonly-used Screenplay services] and anything else required at the root level of your test logic.
2323

2424
[NUnit]: https://nunit.org/
2525
[If Screenplay were to be extended]: ../extendingScreenplay/TestIntegrations.md
26-
[SpecFlow]: https://specflow.org/
26+
[Reqnroll]: https://reqnroll.net/
2727
[commonly-used Screenplay services]: InjectableServices.md
2828

2929
## Into standalone performance logic

CSF.Screenplay.Docs/docs/extendingScreenplay/TestIntegrations.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Writing new Test framework integrations
22

33
A way in which Screenplay is available for extension is the integration of Screenplay with other Test frameworks.
4-
Screenplay currently ships with integrations for [NUnit] and [SpecFlow] but developers are free to integrate it into other frameworks if they wish.
4+
Screenplay currently ships with integrations for [NUnit] and [Reqnroll] but developers are free to integrate it into other frameworks if they wish.
55
Developers who are interested in this may use the source code to these two integrations as inspiration.
66

77
[NUnit]: https://nunit.org
8-
[SpecFlow]: https://specflow.org
8+
[Reqnroll]: https://reqnroll.net/
99

1010
## Requirements
1111

@@ -33,7 +33,7 @@ Terminologies differ between testing frameworks; the word [Scenario] is used to
3333
* Failure to do this could lead to memory leaks or unnecesarily high resource usage whilst the [Screenplay] is in-progress
3434
* The test framework **must** provide access to at least the [`ICast`] and [`IStage`], resolved from the [Scenario]'s dependency injection scope, to the [Scenario] logic
3535
* The manner of doing this depends entirely on the test framework
36-
* By way of example, in NUnit this is performed by providing the values of parameters to the test method, in SpecFlow this is performed by resolving step bindng classes from that same DI scope, allowing constructor injection
36+
* By way of example, in NUnit this is performed by providing the values of parameters to the test method, in Reqnroll this is performed by resolving step bindng classes from that same DI scope, allowing constructor injection
3737

3838
[`Screenplay`]: xref:CSF.Screenplay.Screenplay
3939
[Scenarios]: ../../glossary/Scenario.md

CSF.Screenplay.Docs/docs/gettingStarted/reqnroll/index.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
1-
# Screenplay & SpecFlow tutorial
1+
# Screenplay & Reqnroll tutorial
22

3-
Begin writing SpecFlow tests using Screenplay by following these steps.
3+
> [!TIP]
4+
> Are you using the legacy **SpecFlow**?
5+
> **Reqnroll** is the maintained fork of SpecFlow, so it's recommended you upgrade your projects ASAP.
6+
>
7+
> For now, CSF.Screenplay continues to support SpecFlow.
8+
> Use the [CSF.Screenplay.SpecFlow] package and SpecFlow v3.4.3 or higher instead.
9+
> The remainder of the instructions below work for either Reqnroll or SpecFlow.
10+
11+
Begin writing Reqnroll tests using Screenplay by following these steps.
412
Further detail is provided below.
513

6-
1. Ensure that your test project uses [SpecFlow version 3.4.3] or higher
7-
1. Install the NuGet package **[CSF.Screenplay.SpecFlow]** to the project which will contain your `.feature` files
8-
1. _Optional:_ Add services to dependency injection which will be required by the [Abilities] you intend to use. If required, [use SpecFlow context injection & hooks] to add these to the DI container.
14+
1. Ensure that your test project uses [Reqnroll version 2.0.0] or higher
15+
1. Install the NuGet package **[CSF.Screenplay.Reqnroll]** to the project which will contain your `.feature` files
16+
1. _Optional:_ Add services to dependency injection which will be required by the [Abilities] you intend to use. If required, [use Reqnroll context injection & hooks] to add these to the DI container.
917
1. Write step binding classes which dependency-inject and use Screenplay's architecture
1018

11-
[SpecFlow version 3.4.3]: https://www.nuget.org/packages/SpecFlow/3.4.3
12-
[CSF.Screenplay.SpecFlow]: https://www.nuget.org/packages/CSF.Screenplay.SpecFlow
19+
[Reqnroll version 2.0.0]: https://www.nuget.org/packages/Reqnroll/2.0.0
20+
[CSF.Screenplay.Reqnroll]: https://www.nuget.org/packages/CSF.Screenplay.Reqnroll
1321
[Abilities]: ../../../glossary/Ability.md
14-
[use SpecFlow context injection & hooks]: https://docs.specflow.org/projects/specflow/en/latest/Bindings/Context-Injection.html#advanced-options
22+
[use Reqnroll context injection & hooks]:https://docs.reqnroll.net/latest/automation/context-injection.html#advanced-options
1523

1624
## Writing step bindings
1725

1826
> [!IMPORTANT]
19-
> When using SpecFlow with Screenplay, every Screenplay-using test within a test assembly (thus, within a .NET project) must share the same instance of `Screenplay`.
27+
> When using Reqnroll with Screenplay, every Screenplay-using test within a test assembly (thus, within a .NET project) must share the same instance of `Screenplay`.
2028
> This is not expected to be problematic, as all the [`Screenplay`] object does is set-up the Screenplay architecture and dependency injection for the tests.
2129
22-
When using Screenplay with SpecFlow, `.feature` files are written as normal.
30+
When using Screenplay with Reqnroll, `.feature` files are written as normal.
2331
The only difference in writing your tests is that **Step Binding** classes should inject Screenplay architecture and use it within the bindings.
2432

2533
The recommended services to inject into your step binding classes are either [`IStage`] or [`ICast`].
@@ -38,7 +46,7 @@ If you are not using Personas to get actors, then you might also need to inject
3846
> The implied ability, the performables, persona and `DishwashingBuilder` used in this test, related to washing dishes, are all fictitious.
3947
> See [the documentation for writing performables] to learn about how these could be written.
4048
41-
This example assumes that SpecFlow is writting using [the NUnit runner], and thus [it makes use of NUnit-style assertions].
49+
This example assumes that Reqnroll is writting using [the NUnit runner], and thus [it makes use of NUnit-style assertions].
4250
Feel free to replace the assertion _with whichever assertion library you wish to use_.
4351

4452
```csharp
@@ -75,5 +83,5 @@ public class WashTheDishesSteps(IStage stage)
7583
```
7684

7785
[the documentation for writing performables]: ../../writingPerformables/index.md
78-
[the NUnit runner]: https://docs.specflow.org/projects/specflow/en/latest/Installation/Unit-Test-Providers.html
86+
[the NUnit runner]: https://docs.reqnroll.net/latest/integrations/nunit.html
7987
[it makes use of NUnit-style assertions]: https://docs.nunit.org/articles/nunit/writing-tests/assertions/assertion-models/constraint.html

CSF.Screenplay.Reqnroll/ScreenplayBinding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace CSF.Screenplay
1010
{
1111
/// <summary>
12-
/// SpecFlow binding which uses hooks to coordinate the relevant <see cref="Screenplay"/> &amp; <see cref="IPerformance"/> event invokers.
12+
/// Reqnroll binding which uses hooks to coordinate the relevant <see cref="Screenplay"/> &amp; <see cref="IPerformance"/> event invokers.
1313
/// </summary>
1414
[Binding]
1515
public class ScreenplayBinding

CSF.Screenplay.Reqnroll/ScreenplayPlugin.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
namespace CSF.Screenplay
1919
{
2020
/// <summary>
21-
/// The Screenplay plugin for SpecFlow.
21+
/// The Screenplay plugin for Reqnroll.
2222
/// </summary>
2323
/// <remarks>
2424
/// <para>
25-
/// This plugin class is the <xref href="IntegrationGlossaryItem?text=test+framework+integration"/> for SpecFlow.
26-
/// Crucially it adds the Screenplay architecture to the SpecFlow architecture.
25+
/// This plugin class is the <xref href="IntegrationGlossaryItem?text=test+framework+integration"/> for Reqnroll.
26+
/// Crucially it adds the Screenplay architecture to the Reqnroll architecture.
2727
/// </para>
2828
/// <para>
29-
/// Becuase this plugin leverages the SpecFlow/BoDi <c>IObjectContainer</c>, it is likely incompatible with other plugins
29+
/// Becuase this plugin leverages the Reqnroll/BoDi <c>IObjectContainer</c>, it is likely incompatible with other plugins
3030
/// which integrate with third party Dependency Injection libraries.
3131
/// </para>
3232
/// <para>
@@ -38,8 +38,8 @@ namespace CSF.Screenplay
3838
/// <para>
3939
/// If you wish to further customise the dependency injection, such as adding injectable services for <xref href="AbilityGlossaryItem?text=abilities"/>
4040
/// or implementations of <see cref="IPersona"/>, add them to the relevant DI container.
41-
/// When using SpecFlow's default BoDi container this is described in the following article
42-
/// <see href="https://docs.specflow.org/projects/specflow/en/latest/Bindings/Context-Injection.html#advanced-options"/>.
41+
/// When using Reqnroll's default BoDi container this is described in the following article
42+
/// <see href="https://docs.reqnroll.net/latest/automation/context-injection.html#advanced-options"/>.
4343
/// If using a third-party DI container then you should use that container's appropriate mechanism of adding services.
4444
/// </para>
4545
/// </remarks>
@@ -56,8 +56,9 @@ public class ScreenplayPlugin : IRuntimePlugin
5656
/// </summary>
5757
/// <remarks>
5858
/// <para>
59-
/// This is required because the bindings for beginning/ending the Screenplay in <see cref="ScreenplayBinding"/> must be <c>static</c>:
60-
/// <see href="https://docs.specflow.org/projects/specflow/en/latest/Bindings/Hooks.html#supported-hook-attributes"/>.
59+
/// This is required because the bindings for beginning/ending the Screenplay in <see cref="ScreenplayBinding"/> must be <c>static</c>.
60+
/// Those bindings use the <c>[BeforeTestRun]</c> and <c>[AfterTestRun]</c> hooks, which must be static, as documented here:
61+
/// <see href="https://docs.reqnroll.net/latest/automation/hooks.html#supported-hook-attributes"/>
6162
/// </para>
6263
/// </remarks>
6364
static public Screenplay Screenplay { get; private set; }
@@ -88,9 +89,10 @@ static void OnConfigurationDefaults(object sender, ConfigurationDefaultsEventArg
8889
/// </summary>
8990
/// <remarks>
9091
/// <para>
91-
/// It is a known/documented issue that this event may be triggered more than once in a single run of SpecFlow:
92-
/// <see href="https://github.com/techtalk/SpecFlow/issues/948"/>, and by more than one thread.
93-
/// Thus, to prevent double-initialisation, this method occurs in a thread-safe manner which ensures that even if it
92+
/// It was a known/documented issue that this event may be triggered more than once in a single run of the old
93+
/// SpecFlow, and by more than one thread. Unfortunately I don't know if that's still applicable in Reqnroll.
94+
/// I've opened this discussion to see if I can find out: <see href="https://github.com/orgs/reqnroll/discussions/1005"/>.
95+
/// To prevent double-initialisation, this method occurs in a thread-safe manner which ensures that even if it
9496
/// is executed more than once, there is no adverse consequence.
9597
/// </para>
9698
/// </remarks>

CSF.Screenplay.Reqnroll/ScreenplaySteps.cs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
using CSF.Screenplay.Actors;
2-
#if SPECFLOW
1+
#if SPECFLOW
2+
using CSF.Screenplay.Actors;
33
using TechTalk.SpecFlow;
4-
#else
5-
using Reqnroll;
6-
#endif
74

85
namespace CSF.Screenplay
96
{
@@ -12,6 +9,9 @@ namespace CSF.Screenplay
129
/// </summary>
1310
/// <remarks>
1411
/// <para>
12+
/// Note that this class does not exist in the Reqnroll Test Framework Integration. It is irrelevant there.
13+
/// </para>
14+
/// <para>
1515
/// In SpecFlow 3.x, the <c>Steps</c> class has three methods named <c>Given</c>, <c>When</c> &amp; <c>Then</c> which can cause
1616
/// a naming conflict with the same-named methods of <see cref="PerformanceStarter"/>. If you using the performance starter in
1717
/// the recommended way, then the methods of these two types can become ambiguous and force the developer to write additional
@@ -22,13 +22,10 @@ namespace CSF.Screenplay
2222
/// but in a manner which will not cause a name-resolution conflict.
2323
/// </para>
2424
/// <para>
25-
/// Note that in SpecFlow 4.x and up, this problem is irrelevant; there is no gain in using this subclass over the <c>using static</c> technique.
26-
/// As noted here <see href="https://docs.specflow.org/projects/specflow/en/latest/Bindings/Calling-Steps-from-Step-Definitions.html"/>
27-
/// and here <see href="https://github.com/SpecFlowOSS/SpecFlow/issues/1733"/> the Give, When &amp; Then methods upon the
28-
/// SpecFlow <c>Steps</c> class were removed in v4.x. This means that the naming conflict won't be present and that there is no need
29-
/// for your bindings to derive from this class instead of the official Steps class.
30-
/// Indeed, Screenplay could be described as a specific implementation of the 'driver pattern', which is noted in the linked Github issue
31-
/// as a best-practice alternative to calling-steps-from-steps.
25+
/// Note that in SpecFlow 4.x and up, and Reqnroll, this problem is irrelevant; there is no gain in using this subclass over the <c>using static</c> technique.
26+
/// The Given, When &amp; Then methods upon the SpecFlow <c>Steps</c> class were removed in v4.x, and never existed in any version of Reqnroll.
27+
/// This means that the naming conflict won't be present and that there is no need for your bindings to derive from this class instead
28+
/// of the official Steps class.
3229
/// </para>
3330
/// </remarks>
3431
public abstract class ScreenplaySteps : Steps
@@ -75,3 +72,4 @@ public abstract class ScreenplaySteps : Steps
7572
public static ICanPerformThen Then(Actor actor) => PerformanceStarter.Then(actor);
7673
}
7774
}
75+
#endif

CSF.Screenplay.Reqnroll/ServiceCollectionAdapter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace CSF.Screenplay
1313
{
1414
/// <summary>
15-
/// Adapter class which allows a SpecFlow/BoDi <c>IObjectContainer</c> to be used as an <see cref="IServiceCollection"/>.
15+
/// Adapter class which allows a Reqnroll/BoDi <c>IObjectContainer</c> to be used as an <see cref="IServiceCollection"/>.
1616
/// </summary>
1717
/// <remarks>
1818
/// <para>
@@ -68,7 +68,7 @@ public ServiceDescriptor this[int index]
6868
/// is <see cref="ServiceLifetime.Scoped"/> then the service descriptor will not be added and will be silently ignored.
6969
/// </para>
7070
/// <para>
71-
/// In reality, the Specflow BoDi object container only really supports singleton services at this level. So, any services added as
71+
/// In reality, the Reqnroll BoDi object container only really supports singleton services at this level. So, any services added as
7272
/// <see cref="ServiceLifetime.Transient"/> will actually become singletons here. Whilst the BoDi container does support scoped services, they
7373
/// must be added directly to the scope instance and cannot be added in advance.
7474
/// </para>

0 commit comments

Comments
 (0)