The problem that I encountered in the past is that it is deceptively simple ... first. Nesting contexts are great until you reach your second level of inheritance. Suddenly, you lose track of the world in which your tests live, if you do not dive through 3 levels of the hierarchy and do not take many notes, draw maps, throw runes, etc.
I welcome the approach in which the mechanism for setting context is directly guided by the test itself. Each test class represents one context, which it sets up independently, or using an external set of helpers to create the necessary objects. Thus, I can always look at the method of initializing the test and see at least a high-level description of what the "world" looks like tests in this class.
Let the helpers make the most of each other, but the test setup itself should resemble something like this pseudocode: Given_a_valid_Customer (). WithValidOrders (2) .WithInvalidOrders (1);
Given_a_valid_Customer should configure the client and any required child objects, such as Addresses. .WithValidOrders (2) adds two valid orders, including any child objects, such as LineItems. Finally, .WithInvalidOrders adds another order with some fatal error.
The fact is that the installation is not bogged down in detail. What makes an order valid or invalid? To whom this is important, this is not what this test is about. This test only takes care that there is an incorrect order among several valid ones, and this is the only detail that is important here. An Invalid Order definition can be defined elsewhere and then invoked by several test contexts. If something about this definition changes later, then it can be "flipped" in this helper method, and not in hundreds of separate tests.
When I look at this test, I know how his world looks with exactly the level of detail that I care about.
source share