Использование TDD для вывода поточно-ориентированного кода - PullRequest
10 голосов
/ 11 февраля 2009

Какой хороший способ использовать TDD для вывода поточно-ориентированного кода? Например, скажем, у меня есть фабричный метод, который использует отложенную инициализацию для создания только одного экземпляра класса и возвращает его после этого:

private TextLineEncoder textLineEncoder;
...
public ProtocolEncoder getEncoder() throws Exception {
    if(textLineEncoder == null)
        textLineEncoder = new TextLineEncoder();
    return textLineEncoder;
}

Теперь я хочу написать тест в хорошем TDD-стиле, который заставит меня сделать этот код поточно-ориентированным. В частности, когда два потока вызывают этот метод одновременно, я не хочу создавать два экземпляра и отбрасывать один. Это легко сделать, но как мне написать тест, который заставит меня это сделать?

Я спрашиваю об этом на Java, но ответ должен быть более применимым.

Ответы [ 6 ]

5 голосов
/ 11 февраля 2009

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

 textLineEncoder = new TextLineEncoder();

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

3 голосов
/ 11 февраля 2009

Это сложно, хотя возможно - возможно, сложнее, чем стоит. Известные решения включают в себя инструментирование тестируемого кода. Обсуждение здесь, "Чрезвычайная проблема программирования четырнадцати" стоит просеять.

2 голосов
/ 17 ноября 2009

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

2 голосов
/ 06 марта 2009

В книге Чистый код есть несколько советов о том, как тестировать параллельный код. Один совет, который помог мне найти ошибки параллелизма, - это одновременное выполнение большего количества тестов, чем у процессора.

В моем проекте выполнение тестов на моей четырехъядерной машине занимает около 2 секунд. Когда я хочу протестировать параллельные части (для этого есть несколько тестов), я удерживаю в IntelliJ IDEA горячую клавишу для запуска всех тестов, пока не увижу в строке состояния, что выполняется 20, 50 или 100 тестовых прогонов. Я следую в диспетчере задач Windows за использованием ЦП и памяти, чтобы узнать, когда все тестовые прогоны закончили выполняться (использование памяти увеличивается на 1-2 ГБ, когда все они запущены, а затем медленно снижается).

Затем я закрываю один за другим все диалоговые окна вывода тестового прогона и проверяю, не было ли сбоев. Иногда бывают неудачные тесты или тесты, которые находятся в тупике, и затем я исследую их, пока не найду ошибку и не исправлю ее. Это помогло мне найти пару неприятных ошибок параллелизма. При столкновении с исключительной / тупиковой ситуацией, которая не должна была произойти, самое главное, всегда предполагать, что код нарушен, безжалостно исследовать причину и исправлять ее. Нет космических лучей, которые вызывают случайный сбой программ - ошибки в коде приводят к сбою программ.

Существуют также структуры, такие как http://www.alphaworks.ibm.com/tech/contest, которые используют манипуляции с байт-кодом, чтобы заставить код выполнять большее переключение потоков, что увеличивает вероятность появления ошибок параллелизма.

1 голос
/ 11 февраля 2009

Глава 12 Java-параллелизма на практике называется "Тестирование параллельных программ". Он документирует тестирование на безопасность и жизнеспособность, но говорит, что это сложный вопрос. Я не уверен, что эта проблема разрешима инструментами этой главы.

0 голосов
/ 11 февраля 2009

Вы можете сравнить возвращенные экземпляры, чтобы понять, действительно ли это один и тот же экземпляр или они разные? Это, вероятно, где я бы начал с C #, я думаю, вы можете сделать то же самое в Java

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