SpecFlow BeforeScenario runs for each Feature file - c#

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:
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();
}
}
I have few FeatureSteps files, one for each page/feature. E.g LoginFeature and PurchaseFeature. Each FeatureSteps class extends UITestBase and has [Binding] attribute.
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.
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.
Did anyone face such problem? How do I fix it?

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

Related

How to instantiate outside of a constructor?

How to replicate this code with Autofac syntax?
public static class MenuConfig
{
public static void Initialize()
{
var _menuService = DependecyFactory.GetInstance<IMenuService>();
Parameters.Menu = _menuService.Menu();
}
}
Before calling this a "duplicate question" please note that I'm looking for an Autofac command. I CANNOT inject the interface anywhere and then call "Resolve". What I need to is perform an "InstancePerRequest" inline and uninjected so I don't have to do this:
var _service = new Service(new Dependency(new context()));
LightInject has a method that allows instantiation from an interface OUTSIDE of a constructor like this:
var _service = DependecyFactory.GetInstance<IService>();
What is the equivalent method for Autofac?
When calling containerBuilder.Build() you get back a container which implements IContainer and ILifetimeScope, whenever you get hold of one of these interfaces, you can resolve types from it:
container.Resolve<IService>();
If you want this container to be static, you could add the container as a static property to the Program or Startup class (depending if you're creating a Console or ASP.NET application).
Remember that the root container will be around for the entire duration of your application, so this can result in unwanted memory leaks when used incorrectly. Also see the warning in the documentation.
Still, it's perfectly possible to do the memory management yourself by resolving an Owned<> version from your interface:
using (var service = Program.Container.Resolve<Owned<IService>>())
{
service.Value.UseService();
}
Anyway, since you mention a static class in the comments, the best solution is to change that into a non-static class and register it as a singleton with Autofac. Then you can inject a Func<Owned<IService>> serviceFactory into that singleton and create/dispose an instance of the service wherever you need it.
using (var service = serviceFactory())
{
service.Value.UseService();
}
This is simply not possible with Autofac. All other solutions involving Autofac will require code refactoring which may potentially break software functionality. So unfortunately, the most elegant and least disruptive solution is this:
var _service = new Service(new Dependency(new context()));
Since this is an edge case addressing only one part of the software, this compromise is acceptable. It would be nice, however, if Autofac implemented this functionality in some future release.

How to configure BsonSerializer without use of static registry?

Within a C# project we currently use static methods on BsonSerializer to register serializers for specific types. This happens once on app startup.
However, our acceptance tests start the app up before every test and shut it down after every test, and the second time the app starts up it fails when RegisterSerializer is called, as the registration from the previous test is still in the registry as it's a global static.
Is there any way to register serializers without relying on global statics? Or another strategy for avoiding this problem when running tests?
If you're using the MongoDB serializer, you could check if the serializer is already registered before registering it:
if(BsonSerializer.LookupSerializer<YourCusomType>().GetType() != typeof(YourCusomTypeSerializer))
{
BsonSerializer.RegisterSerializer(new YourCusomTypeSerializer());
}
If you go down this route you should take into account multithreaded scenarios, the above code is not thread safe.
Another option would be to register your own provider and skip the individual serializer registrations:
public class YourCustomSerializationProvider : IBsonSerializationProvider
{
public IBsonSerializer GetSerializer(Type type)
{
if (type == typeof(YourCusomType)) return new YourCusomTypeSerializer();
// fall back to Mongo's defaults
return null;
}
}
// Where you previously registered individual serializers you will now register your provider instead
BsonSerializer.RegisterSerializationProvider(new YourCustomSerializationProvider());
This approach would be a bit more IoC friendly and would give you a bit more control.
Can you register these serializers in static constructor? This way you can call it any number of times you want, the static constructor will not execute more than once.
public class BsonSerializerRegisterer
{
static BsonSerializerRegisterer()
{
BsonSerializer.RegisterSerializer(typeof(DateTime), new DateTimeSerializer(DateTimeKind.Utc));
BsonSerializer.RegisterSerializer(typeof(decimal), new DecimalSerializer(BsonType.Decimal128));
BsonSerializer.RegisterSerializer(typeof(decimal?), new NullableSerializer<decimal>(new DecimalSerializer(BsonType.Decimal128)));
BsonSerializer.RegisterSerializer(new EnumSerializer<MyAwesomeEnum>(BsonType.String));
}
public static void RegisterSerializers()
{
}
}
And then call:
BsonSerializerRegisterer.RegisterSerializers()
A nice article that can help any future readers
https://www.mydevhub.com/mongodb/adding-custom-type-converter-to-mongodb-in-c/
My solution was to add all BsonSerializer.* invokations in the static constructor of StartUp.cs

How to resolve from autofac parent scope without passing it around multiple times?

I have an application that creates a lifetime scope at some point like so:
public class Main
{
public void Main()
{
using (ILifetimeScope scope = AutofacContainer.Container.BeginLifetimeScope())
{
scope.Resolve<SomeClass>();
}
}
}
Within SomeClass I have logic which then calls a lot of different classes and so on..
Then, about 10 methods down the call stack I need to use the main scope to do this:
public class ActivatorFactory : IActivatorFactory
{
public T Create<T>(Type instance)
{
using (ILifetimeScope scope = AutofacContainer.Container.BeginLifetimeScope())
{
return (T)scope.Resolve(instance);
}
}
}
The problem with that is that now I've created a new scope which is just used to resolve a runtime type. I want to be able to use the main scope to resolve this type. How can I do so without passing the main scope down to this factory class through 10 different methods/functions?
The only "hacky" solution I thought of is to just have a static property on my ActivatorFactory and set the scope in my Main class like so:
public class Main
{
public void Main()
{
using (ILifetimeScope scope = AutofacContainer.Container.BeginLifetimeScope())
{
ActivatorFactory.Scope = scope;
scope.Resolve<SomeClass>();
}
}
}
Is there a cleaner solution to use the main scope in another part of my application?
I had this need for a CancellationTokenSource instance per lifetime scope, where children are linked to their parent. If the the root scope's CancellationTokenSource, is canceled, all children lifetime scope's CancellationToken are canceled. To accomplish this, I created:
private sealed class ParentLifetimeScopeAccessor
{
private readonly ILifetimeScope _lifetimeScope;
public ParentLifetimeScopeAccessor(ILifetimeScope lifetimeScope)
{
_lifetimeScope = lifetimeScope;
_lifetimeScope.ChildLifetimeScopeBeginning += OnChildLifetimeScopeBeginning;
}
public ILifetimeScope ParentLifetimeScope { get; private set; }
private void OnChildLifetimeScopeBeginning(object sender, LifetimeScopeBeginningEventArgs e) =>
e.LifetimeScope.Resolve<ParentLifetimeScopeAccessor>().ParentLifetimeScope = _lifetimeScope;
}
With a registration, you can now access your parent's scope:
builder.RegisterType<ParentLifetimeScopeAccessor>().InstancePerLifetimeScope();
With the parent lifetime scope accessor, linked CancellationTokenSource instances can be created:
private static CancellationTokenSource CancellationTokenSourceFactory(IComponentContext context)
{
var scopeAccessor = context.Resolve<ParentLifetimeScopeAccessor>();
var parentScope = scopeAccessor.ParentLifetimeScope;
return null == parentScope
? new CancellationTokenSource()
: CancellationTokenSource.CreateLinkedTokenSource(parentScope.Resolve<CancellationTokenSource>().Token);
}
CancellationToken resolver:
private static CancellationToken CancellationTokenResolver(IComponentContext context) =>
context.Resolve<CancellationTokenSource>().Token;
Two registrations:
builder.Register(CancellationTokenSourceFactory).AsSelf().InstancePerLifetimeScope();
builder.Register(CancellationTokenResolver).AsSelf().InstancePerDependency();
If you're not using ActivatorFactory for your app (and you shouldn't be if you're using inversion of control) then delete it and think about what you're trying to test.
Are you trying to test that you can generally just resolve things from Autofac? Autofac has a raft of unit tests as well as millions of successful users. No value in testing the framework.
Are you trying to test that you registered all the things you needed to register? There's not a lot of value in that, either, for a couple of reasons: first, you'll hit that at runtime pretty quickly and see it in those tests; second, in a large, decoupled system those tests get really stale really quickly. It's a maintenance hassle.
Are you trying to test that a specific object graph can be composed based on your registrations? I might buy this one. See below.
Let's say it's the last thing - you have a really complex and troublesome object graph you want to ensure you can create because people keep breaking it. I could see that.
Separate your registrations out into an Autofac module. Use the Autofac module to test.
public class MyRegistrations : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Thing>();
// and all your other registrations.
}
}
then in the unit test
var builder = new ContainerBuilder();
builder.RegisterModule<MyRegistrations>();
var container = builder.Build();
var thing = container.Resolve<Thing>();
// Assert on the resolved thing.
You can use that same module to encapsulate your registrations in the app and then you'll actually be testing the complex registration but without a factory you're not using.
Warning: It is a slippery slope between testing some complex registration and testing all registrations. Like I said, you really don't want to test every registration you have. I've fallen down this slope. It's a maintenance nightmare. Add a registration to the module/app, add a test. Uh oh, we refactored, now the registrations are all different. Ugh. That's less testing about behavior than about characterization (not "what do I want it to do" but "what does it do now"). Pain. Suffering.
If you are using ActivatorFactory in your app for, say, service location instead of using some more standard thing like CommonServiceLocator that already does that for you and for which Autofac already directly integrates... then just test ActivatorFactory with a real container but with some arbitrary test registrations rather than the whole set from the real app. The functionality of ActivatorFactory doesn't have any bearing on what's registered inside it.
And, yeah, if you're using ActivatorFactory and need to keep it around, you'll have to hand it an ILifetimeScope at app startup. That's how service locators work. You'll see that all over in the Autofac docs when you look at how to integrate with apps like ASP.NET, WCF, and others.

