Search code examples
c#automated-testsnunit

How to pass a value from one test to another one?


I am part of a developers team maintaining multiple B2B .NET APIs under regulations.

For each release, we deploy the release branch to our dev environment then we do a series of queries manually in swagger:

  1. create a customer
  2. Create a cart
  3. Add a subscription in the cart
  4. Checkout the cart
  5. Confirm the bought subscription is registered to the customer
  6. Suspending the subscription
  7. Reactivating the subscription
  8. Etc.

We are already doing our unit tests in nunit. Some API partner may take like 5 minutes to response for a POST, like creating a customer.

We are considering to use nunit to automate this process and break knowingly rules that tests should be independent and should be run on any order.

How could we technically pass the result of a test to another test?

Examples:

  1. When the customer is created, the next test should know the created CustomerId.
  2. When a subscription is created, the next test should know the SubscriptionId.
  3. Etc.

Thank you!


Solution

  • For NUnit you can use the SetUpFixture which is:

    the attribute that marks a class that contains the one-time setup or teardown methods for all the test fixtures in a given namespace including nested namespaces below, within an assembly.

    So you just place class marked with the attribute into the root of the test project (and root namespace) and perform the needed actions as a one time setup creating the "shared" data (obviously you can have multiple such fixtures when different sets of data are needed for some subsets of tests):

    [SetUpFixture]
    public class RootSetup
    {
        // Use it in all tests
        // also consider making User an immutable type
        public static readonly User UserForAllTests; 
        
        [OneTimeSetUp]
        public void RunBeforeAnyTests()
        {
            User = ... // get user
        }
    }
    

    Also you can use the OneTimeSetUp on per test class basis which can be combined with Order:

    public class MySetOfScenarios
    {
        private int I;
        private int J;
    
        [OneTimeSetUp]
        public void BaseSetUp()
        {
            J = 7;
        }
        
        [Test, Order(1)]
        public void TestA()
        {
            I = 42;
            TestContext.Out.WriteLine(J); // Outputs 7
            J = 1;
        }
    
        [Test, Order(2)]
        public void TestB()
        {
            TestContext.Out.WriteLine(I); // Outputs 42
            TestContext.Out.WriteLine(J); // Outputs 1
        }
    }
    

    Note that the Order approach in general is discouraged and there are some caveats. For example NUnit does not enforce (as far as I can see) "previous" test to be run if you run only one of the "following" i.e. the #2 test will fail if it would be run independently (if it relies on the data from #1).