Run same tests for multiple ICollectionFixture in xUnit
Asked Answered
T

0

6

I am curious if there is a solution for running the same tests for multiple ICollectionFixtures. Like having InlineData, but over the whole test class, not only a method.

I need this functionality because I want to see if the tests are passing for different configurations (a switch, or connection string), that are being set in the ICollectionFixture.

For Example, I have the following fixtures:

public abstract class BaseTestConfigurationFixture : ConfigurationFixture<BaseTestConfigurationFixture>
{
    public BaseTestConfigurationFixture(bool shouldConfigure)
    {
        /// Configure 
    }
}

public class TestConfigurationFixtureVersionA : ConfigurationFixture<TestConfigurationFixtureVersionA>
{
    public TestConfigurationFixtureVersionA()
        : base(false)
    { }
}

public class TestConfigurationFixtureVersionB : ConfigurationFixture<TestConfigurationFixtureVersionB>
{
    public TestConfigurationFixtureVersionB()
        : base(true)
    { }
}

Now, I use those fixtures in the following collections:

public abstract class BaseTestEnvironmentCollection : ICollectionFixture<BaseTestConfigurationFixture>
{
    // This class has no code, and is never created. Its purpose is simply
    // to be the place to apply [CollectionDefinition] and all the
    // ICollectionFixture<> interfaces.     
}

[CollectionDefinition(nameof(TestEnvironmentCollectionVersionA))]
public class TestEnvironmentCollectionVersionA: ICollectionFixture<TestConfigurationFixtureVersionA>
{
    // This class has no code, and is never created. Its purpose is simply
    // to be the place to apply [CollectionDefinition] and all the
    // ICollectionFixture<> interfaces.     
}

[CollectionDefinition(nameof(TestEnvironmentCollectionVersionB))]
public class TestEnvironmentCollectionVersionB: ICollectionFixture<TestConfigurationFixtureVersionB>
{
    // This class has no code, and is never created. Its purpose is simply
    // to be the place to apply [CollectionDefinition] and all the
    // ICollectionFixture<> interfaces.     
}

I want my tests to run once with the configurations from TestEnvironmentCollectionVersionA, and then with the configurations from TestEnvironmentCollectionVersionB.

I also need to access BaseTestConfigurationFixture inside my test class. This seems to cause problems, because if I annotate the test class only with one of my collection fixtures, [Collection(nameof(TestEnvironmentCollectionVersionA))], I get the following error:

Message: The following constructor parameters did not have matching fixture data: BaseTestConfigurationFixture testConfigurationFixture

This error does not appear if I use only one TestFixture and CollectionFixture, without inheritance.

I see that there is a restriction over [CollectionAttribute], to not accept multiple such attributes.

What method should I consider, in order to achieve this functionality?

Thank you!

EDITED: Found the fix for the error bellow

The following constructor parameters did not have matching fixture data: BaseTestConfigurationFixture testConfigurationFixture

Tallou answered 10/1, 2020 at 16:36 Comment(4)
Each test should be atomic. Each test should have its own setups. Dont reuse configurations or values from test to test. Set up the configuration for each test.Viscount
Is this what you're looking for?Avocation
@Josh I agree, the tests should be atomic, and they are, for each method. But as we have the [Theory] with [InlineData], [MemberData] and [ClassData] attributes, I need something for global configuration. In my case, the variables for which the methods that I am unit testing should pass, are not the arguments, but the Environment Variables and AppSettings.Tallou
@Avocation Thank you for your help. Unfortunately, I am looking for a way to pass different environment variables to my tests, not parameters. The [InlineData], [MemberData] and [ClassData] were designed for different parameters.Tallou

© 2022 - 2024 — McMap. All rights reserved.