1
votes

I have a test suite that utilizes a test reporting framework that I need to run through a base class, everything works fine but the [BeforeScenario] is being called 10 times for every scenario I run, 1 time for each feature in my suite, strangely the teardown only runs once.

Here is what my base class looks like:

[Binding]
public class BaseStep : AllureReport
{
    public DriverSupport _support;
    public BaseStep(DriverSupport support)
    {
        _support = support;
    }

    [BeforeScenario]
    public void Setup(FeatureContext context)
    {
            _support.startDriver();
            AllureLifecycle.Instance.RunStep(() =>
            {
                TestContext.Progress.WriteLine(
                    $"Test \"{TestExecutionContext.CurrentContext.CurrentTest.FullName}\" is starting...");
            });

    }

    [AfterScenario, Order(0)]
    private void TearDown()
    {

        AllureLifecycle.Instance.RunStep(() =>
        {
            TestContext.Progress.WriteLine(
                $"Test {TestExecutionContext.CurrentContext.CurrentTest.FullName}\" is stopping...");
        });

}

And this is what my feature step file looks like (there are 10 of these)

[Binding]
public class TestSteps1:BaseStep
{

    public TestSteps1(DriverSupport support) : base(suppprt)
    {
    }

    [Given(@"user goes to (.*)")]
    public void GivenUserGoesTo(string p0)
    {
        _support.driver.GoToUrl(p0)
    }

When I run just ONE scenario in a feature by themselves, it will print start the driver and print "test xxx is starting..." 10 times, once for each feature I have, I just want it to run once.

I have thought of moving beforescenario to the step classes themselves, but many of my features use steps from multiple step files, so I think that would be an issue. Is there any way to make it so it only runs BeforeScenario one time per scenario?

1

1 Answers

2
votes

SpecFlow will execute the BeforeScenario method for each type it finds in your test project. It looks like there are 10 types that define or inherit this method:

  • The BaseStep class
  • Each sub class of BaseStep

When I want a BeforeScenario to run only once per test run I will put it into its own "hooks" class.

Since both the before and after hooks should only execute once, just put both of them in something like SpecFlowHooks.cs.

The Selenium web driver object should be registered with the SpecFlow dependency injection framework, and passed directly to each step class as a constructor argument. Given the code you posted, I'm not sure a common base class for your step definitions is beneficial.

See my answer for How to properly manage and access webdriver instances to avoid problems with parallel execution of tests? for more information about properly registering a Selenium web driver object with SpecFlow.