Сообщение Re: Как тестировать многопоточные штуки? от 17.02.2025 4:41
Изменено 17.02.2025 4:42 vsb
Re: Как тестировать многопоточные штуки?
Нормального способа такое тестировать я не знаю.
Если прям сильно надо — я бы так поступил:
1. Сделать спец-интерфейс вида interface DebugSynchronization { void wait(String point); }.
2. В реализацию класса пробросить этот интерфейс и во всех интересующих точках вызывать debugSynchronization.wait("pointname").
3. В продакшне использовать реализацию с пустым методом.
4. Для тестов использовать специальную реализацию, которой можно управлять. Т.е. запускаем интересующий нас метод в отдельном потоке, а из потока-теста вызываем что-то вроде waitForArrival("pointname"), resume("pointname"). Эти методы останавливают вызывающий поток, пока целевой поток не дойдёт до указанной точки (в этот момент тестируемый поток останавливается в wait) или продолжают выполнение тестируемого потока, который остановился в указанной точке.
Собственно таким образом внутри тестов можно смоделировать любую последовательность выполнения участков кода, имитируя переключение потоков "вручную". При этом тест будет полностью детерминированным.
Наверняка я не первый это придумал и такое уже есть в готовом виде.
Если прям сильно надо — я бы так поступил:
1. Сделать спец-интерфейс вида interface DebugSynchronization { void wait(String point); }.
2. В реализацию класса пробросить этот интерфейс и во всех интересующих точках вызывать debugSynchronization.wait("pointname").
3. В продакшне использовать реализацию с пустым методом.
4. Для тестов использовать специальную реализацию, которой можно управлять. Т.е. запускаем интересующий нас метод в отдельном потоке, а из потока-теста вызываем что-то вроде waitForArrival("pointname"), resume("pointname"). Эти методы останавливают вызывающий поток, пока целевой поток не дойдёт до указанной точки (в этот момент тестируемый поток останавливается в wait) или продолжают выполнение тестируемого потока, который остановился в указанной точке.
Собственно таким образом внутри тестов можно смоделировать любую последовательность выполнения участков кода, имитируя переключение потоков "вручную". При этом тест будет полностью детерминированным.
Наверняка я не первый это придумал и такое уже есть в готовом виде.
Re: Как тестировать многопоточные штуки?
Нормального способа такое тестировать я не знаю.
Если прям сильно надо — я бы так поступил:
1. Сделать спец-интерфейс вида interface DebugSynchronization { void wait(String point); }.
2. В реализацию класса пробросить этот интерфейс и во всех интересующих точках вызывать debugSynchronization.wait("pointname").
3. В продакшне использовать реализацию с пустым методом.
4. Для тестов использовать специальную реализацию, которой можно управлять. Т.е. запускаем интересующий нас метод в отдельном потоке, а из потока-теста вызываем что-то вроде waitForArrival("pointname"), resume("pointname"). Эти методы останавливают вызывающий поток, пока целевой поток не дойдёт до указанной точки (в этот момент тестируемый поток останавливается в wait) или продолжают выполнение тестируемого потока, который остановился в указанной точке.
Собственно таким образом внутри тестов можно смоделировать любую последовательность выполнения участков кода, имитируя переключение потоков "вручную". При этом тест будет полностью детерминированным.
Наверняка я не первый это придумал и такое уже есть в готовом виде.
Тут, конечно, не очень красиво получается, что в обычный код просочился тестовый. Ну лучше варианта не знаю.
Если прям сильно надо — я бы так поступил:
1. Сделать спец-интерфейс вида interface DebugSynchronization { void wait(String point); }.
2. В реализацию класса пробросить этот интерфейс и во всех интересующих точках вызывать debugSynchronization.wait("pointname").
3. В продакшне использовать реализацию с пустым методом.
4. Для тестов использовать специальную реализацию, которой можно управлять. Т.е. запускаем интересующий нас метод в отдельном потоке, а из потока-теста вызываем что-то вроде waitForArrival("pointname"), resume("pointname"). Эти методы останавливают вызывающий поток, пока целевой поток не дойдёт до указанной точки (в этот момент тестируемый поток останавливается в wait) или продолжают выполнение тестируемого потока, который остановился в указанной точке.
Собственно таким образом внутри тестов можно смоделировать любую последовательность выполнения участков кода, имитируя переключение потоков "вручную". При этом тест будет полностью детерминированным.
Наверняка я не первый это придумал и такое уже есть в готовом виде.
Тут, конечно, не очень красиво получается, что в обычный код просочился тестовый. Ну лучше варианта не знаю.