Как мне выполнить модульное тестирование многопоточного кода? - PullRequest
643 голосов
/ 15 августа 2008

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

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

Ответы [ 25 ]

0 голосов
/ 20 июня 2018

Параллельность - это сложное взаимодействие между моделью памяти, оборудованием, кешами и нашим кодом. В случае Java, по крайней мере, такие тесты были частично рассмотрены в основном jcstress . Известно, что создатели этой библиотеки являются авторами многих функций параллелизма JVM, GC и Java.

Но даже эта библиотека нуждается в хороших знаниях спецификации Java Memory Model, чтобы мы точно знали, что мы тестируем. Но я думаю, что основное внимание в этом усилии уделяется миробенчмаркам. Не огромные бизнес-приложения.

0 голосов
/ 09 апреля 2018

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

Например, если код тестируемого объекта вызывает новый поток, подобный этому

Class TestedClass {
    public void doAsychOp() {
       new Thread(new myRunnable()).start();
    }
}

Тогда может помочь насмешка над новыми потоками и последовательный запуск аргумента runnable

@Mock
private Thread threadMock;

@Test
public void myTest() throws Exception {
    PowerMockito.mockStatic(Thread.class);
    //when new thread is created execute runnable immediately 
    PowerMockito.whenNew(Thread.class).withAnyArguments().then(new Answer<Thread>() {
        @Override
        public Thread answer(InvocationOnMock invocation) throws Throwable {
            // immediately run the runnable
            Runnable runnable = invocation.getArgumentAt(0, Runnable.class);
            if(runnable != null) {
                runnable.run();
            }
            return threadMock;//return a mock so Thread.start() will do nothing         
        }
    }); 
    TestedClass testcls = new TestedClass()
    testcls.doAsychOp(); //will invoke myRunnable.run in current thread
    //.... check expected 
}
0 голосов
/ 26 сентября 2017

Для кода J2E я использовал SilkPerformer, LoadRunner и JMeter для параллельного тестирования потоков. Они все делают одно и то же. По сути, они предоставляют вам относительно простой интерфейс для администрирования своей версии прокси-сервера, необходимый для анализа потока данных TCP / IP и моделирования одновременного выполнения запросов несколькими пользователями на сервере приложений. Прокси-сервер может дать вам возможность выполнять такие вещи, как анализ выполненных запросов, представляя всю страницу и URL-адрес, отправленный на сервер, а также ответ от сервера после обработки запроса.

Вы можете найти некоторые ошибки в небезопасном режиме http, где вы можете по крайней мере проанализировать отправляемые данные формы и систематически изменять их для каждого пользователя. Но настоящие тесты - это когда вы работаете в https (Secure Socket Layers). Затем вам также придется бороться с систематическим изменением данных сеанса и файлов cookie, что может быть немного более запутанным.

Лучшая ошибка, которую я когда-либо обнаруживал при тестировании параллелизма, заключалась в том, что я обнаружил, что разработчик полагался на сборку мусора Java для закрытия запроса на подключение, который был установлен при входе, на сервер LDAP при входе. пользователи, подвергающиеся сеансам других пользователей и получающие очень запутанные результаты, когда пытаются проанализировать, что произошло, когда сервер оказался на коленях, едва могут выполнить одну транзакцию каждые несколько секунд.

В конце концов, вам или кому-то, вероятно, придется сгибаться и анализировать код на наличие грубых ошибок, подобных тому, который я только что упомянул. И наиболее полезными являются открытые дискуссии между департаментами, подобные тем, которые произошли, когда мы раскрыли описанную выше проблему. Но эти инструменты являются лучшим решением для тестирования многопоточного кода. JMeter является открытым исходным кодом. SilkPerformer и LoadRunner являются собственностью. Если вы действительно хотите знать, является ли ваше приложение потокобезопасным, именно так поступают большие мальчики. Я сделал это для очень крупных компаний профессионально, так что я не думаю. Я говорю из личного опыта.

Слово предостережения: для понимания этих инструментов требуется некоторое время. Это не будет вопросом простой установки программного обеспечения и запуска графического интерфейса, если вы уже не знакомы с многопоточным программированием. Я попытался определить 3 критические категории областей для понимания (формы, данные сеансов и файлы cookie), надеясь, что, по крайней мере, начиная с понимания этих тем, вы сможете сосредоточиться на быстрых результатах, а не на том, чтобы читать через вся документация.

0 голосов
/ 04 июля 2013

(если возможно) не используйте потоки, используйте актеры / активные объекты. Легко проверить.

0 голосов
/ 13 января 2014

Вы можете использовать EasyMock.makeThreadSafe, чтобы сделать тестовый экземпляр безопасным

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