在leiningen插件中使用动态变量绑定

时间:2016-04-21 15:38:48

标签: plugins clojure leiningen clojure.test

我有一个lein插件,可以手动运行我的clojure.test代码。它声明了我希望在我的测试中访问的动态变量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方法。

2 个答案:

答案 0 :(得分:1)

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

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

  • 测试在binding建立的同一个线程中执行(也许你可以在你的插件和测试中添加线程名称/ id的记录)

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

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

答案 1 :(得分: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而不重新绑定它 也许你可以添加一个回购链接到一个最小的可重复测试用例,以更好地理解它?