testing - 如何以一对多的方式编写 clojure.test.check 生成器?

标签 testing clojure generative-testing

假设我有一个生成器 users-gen,它生成一组 1 个或多个用户。另一个名为 user-actions-gen 的参数化生成器接受一个或多个用户的序列,并生成这些用户可能执行的一系列操作。

(def user-gen 
 ;; generates a user
 ...)

(def users-gen 
 ;; sequences of 1 or more users 
 (gen/such-that not-empty (gen/vector gen/users))

(defn user-actions-gen [users]
  ;; a action performed by some user from the `users argument
  ...)

如果我想为 users-gen 生成的单个用户序列生成单个操作,那么很简单,直接将 users-gen 生成/绑定(bind)到 user-actions-gen 即可。

但是,我想从相同的用户序列中生成许多操作。我遇到这个问题是因为我基本上只是想说“这是状态,让任何随机 Action 进来,让我们将 Action 应用到状态,让我们确认状态仍然有效;对所有 Action 都这样做。 “我有以下代码。

(defspec check-that-state-is-always-valid
  100
  (let [state-atm (atom {})]
    (prop/for-all
     [[actions users]
      (gen/bind users-gen
                (fn [users]
                  (gen/tuple
                   (gen/vector (user-actions-gen users))
                   (gen/return users))))]
     (doseq [action actions
             :let [state (swap! state-atm state-atm-transform-fx action)]]
       (is (state-still-valid? state))))))

这类作品。问题是:

  1. 它似乎完全评估了 doseq 而不是在第一个错误时停止
  2. 它看起来有点不对劲。代码到处都是,它的作用并不完全明显。
  3. 似乎 user-actions-gen 应该采用 users-gen 的生成器,而不是 users-gen 的已实现用户值?这对可组合性有帮助吗?请注意,我不想将它们放在一起,因为 users-gen 可能对其他生成器有用。

所以,回顾一下。我从one 生成器获取单个生成值并将其作为参数传递给多个 生成器。我该如何以更具吸引力/优雅的方式来做到这一点?

最佳答案

您可能想查看最新版本的 test.check (0.9.0)。它现在在生成器命名空间中包含一个 let,这使得组合生成器变得轻而易举:

https://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check/generators.cljc#L1452

这样做的缺点是您仍然不能直接在 prop/for-all 中执行此操作(显然是由于向后兼容的原因)。

我推荐的替代方案是使用 test.chuck (它是由 test.check 的当前维护者编写的)。它确实有一个for-all,它的绑定(bind)形式就像generators/let 一样工作。这是我发现的最干净的方法,并且效果很好。

关于testing - 如何以一对多的方式编写 clojure.test.check 生成器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23685366/

相关文章:

clojure - 如何加速 lein Uberjar Build

multithreading - 保证 future 从某一点开始吗?

c# - C# : generate a list of two dimension arrays with the same shape 中的 FsCheck

javascript - 您如何使用 Neptune 在本地进行测试?

javascript - 如何在 Intern 2 功能测试中加载 pollUntil 助手

unit-testing - CMake:目标 "test"不构建测试,目标 "all"构建测试

java - 用于测试的 Android Assets

clojure - 为什么Partial的Clojure这么慢