I want to share DBfixture in all tests. This is the collection created for this purpose:
[CollectionDefinition("db")]
public class TestColDefinition : IClassFixture<DBfixture> { }
I have a base class from which i derive my test classes:
public class TestBase
{
protected readonly ITestOutputHelper testOutputHelper;
protected DBfixture dbf;
public TestBase(ITestOutputHelper testOutputHelper, DBfixture dbf)
{
this.testOutputHelper = testOutputHelper;
this.dbf = dbf;
}
}
[Collection("db")]
public class TestClass1 : TestBase
{
public TestClass1(ITestOutputHelper testOutputHelper, DBfixture dbf) : base(testOutputHelper, dbf) { }
[Fact]
public void fact(){}
}
[Collection("db")]
public class TestClass2 : TestBase
{
public TestClass2(ITestOutputHelper testOutputHelper, DBfixture dbf) : base(testOutputHelper, dbf) { }
[Fact]
public void fact(){}
}
But when I run tests two DBfixture objects are created (one for each test class). Without collection four objects are created. How do I setup this so that one object is shared among all test classes?
You can use the collection fixture and add every test under that collection to achieve what you mentioned above. But if you use a single collection fixture then your entire test will run in serial unless you explicitly disable it in Xunitrunner config.
One of the point from Xunit Docs:
Test collections also influence the way xUnit.net runs tests when running them in parallel.
For more details please read:
https://xunit.net/docs/shared-context
Alternative can be, use a static class to store the DB context which you can assign while starting the test and use that across the test life cycle.
Related
I want to group tests like this:
To get this screenshot I used TestCases, but they don't really apply to my needs.
Obviously I don't want this:
[TestCase(TestName = "ShouldDoSomething")]
[TestCase(TestName = "ShouldDoSomethingElse")]
public void OnJoinRoom()
{ ... }
I want something like this:
[TestGroup("OnJoinRoom")]
public void ShouldDoSomething()
{ ... }
[TestGroup("OnJoinRoom")]
public void ShouldDoSomethingElse()
{ ... }
I don't think using subclasses is an option, as the tests are depending on a SetUp method used in the TestFixture class.
In NUnit, TestFixtures are used to group tests as well as to provide a common setup. The normal way to provide a common setup across multiple TestFixtures is to have a common base class like
public class CommonBase
{
[SetUp]
public void CommonSetUp() { }
}
[TestFixture]
public class OnJoinRoom : CommonBase { }
[TestFixture]
public class OnLeaveRoom : CommonBase { }
Notes:
Put all your tests in the derived classes
TestFixture attribute is optional, of course, but do not put it on the base class.
Base class may be abstract if you like.
I want to do something like this to provide methods from test classes to other test classes using composition.
public class SomeTestClass : IClassFixture<SomeService>
{
private readonly SomeService SomeService;
public SomeTestClass(SomeService someService)
{
SomeService = someService;
}
[Fact]
private void Test()
{
//....
}
public SomeData CreateSomeData()
{
// populate fields with something based on internal/service state
return new SomeData();
}
public void DoSomeAction(....)
{
// does action which modifies internal/service state
}
}
public class SomeConsumingClass : IClassFixture<SomeTestClass>
{
private readonly SomeTestClass SomeTestClass;
public SomeConsumingClass(SomeTestClass someTestClass)
{
SomeTestClass = someTestClass;
}
[Fact]
private void Test()
{
var data = SomeTestClass.CreateSomeData();
// ....
SomeTestClass.DoSomeAction(...)
}
}
The test in SomeTestClass passes but the test in SomeConsumingClass fails with a message
Class fixture type 'Requirements.SomeTestClass' had one or more unresolved constructor arguments: SomeService someService) (The following constructor parameters did not have matching fixture data: SomeTestClass someTestClass
It seems like a feature like this is not directly supported as it seems to be looking for a parameterless constructor. I intended to use this pattern for each test class, therefore I am looking for some good way to do something similar without too much boilerplate code. Any suggestions on how I could provide methods from the other test classes without inheritance?
EDIT:
Added some additional examples how I imagine myself using this
From the xUnit documentation on Class Fixtures (emphasis added):
Note that you cannot control the order that fixture objects are created, and fixtures cannot take dependencies on other fixtures. If you have need to control creation order and/or have dependencies between fixtures, you should create a class which encapsulates the other two fixtures, so that it can do the object creation itself.
One solution would be to move the CreateSomeData method to SomeService, and then change SomeConsumingClass so that it also implements IClassFixture<SomeService>.
However, it's worth pointing out this line from the documentation regarding when IClassFixture is appropriate:
When to use: when you want to create a single test context and share it among all the tests in the class, and have it cleaned up after all the tests in the class have finished.
From the description you've provided, it doesn't seem clear to me that IClassFixture is necessary here, since all you really want is the ability to call CreateSomeData from different test classes. A dead-simple alternative would be to just move GetSomeData to a utility class that can be directly called from any test fixture that needs it.
So I played around with possible solutions and was able to come up with a solution which allows for identical behavior
public class SomeTestClass
{
private readonly SomeService SomeService;
public SomeTestClass(SomeService someService)
{
SomeService = someService;
}
[Fact]
private void Test()
{
//....
}
public SomeData CreateSomeData()
{
// populate fields with something based on internal/service state
return new SomeData();
}
public void DoSomeAction(....)
{
// does action which modifies internal/service state
}
}
public class SomeDerivingTestClass : SomeTestClass
{
public SomeDerivingTestClass() : base(CreateSomeService())
{
}
private static SomeService CreateSomeService()
{
return new SomeService();
}
}
public class SomeConsumingClass : IClassFixture<SomeDerivingTestClass>
{
private readonly SomeTestClass SomeTestClass;
public SomeConsumingClass(SomeDerivingTestClass someTestClass)
{
SomeTestClass = someTestClass;
}
[Fact]
private void Test()
{
var data = SomeTestClass.CreateSomeData();
// ....
SomeTestClass.DoSomeAction(...)
}
}
I have my test class inheriting from a base, which basically calls a Context method before the Facts, but xunit is calling context once per fact:
public class running_some_test : TestContext<ThingImTesting>
public void Because()
[Fact]
public void it_should_do_something()
[Fact]
public void it_should_do_more()
public void Context()
I know I could use the IClassFixture , but the TestContext inheritance is providing the test with Because() and Context() methods to override along with the type of SUT. I also think the IClassFixture is too generic, my context is very specific for each test criteria, and SetFixture seems more like a generic set up. Does anyone have a similar pattern that I could follow?
xunit instantiates a new object from your test class per fact. This is done to give each test it's own environment and to make parallelism easier. The recommended way to share context between tests in the same test class is the IClassFixture<T> interface.
You can add you Because() method to your fixture class if you need access to it in your tests. It looks to me like you're already doing something similar, only you're doing it with inheritance as opposed to composition. You can read up on how the interface works here: https://xunit.github.io/docs/shared-context.html#class-fixture
Example from the link:
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString");
// ... initialize data in the test database ...
}
public void Dispose()
{
// ... clean up test data from the database ...
}
public SqlConnection Db { get; private set; }
}
public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
DatabaseFixture fixture;
public MyDatabaseTests(DatabaseFixture fixture)
{
this.fixture = fixture;
}
// ... write tests, using fixture.Db to get access to the SQL Server ...
}
xunit injects the fixture class via your constructor, so you can do stuff the way you do them now, only you access fixture members via the injected parameter instead of via your super class.
I need to pass test data on class level but Theory and InlineData attributes can only be used on methods.
public class ContainerTests : TestFixture
{
private IContainer _container;
public ContainerTests(string containerName)
{
_container = CreateContainer(containerName);
}
[Fact]
public void ResolveJobFactory()
{
IJobFactory jobFactory = _container.Resolve<IJobFactory>();
}
private IContainer CreateContainer(string containerName)
{
if (containerName == "CastleWindsor")
{
return new WindsorContainerAdapter();
}
//other adapters
throw new NotImplementedException();
}
}
Is there a way to achieve something similar in xUnit.net?
Testing multiple implementations of an interface in a single test
class
Don't! Have a test class per implementation.
Edit: As per comments, I recommend having a base TestClass with all of the common tests, and then a Test Class per implementation which inherits from this base class.
I'm in the process of setting up tests in NUnit and have a newbie question.
Is it possible to have a Test/s that could be used in multiple [TestFixture]s?
So
[Test]ValidateString(string bob)
Could be called in a series of different [TestFixture]?
That doesn't sound like a test to me. Tests are typically parameterless (unless you're using [TestCase]s) and running it within a context of a single fixture would typically be enough -- it either passes once and that's good or it doesn't and it's a broken test.
If you just have a method that does some validation on a string, you could set it up as a static method on some class (e.g. TestHelpers) and call it from whatever tests (in multiple test fixtures) need it.
Here's another idea: inheritance. You can have a base fixture that has all your tests, and then fixtures that inherit from it that set up whatever variables you need. The tests will run for each fixture. I'm not familiar with Selenium RC, but you should be able to adapt the code below to set up whatever variables you need in various fixtures.
[TestFixture]
public class BaseFixtureTests
{
protected IMyClass _myClass;
[TestFixtureSetUp]
public void FixtureSetup()
{
_myClass = ConfigureMyClass();
}
protected virtual IMyClass ConfigureMyClass()
{
// fixtures that inherit from this will set up _myClass here as they see fit.
}
[Test]
public void MyClassTest1()
{
// test something about _myClass;
}
}
[TestFixture]
public class MySpecificFixture1 : BaseFixtureTests
{
protected override IMyClass ConfigureMyClass()
{
return new MySpecificMyClassImplementation();
}
}
public class MySpecificMyClassImplementation : IMyClass
{
//some implementation
}
You can also add extra tests in each fixture as well that don't test common functionality and don't need to be reused across fixtures.
The newer version of NUnit supports generics. This is a great fit if what you are testing doesn’t need to be configured (only created) from your test code. Here is an example copied from http://nunit.net/blogs/:
[TestFixture(typeof(ArrayList))]
[TestFixture(typeof(List<int>))]
public class IList_Tests<TList> where TList : IList, new()
{
private IList list;
[SetUp]
public void CreateList()
{
this.list = new TList();
}
[Test]
public void CanAddToList()
{
list.Add(1); list.Add(2); list.Add(3);
Assert.AreEqual(3, list.Count);
}
}
I’ve also used Anna’s approach of inheritance. One possible refinement to her example (depending on personal preference): Don’t mark the base class as a TestFixture, only the child classes. Each class that you mark as a TestFixture will be displayed as a set of tests in the NUnit client. You will probably never want to run the base class methods directly because the child is providing all of the setup code. If you remove TestFixture from the base class, running invalid tests won’t be an option in the UI. This allows you to run all the tests and see all green… always a nice feeling.
You might be able to achieve what you want with inheritance.
using NUnit.Framework;
namespace ClassLibrary1
{
[TestFixture]
public class TestFixtureBase
{
[SetUp]
public virtual void Setup()
{
// setup code here
}
[Test]
public void CommonTest1()
{
Assert.True(true);
}
[Test]
public void CommonTest2()
{
Assert.False(false);
}
}
public class MyClassTests : TestFixtureBase
{
[SetUp]
public override void Setup()
{
base.Setup();
// additional setup code
}
[Test]
public void MyClassTest1()
{
Assert.True(true);
}
}
}
You can write a method to be called from multiple [Test] methods. But I don't think there is a way to have the same [Test] included in multiple [TestFixture]s.
[TestFixture]
public class TestsOne{
[Test] public void TryOne(){
Helpers.ValidateString("Work?");
}
}
[TestFixture]
public class TestsTwo{
[Test] public void TryTwo(){
Helpers.ValidateString("Work?");
}
}
public static class Helpers{
public static void ValidateString(string s){
Assert.IsNotNull(s);
}
}