Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retry a Visual Studio C# TestMethod

I'm curious to know if there's any built-in mechanism to retry tests in the Visual Studio 2008 unit testing framework for C#. Case in point, I have a C# unit test which looks something like:

[TestMethod]
public void MyMethod() {
    DoSomething();
    Assert.Something();
}

Now, occasionally DoSomething() performs badly; in that case I would like to rerun the DoSomething() method before reaching the assertion. Obviously I can do something like:

...
do {
    Initialization();
    DoSomething();
} while (PerformedOK() == false);
Assert.Something();
...

Though this is a bit cumbersome because of the added loop and repeating the test initialization which would otherwise be completely handled by other methods / class constructor.

My question is whether there is a more convenient mechanism for retrying a test, something like:

DoSomething();
if (PerformedOK() == false) Retry();
else Assert.Something();

which will automatically retry the test without registering it as a failure, while performing all the regular initialization code as usual.

like image 991
Oak Avatar asked Jul 30 '10 18:07

Oak


1 Answers

Seriously...

occasionally DoSomething() performs badly

A test should be green every time. If the tested code sometimes perform "badly", then you need to fix your code, isolating the different behavior. You should have two test, one where it Asserts correct when DoSomething fails (and is supposed to fail), and one where it Asserts correct when DoSomething is ok (and is supposed to be ok).

Having retry logic in a test is just wrong imo. You should always Assert on the expected outcome, and you should be able to isolate and instrument your code to return what you expect.

[Edit - added some code which could be used for a retry loop]

You could create a loop wrapper which takes whatever method in and calls it X number of times, or until it succeeds. You could also have the Loop function call your init, or pass it as a separate argument. The method could also return a bool if successful. Change the signature to fit your needs.

[TestMethod]
public void something()
{
   Loop.LoopMe(TestMethod,3);            
   Assert.Something();
}

class Loop
{
    public static void LoopMe(Action action, int maxRetry)
    {
        Exception lastException = null;
        while (maxRetry > 0)
        {
            try
            {
                action();
                return;
            }
            catch (Exception e)
            {
                lastException = e;
                maxRetry--;                    
            }                
        }
        throw lastException;
    }
}
like image 159
Mikael Svenson Avatar answered Sep 30 '22 18:09

Mikael Svenson