Testing: Call Context is lost
i need to store application information so i can reuse it in the next test.
but when i execute a series of (unit) tests it seems that each test is executed in a complete new environment thus loosing any information such as the call context. since i'm storing relevant application information in the call context this information gets recalculated before every test what is very time consuming. i don't understand the reason for this behaviour; is it on purpose or am i doing something wrong?
Each Test is executed statelessly -- that is to say that we reinstantiate the test class for every test method. This causes a small rpoblem if you have state with your objects -- which is not uncommon. However, there are a number of ways around this. But, at the same time, one has to remember that for unit tests, this is the behaviour that you want -- small quick test.
Work arounds:
[ClassInitialise] & [ClassCleanup] are called once per run per test class. This means you can use them to store state either in the TestContext or in a static member. Your tests classes can then access those "Code Under Test" classes to call the methods etc that need to be tested. Additionally, you can create a stateless init in the [TestInitialize] and store the data in the same place.
If have a lot of setup/tear down, you should take a look at ordered tests. These still have the same state issues, but would allow you to ensure that the state setup/tear down tests are executed in order rather than duplicating a lot of init code across classes or not getting full fidelity results.
i was not using local variables to store the app information - i was using the System.Runtime.Remoting.Messaging.CallContext. the call context is intended to be used when multiple assemblies in the same application domain need to share some information.
for that reason i don't agree - at least partially - with the statement that this is the behaviour to expect from unit tests. lets say i have a larger application with several assemblies and i want to run an ordered test that include several unit tests; i test one assembly and put some return information in the call context; i test another assembly and put some more information in the call context; and so on. in this case i do expect the call context to be the same, that means to contain the information previously stored within. we can dicuss about that when several single unit tests are run but i don't think there's a good argument against it when an ordered test that includes several unit tests is run.
anyway, i changed my tests to store the information in local static variables as well. this way i have to read back the call context in every [teardown] and reload it in every [initialize]... so much for the expected behaviour... ;-)
I'm not a remoting expert, so I apologise :)
Could you provide a simple repro for this? I'd like to investigate and see if this might be mitigated. If you wish to email, you can deduce my email addres by removing MSFT :)
sorry for not answering so long - i didn't see your response.
here's a simple repro (quick and dirty from my mind - hope i didn't miss anything):
1. create a new solution.
2. add a new class library project.
3. add a new class.
4. add the "using System.Runtime.Remoting.Messaging;" statement.
5. create the following property:
private string xy
{
get { return (string)CallContext.GetData(("Test"); }
set { CallContext.SetData("Test", value); }
}
6. create a method that sets any value to this property.
7. repeat steps 2-5.
8. create a method that gets and checks the value from this property.
9. add a new test project.
10. add a test for each of the two methods in the two classes.
11. add an ordered test that runs the tests in the order we created the classes.
12. run the ordered test.i explained the reasons for this architecture in the posts above.
if you got any questions or if the repro is not working, just tell me.