在clojure中有没有好的库或策略来测试多线程应用程序?

在clojure中有没有好的库或策略来测试多线程应用程序?,clojure,Clojure,我很好奇是否有人想出了一个测试多线程应用程序的好策略 我用midje做了很多测试,这对测试函数非常有用。。。但我不太确定如何测试多线程代码,而不让它看起来很黑: (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* :up

我很好奇是否有人想出了一个测试多线程应用程序的好策略

我用midje做了很多测试,这对测试函数非常有用。。。但我不太确定如何测试多线程代码,而不让它看起来很黑:

  (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))
有时,由于编译时间的原因,我的测试失败,因为状态没有及时更新,所以我不得不睡更长的时间。理想情况下,我希望有一种方式来写:

  (fact "the state is modified by a thread call"
    (modify-state-thread-call *state* :updated-value) 
     =leads-to=> (check-state-eq *state* :updated-value))

远离睡眠。有这样做的策略吗?

如果本例中的
*state*
是clojure引用类型之一,您可以使用add watch添加一个函数,该函数将通知该对象的每次更改:

我可能建议的一种方法是在条件满足时使用手表来兑现承诺

(let [check-promise (promise)]
  (add-watch *state* :check-for-updated-value
    (fn [rkey refr _oldval newval]
       (when (some-check newval)
          (remove-watch refr rkey)
          (deliver check-promise true))))
  (modify-state-thread-call *state* :updated-value)
  (deref check-promise 1000 false))

如果
*状态*
在1000毫秒内获得满足
某些检查的值,则该值将立即返回true;如果条件不满足,则在1000毫秒后返回false。

根据Crate的响应,我创建了
等待
函数:

(defn return-val [p ms ret]
  (cond (nil? ms) (deref p)
        :else (deref p ms ret)))

(defn wait
  ([f rf] (wait f rf nil nil))
  ([f rf ms] (wait f rf ms nil))
  ([f rf ms ret]
     (let [p (promise)
           pk (hash-keyword p)
           d-fn (fn [_ rf _ _]
                  (remove-watch rf pk)
                  (deliver p rf))]
       (add-watch rf pk d-fn)
       (f rf)
       (return-val p ms ret))))
其用途是:

(defn threaded-inc [rf]
  (future
    (Thread/sleep 100)
    (dosync (alter rf inc)))
  rf)

(def arf (ref 0))
(deref (threaded-inc arf)) ;=> 0

(dosync (ref-set arf 0))
(deref (wait threaded-inc arf)) ;=> 1

我的问题是必须在代码中写入等待一定时间长度的代码。有时由于汇编的原因,时间差别很大。我喜欢承诺的概念,虽然我不太熟悉这个概念哦。。。在再次查看代码之后。。。我知道现在发生了什么。非常酷,只要条件满足,它就会短路并完成。您可以很容易地将其包装起来,这样您就可以编写(等待某个ref或某个谓词超时),或者如果您对编写bug时永远挂起的测试感到满意,那么您可以将超时保留下来;)