Повторите попытку Visual Studio C # TestMethod - PullRequest
4 голосов
/ 30 июля 2010

Мне любопытно узнать, есть ли какой-либо встроенный механизм для повтора испытаний в рамках модульного тестирования Visual Studio 2008 для C #.Например, у меня есть модульный тест на C #, который выглядит примерно так:

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

Теперь время от времени DoSomething() работает плохо;в этом случае я бы хотел перезапустить метод DoSomething(), прежде чем достигнуть утверждения.Очевидно, я могу сделать что-то вроде:

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

Хотя это немного громоздко из-за добавленного цикла и повторения инициализации теста, которая в противном случае была бы полностью обработана другими методами / конструктором класса.* Мой вопрос заключается в том, существует ли более удобный механизм для повторения теста, например:

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

, который автоматически повторяет тест без регистрации его как сбоя при выполнении всехобычный код инициализации как обычно.

Ответы [ 2 ]

8 голосов
/ 30 июля 2010

Серьезно ...

иногда DoSomething () работает плохо

Тест должен быть зеленым каждый раз.Если тестируемый код иногда работает «плохо», то вам нужно исправить свой код, изолируя другое поведение.У вас должно быть два теста, один, где он подтверждает правильность при сбое DoSomething (и предполагается, что он потерпит неудачу), и один, где он подтверждает правильность, когда DoSomething в порядке (и должен быть в порядке).в тесте просто неверно ИМО.Вы всегда должны утверждать об ожидаемом результате, и вы должны быть в состоянии изолировать и обработать ваш код так, чтобы он возвращал то, что вы ожидаете.

[Правка - добавлен некоторый код, который можно использовать для цикла повторных попыток]

Вы можете создать оболочку цикла, которая принимает любой метод и вызывает его X раз или до тех пор, пока он не будет успешным.Вы также можете сделать так, чтобы функция Loop вызывала ваш init или передавала его как отдельный аргумент.Метод также может вернуть bool в случае успеха.Измените подпись в соответствии с вашими потребностями.

[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;
    }
}
1 голос
/ 30 июля 2010

Ваш второй пример - почти такие же строки кода и такая же сложность. Есть тонны способов его обрезать, вы могли бы не то чтобы я выступал за использование рекурсии.

[TestMethod]
public void MyMethod() {
   bool success = DoSomething();
   Assert.IsTrue(success);
}

public boolean DoSomething(){
    //Do whatever

    if(performedOk){
       return true;
    }else{
        //find a way to stop it.
    }

}

Но дело в том, что это юнит-тест. Если что-то вызывает ошибку, вам нужно найти способ изолировать ваш тест, чтобы он находился в контролируемой среде.

Если у вас нет требования, согласно которому тест должен пройти в конце концов. Лучшая логика повторения, которую вы должны использовать, - после сбоя. Нажмите на тест и снова нажмите «Выполнить».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...