Найти в Дзене
CLLAX

Unit-testing for multi-threaded code – how should this be approached?

A question that often arises in development teams is “how do you approach unit-testing for multi-threaded code”? The thing that concerns developers is of course, the order of execution which can be difficult to control when the code is particularly complex. However, while ignoring testing can seem tempting – it’s important to test all of your code. Here are some ideas on how to approach it: Force the code to execute in a synchronous manner Given that a unit-test has the most value when it can be reproduced and executed again and again, multi-threaded code presents real challenges. We’ve found that one method that can help is forcing asynchronous code to be executed synchronously. The method involves taking the core logic and then reassigning it to a separate class. The content which is not synchronous is executed by the core logic. You should be able to map the path of the calls made by the core logic – and thus produce repeatable unit-tests. However, at Typemock we have a preferable

A question that often arises in development teams is “how do you approach unit-testing for multi-threaded code”? The thing that concerns developers is of course, the order of execution which can be difficult to control when the code is particularly complex. However, while ignoring testing can seem tempting – it’s important to test all of your code. Here are some ideas on how to approach it:

Force the code to execute in a synchronous manner

Given that a unit-test has the most value when it can be reproduced and executed again and again, multi-threaded code presents real challenges. We’ve found that one method that can help is forcing asynchronous code to be executed synchronously.

The method involves taking the core logic and then reassigning it to a separate class. The content which is not synchronous is executed by the core logic. You should be able to map the path of the calls made by the core logic – and thus produce repeatable unit-tests. However, at Typemock we have a preferable solution:

Make the code simpler to execute

We think that when code becomes too complex to test there’s probably a good business case for revisiting that code and making it simpler. The best place to start might be with the actual design where you can start looking at options that make tracking threads more straightforward.

You should seek to make your objects immutable. If you can’t, then you should concentrate your efforts on reducing the volume of thread interactions. You may not eliminate all the multi-threading but you should be able to get it down to a point where it’s manageable enough to begin developing test cases.

If you’re still finding it difficult to test all the situations when threads interact, the best approach is to try and control the order of line execution during the test. This does require the use of a simulation and that means coding for testing…something we don’t really recommend.

Your best option is to look at static code testing to try and work through your multi-threaded code. If you ensure that you limit the number of possible permutations to a finite number, you’ll find that this is an effective way to approach the problem. If you have an infinite number of permutations then it’s probably best to revisit the code development and simplify again. Tight code is always easier to test.