How can I implement static 'test local' data in an NUnit test?

I have a couple thousand NUnit tests for a library, many of which rely on having some statically available 'request context' that is scoped to the request being served and flows across tasks. The library consumer provides an implementation to retrieve the current request context.
I need to implement something to provide this context for our NUnit test project, where the context is scoped to each individual test run; each test run should have it's own object, and I should be able to access it from anywhere during the test.
Initially, I had achieved this using TestContext.Current.Properties and storing my request context there, but with a recent NUnit update, Properties has become read-only.
Is there any replacement that I can use to achieve 'test local' data? i.e. something that's scoped to the current test run, and statically accessible.
Similar issue on github contains the following statement from NUnit developer:
However, it's not intended that you should change the properties of an
NUnit Test, because Test and its derivatives are internal and the
implementation can change. The internal classes allow it because
custom attributes may need to do it, but I recommend that tests avoid
doing it.
And such implementation change has actually happen. Before NUnit 2.6.0, TestContext had Properties bag, but since 2.6.0 it was moved to TestAdapter. You still could access it via TestContext.CurrentContext.Test.Properties however you have no guarantee that this will not change again in the future.
The cleaner way to implement such context accessor is by adding simple holder that will compare current test against the test for which current context instance was created. If those tests do not match it just creates a new context instance and remember current test.
Here is a working sample:
internal static class ContextAccessor
{
private static TestExecutionContext currentRequestTest;
private static RequestContext currentRequestContext;
public static RequestContext Current
{
get
{
var currTest = TestExecutionContext.CurrentContext;
if (currentRequestTest == currTest)
{
return currentRequestContext;
}
currentRequestContext = CreateRequestContext();
currentRequestTest = currTest;
return currentRequestContext;
}
}
public static RequestContext CreateRequestContext()
{
return new RequestContext();
}
}
RequestContext here is your context class. CreateRequestContext() is basically a factory method that creates context. You could put any logic you need for creating new context instance.
Now in the test you could just call ContextAccessor.Current:
[Test]
public void SomeTest()
{
var context1 = ContextAccessor.Current;
var context2 = ContextAccessor.Current;
Assert.AreSame(context1, context2);
}
Sample Project on GitHub

