2

I've only started to work with specflow and i know it's bindings are global for the assembly. Anyways, i couldn't find the solution or workaround for my problem:

  1. I use abstract class for my UI tests, such as

    public abstract class UITestBase<T>
        where T : FeatureContext, new()
    {
        private static readonly object SyncObject = new object();
        private static AutoTestSettings settings;
    
        private IWebDriver webDriver;
        private IBrowserFactory browserFactory;
        private Container container;
    
        protected static T Context;
    
        [BeforeScenario]
        public virtual void BeforeScenario()
        {
            BuildConfiguration();
    
            var driverPool = container.GetInstance<IWebDriverPool>();
            webDriver = driverPool.GetDriver(settings.BrowserType);
            browserFactory = container.GetInstance<IBrowserFactory>();
    
            Context = new T
                          {
                              Browser = browserFactory.Create(webDriver, settings.WebsiteUrl, settings.BrowserType),
                              Container = container
                          };
        }
    
        [AfterScenario]
        public virtual void AfterScenario()
        {
            webDriver.Dispose();
        }
    }
    
  2. I have few FeatureSteps files, one for each page/feature. E.g LoginFeature and PurchaseFeature. Each FeatureSteps class extends UITestBase and has [Binding] attribute.

  3. Whenever I run scenario for LoginFeature it seems to hook on BeforeScenario for PurchaseFeatureSteps as well. At least thats what Debug.WriteLine(this.GetType().Name) says.

  4. It causes that each scenario opens as many browsers as there are inheritors of UITestBase. Although tests are running fine it looks sorta ugly and feels wrong.

  5. Did anyone face such problem? How do I fix it?

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
Vladislav Qulin
  • 1,872
  • 1
  • 17
  • 20
  • The `BeforeScenario` attribute can be scoped to a tag I believe: `[BeforeScenario("myTag")]`. The `Binding` attribute itself doesn't take a scope, but alongside it you can apply the `Scope` attribute that can take a tag name. – Adam Houldsworth Jul 20 '15 at 12:38
  • But this code (initiating the IOC, starting the web driver) is common for every UI feature ever. Am I supposed to put before scenario method for every feature? That doesn't sound good as well. – Vladislav Qulin Jul 20 '15 at 12:45
  • I was commenting on your observation about global items, scoping helps negate that. We also fire up Selenium via Seleno in SpecFlow - I'll have a look to see how we've done it, but I'm certain it didn't involve `BeforeScenario`. – Adam Houldsworth Jul 20 '15 at 12:49
  • We maintain a browser host and `BeforeFeature` (tagged with the need to have a browser) we check if it is running, if not, we run it. – Adam Houldsworth Jul 20 '15 at 12:52
  • I wonder if I can use nunit attributes such as testfixture/setup/teardown with specflow scenarios. Nunit seems to work this things out. – Vladislav Qulin Jul 20 '15 at 12:54
  • @Adam, that sounds interesting. I'll give it a try. – Vladislav Qulin Jul 20 '15 at 12:55
  • 2
    @Vladisav I would avoid doing that. SpecFlow can generate more than just NUnit tests, it also offers most hooks into a test that are necessary for stuff like this. – Adam Houldsworth Jul 20 '15 at 12:59

1 Answers1

4

As you noted, bindings are global in specflow. Also as you have discovered bindings in a base class are run once for each inheritor of that class. Don't place bindings into base classes, instead place them in a separate class specifically for this purpose, then Specflow will find them and run them. If you need to initialise objects for your scenarios to use, then I find its better to pass those objects through specflow's prescribed ways of sharing data between bindings. I have outlined an approach in this answer. My preference is for using context injection.

If you have some setup which is specific to particular features or scenarios, then the bindings can be scoped so that they only run for particular features or scenarions

Community
  • 1
  • 1
Sam Holder
  • 32,535
  • 13
  • 101
  • 181
  • Thanks a lot, you're very helpful. Although i don't like the concept of separate class (hard to maintain where the hooks are), it seems like legit solution. – Vladislav Qulin Jul 20 '15 at 16:27