1

我有一个手动运行我的 clojure.test 代码的 lein 插件。它声明了一个baseuri我希望在我的测试中访问的动态变量。我将删除并更改代码以直截了当。在这里,在我的插件内部,我有一个配置文件,它创建动态baseuri变量并将其设置为空白字符串。

;; myplugin
;; src/myplugin/config.clj
(ns leiningen.myplugin.config)    
(def ^:dynamic baseuri "")

插件中的任务设置动态baseuri变量并使用 clojure.test 运行测试:

;; src/myplugin/runtests.clj
(ns leiningen.myplugin.runtests
      (:require [leiningen.myplugin.config :as config]
                [clojure.test]
                [e2e.sometest]))

(defn run [project]
  (binding [config/baseuri "https://google.com/"]
    (println config/baseuri) ;; <-- prints google url
    ;; run clojure.test test cases from e2e.sometest namespace
    ;; This will call the `sampletest` test case
    (clojure.test/run-tests e2e.sometest)
  ))

在我的 clojure.test 内部,我尝试使用 baseuri 变量,但绑定不成立。它的值是我最初声明的值baseuri(一个空字符串)

;; tests/e2e/sometest.clj
(ns e2e.sometest
  (:require [leiningen.myplugin.config :as config]))

(deftest sampletest
  (println config/baseuri))  ;; <-- Prints an empty string instead of google url

我已经编辑了代码,以基本方式显示 clojure.test 用例是如何运行的。我只是将要运行的命名空间传递给该clojure.test/run-tests方法。

4

2 回答 2

1

我同意clojure.test在参数化测试时实现不是最佳的。

我不确定为什么您的binding表单不起作用 - 我已经检查了代码,clojure.test但看不出有什么问题。我会检查是否:

  • 测试在与建立相同的线程中执行binding(也许您可以在插件和测试中添加记录线程名称/ID)

  • 不同的类加载器导致您的插件命名空间及其全局动态变量实际上被加载和定义两次

我还有一个想法(我真的不想批评您的解决方案,只是想寻找替代解决方案:)):您的问题是将全局配置选项从外部来源(如测试脚本配置)传递给您的测试代码。您是否考虑过将它们作为环境变量传递?(System/getenv "baseuri")您可以使用或environ轻松阅读它们。

于 2016-04-21T19:16:24.980 回答
0

也许您出于非常特定的原因有一个动态变量,但是,由于您没有如此明确地说明,我在这里试一试。

避免动态重新绑定变量。在最好的情况下,完全避免全局状态,而是重新定义你的函数以将 baseuri 作为参数。
或者重构您的应用程序,使其根本不需要静态变量,就像您现在拥有它一样。

编辑我的猜测是你的功能:

(defn run [project]
  (binding [config/baseuri "https://google.com/"]
    (println config/baseuri) ;; <-- prints google url
    ;; runs clojure.test code here …
  ))

(deftest sampletest
  (println config/baseuri))

不以任何方式连接。至少我不明白他们应该如何。您正在运行测试并打印其他一些 var 而无需重新绑定它。
也许您可以将一个指向 repo 的链接添加到一个最小的可重现测试用例以更好地理解它?

于 2016-04-21T15:54:15.350 回答