Home > Mobile >  NUnit use different objects as Test Cases
NUnit use different objects as Test Cases

Time:10-19

I am trying to write an Update Test for different products (which are classes in this case) and different time steps :

public class UpdateTest 
{
    private static Product ProductLastYear;
    private static Product ProductTwoYearsAgo;
    public UpdateTest(Product product)
    {
        var previousReleasedProducts = new Products();
        ProductLastYear = previousReleasedProducts.GetProduct(Years.GetLastYear());
        ProductTwoYearsAgo = previousReleasedProducts.GetProduct(Years.GetTwoYearsAgo());
    }

Each product needs to be installed, and afterwards it is checked if the installation was successful (this is basically a pre-step before the Update). Right now, I am using two Tests for this:

[Test, Category("UpdateLastYear")), Order((int) NunitTestOrderEnum.Order.First)]
public void InstallPreviousReleasedProduct()
{
    using (var controller = new BootstrapperController(ProductLastYear))
    {
        controller.Install();
    }

    var successfulInstallation = InstallationValidator.ValidateInstall(ProductLastYear);
    Assert.That(successfulInstallation, Is.True);
}

[Test, Category("UpdateTwoYearsAgo"), Order((int) NunitTestOrderEnum.Order.First)]
public void InstallTwoYearsAgoProduct()
{
    using (var controller = new BootstrapperController(ProductTwoYearsAgo))
    {
        controller.Install();
    }

    var successfulInstallation = InstallationValidator.ValidateInstall(ProductTwoYearsAgo);
    Assert.That(successfulInstallation, Is.True);
}

Now, both tests have some code redundancy, which I would like to avoid. I was thinking about using TestCases for this, something like :

[TestCase(ProductLastYear), Category("UpdateLastYear"), Order((int) NunitTestOrderEnum.Order.First)]
[TestCase(ProductTwoYearsAgo), Category("UpdateTwoYearsAgo"), Order((int) NunitTestOrderEnum.Order.First)]
public void InstallPreProduct(Product product)
{
    using (var controller = new BootstrapperController(product))
    {
        controller.Install();
    }

    var successfulInstallation = InstallationValidator.ValidateInstall(product);
    Assert.That(successfulInstallation, Is.True);
}

Is something like this possible? I tried different Syntax for that approach, but it does not seem to work that easily.

CodePudding user response:

You can only use compile-time constants within attributes. However your static fields are no constants.

You can use the TestCaseSource-attribute:

[TestCaseSource(nameof(ProvideTestcases))]
public void InstallPreProduct(Product product)
{
    using (var controller = new BootstrapperController(product))
    {
        controller.Install();
    }

    var successfulInstallation = InstallationValidator.ValidateInstall(product);
    Assert.That(successfulInstallation, Is.True);
}
public static IEnumerable<TestCaseData> ProvideTestcases()
{
    yield return new TestCaseData(ProductLastYear).SetCategory("UpdateLastYear");
    yield return new TestCaseData(ProductTwoYearsAgo).SetCategory("UpdateTwoYearsAgo");
}

However that assumes your static fields are already initialized, which isn't the case. So you need a static constructor for your testclass.

[TestFixture]
public UpdateTest
{
    public static ProductLastYear;
    public static ProductTwoYearsAgo;

    static 
    {
        ProductLastYear = ...;
        ProductTwoYearsAgo = ...;
    }
}

This is pretty much boilerplate for so little duplication. So it's a tradeoff if or of it not this is worth the afford.

Another opportunity is to introduce some static constant, like an enum that reflects the property to be used:

[TestCase(MyEnum.LastYear), Category("UpdateLastYear")]
[TestCase(MyEnum.TwoYearsAgo), Category("UpdateTwoYearsAgo")]
public void InstallPreProduct(MyEnum product)
{
    var Product = product == MyEnum.LastYear ? 
        ProductLastYear : 
        ProductTwoYearsAgo ;
    using (var controller = new BootstrapperController(product))
    {
        controller.Install();
    }

    var successfulInstallation = InstallationValidator.ValidateInstall(product);
    Assert.That(successfulInstallation, Is.True);
}

An enum is a constant expression, so you can easily use it within the test-attributes.

  • Related