I’m curious if anyone has come up with a good strategy for testing multithreaded apps.
I do alot of testing with midje, which is great for testing functions… but I’m not really sure how to test multithreaded code without it looking really hacky:
(fact "the state is modified by a thread call"
(Thread/sleep 100)
(check-state-eq *state* nil)
(Thread/sleep 100)
(modify-state-thread-call *state* :updated-value)
(Thread/sleep 100)
(check-state-eq *state* :updated-value))
Sometimes, because of compilation time, my tests fail because a state was not updated in time, so then I have to sleep for longer. Ideally, I would want a way to write something like:
(fact "the state is modified by a thread call"
(modify-state-thread-call *state* :updated-value)
=leads-to=> (check-state-eq *state* :updated-value))
and move away from the sleeps. Are there strategies to do that?
If
*state*in this example is one of the clojure reference types, you can add a function that is notified of every change to that object using add-watch: http://clojuredocs.org/clojure_core/clojure.core/add-watchAn approach I might suggest is to use a watch to deliver a promise when the condition is satisfied.
This will return true immediately if
*state*takes on a value that satisfiessome-checkwithin 1000ms, or after 1000ms if the condition is not met, returns false.