Тестирование на тупик с помощью nUnit - PullRequest
6 голосов
/ 23 января 2009

Я новичок в модульном тестировании и nUnit (2.48). Я хотел бы написать тестовый метод, в котором случай сбоя заключается в том, что он блокируется. Это возможно? Очевидно, что по умолчанию nUnit не знает, сколько времени должно занять выполнение метода, поэтому мне нужно было бы написать код для выполнения работы в отдельном потоке, а затем прервать его и выдать исключение, если это заняло больше времени, чем я определил? Есть ли лучший способ сделать это?

Спасибо

Ответы [ 5 ]

7 голосов
/ 23 января 2009

Что ж, безусловно, можно проверить на взаимоблокировку, запустив код в другом потоке и посмотрев, вернется ли он своевременно. Вот некоторый (очень простой) пример кода:

[TestFixture]
public class DeadlockTests
{
    [Test]
    public void TestForDeadlock()
    {
        Thread thread = new Thread(ThreadFunction);
        thread.Start();
        if (!thread.Join(5000))
        {
            Assert.Fail("Deadlock detected");
        }
    }

    private void ThreadFunction()
    {
        // do something that causes a deadlock here
        Thread.Sleep(10000);
    }
}

Я бы не хотел сказать, что это «лучший способ», но я нашел его полезным в некоторых случаях.

5 голосов
/ 23 января 2009

Обнаружение взаимоблокировки эквивалентно проблеме остановки , и, следовательно, в настоящее время не решаемо в общем случае.

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

5 голосов
/ 23 января 2009

Возможно, но это может быть не лучшим решением. Модульные тесты не очень подходят для тестирования поведения параллелизма, к сожалению, не так много подходящих методов тестирования.

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

Другая проблема заключается в том, что поведение взаимоблокировки обычно зависит от порядка, в котором запланированы потоки. Поэтому было бы трудно написать убедительный тест для проверки определенной проблемы взаимоблокировки, поскольку у вас нет никакого контроля над планированием потоков, это сделано ОС. Вы можете получить тесты, которые иногда дают сбой на многоядерных процессорах, но всегда дают успех на одноядерных процессорах.

4 голосов
/ 23 января 2009

Взгляните на проект Microsoft под названием «Шахматы». Он предназначен для поиска совпадающих ошибок http://research.microsoft.com/en-us/projects/chess/

3 голосов
/ 23 января 2009

Чтобы проверить наличие тупика, вы должны реализовать график состояний и проверку циклов в своем графике текущего состояния в модульном тесте. Граф состояний состоит из ресурсов в виде узлов и зависимостей в виде ребер. Я не имею представления о реализации такой вещи, но это теория.

Модульный тест проверяет правильность ввода и вывода данных (в основном для более поздней точки), а не правильность потока выполнения вашего приложения.

Идея Марка Хита кажется разумной, но академически неверна.

...