Best approach for breaking dependencies in C#?

We are looking at adding unit tests to our C# code base. I am finding it easy to add unit tests to simple classes, but classes that interact with other dependencies are more difficult. I have been looking at mocking frameworks, but was wondering about the best approach to write classes in the first place to break external dependencies, like file system, database and messaging system dependencies.
To give an example, a routine listens on a socket for a message in a certain format - say MessageA. This is decoded, some calculations are done, this is re-encoded into a different binary format and the resulting message then sent, MessageB.
My current testing approach is as follows. I extract an interface for all socket interactions, and create a mock interface. I set the interface in a singleton. Then run the class against hard coded inputs. The class under test will use the interface in the singleton to send/receive.
I do a similar thing to test database interactions.
This does not seem like the most flexible approach, how would you go about improving this to make it easier to test? If a mocking framework is the answer, how would I design the classes?
Example code :
[SetUp]
public void init()
{
// set message interface in singleton as mock interface
CommAdapter.Instance.MessageAdapter = new MockMessage();
// build reference message from hard coded test variables
initialiseMessageA();
// set input from mock message socket
((MockMessage) CommAdapter.Instance.MessageAdapter).MessageIn = m_messageA;
}
[Test]
public void test_listenMessage_validOutput()
{
// initialise test class
MessageSocket tS = new MessageSocket();
// read from socket
tS.listenMessage();
// extract mock interface from singleton
MockMessage mm = ((MockMessage) CommAdapter.Instance.MessageAdapter);
// assert sent message is in correct / correstpoinding format
Assert.AreEqual(1000001, mm.SentMessageB.TestField);
}
Instead of using Singletons to set your component implementations, use a Dependency Injection, and a DI library like Ninject. This is exactly the type of scenario they were designed for.
Not pushing you to Ninject specifically, but they have a good tutorial :) The concepts will transfer to other frameworks (like Unity).
https://github.com/ninject/ninject/wiki
With DI alone, the code will look something like this:
class Samurai {
private IWeapon _weapon;
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
public void Attack(string target) {
_weapon.Hit(target);
}
}
class Shuriken : IWeapon {
public void Hit(string target) {
Console.WriteLine("Pierced {0}'s armor", target);
}
}
class Program {
public static void Main() {
Samurai warrior1 = new Samurai(new Shuriken());
Samurai warrior2 = new Samurai(new Sword());
warrior1.Attack("the evildoers");
warrior2.Attack("the evildoers");
}
}
This looks clean now, but wait until your dependencies have dependencies, or further :) You can use a DI library to solve that, though.
With a library to handle the wiring up for you, it will look something like:
class Program {
public static void Main() {
using(IKernel kernel = new StandardKernel(new WeaponsModule()))
{
var samurai = kernel.Get<Samurai>();
warrior1.Attack("the evildoers");
}
}
}
// Todo: Duplicate class definitions from above...
public class WarriorModule : NinjectModule {
public override void Load() {
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
With either of these approaches, plus a mock object framework like Moq, your unit tests look something like this:
[Test]
public void HitShouldBeCalledByAttack()
{
// Arrange all our data for testing
const string target = "the evildoers";
var mock = new Mock<IWeapon>();
mock.Setup(w => w.Hit(target))
.AtMostOnce();
IWeapon mockWeapon = mock.Object;
var warrior1 = new Samurai(mockWeapon);
// Act on our code under test
warrior1.Attack(target);
// Assert Hit was called
mock.Verify(w => w.Hit(target));
}
You'll notice you can just pass mock instances straight into the code under test, and you don't have to mess around with setting singletons. This will help you avoid problems like needing to set up the state multiple times, or in between calls. It means no hidden dependencies.
You'll also notice I didn't use the DI container in the tests. If your code is well factored, it will only be testing a single class (and as often as possible, only a single method), and you will only need to mock out the direct dependencies of that class.
In addition to a DI container (I'm using MS Unity 2.0 currently but there are many to choose from) you will need a good mocking framework, my preference is MOQ. A common pattern/process for breaking concrete dependencies is:
define the dependency via an interface; you may luck out and already have an interface, like IDbConnection or you may need to use Proxy to wrap a concrete type and define your own interface.
resolve the concrete implementation via your DI container
inject your mock implementations into your DI container at test setup time (inject real impls. at system startup)

Categories