[英]Using a dynamic variable binding in a leiningen plugin
我有一个手动运行我的 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
方法。
我同意clojure.test
实现在参数化测试方面不是最佳的。
我不确定为什么您的binding
表单不起作用 - 我已经检查了clojure.test
的代码,但我看不出有什么问题。 我会检查是否:
测试在建立binding
的同一线程中执行(也许您可以在插件和测试中添加记录线程名称/ID)
不同的类加载器导致你的插件命名空间和它的全局动态变量实际上被加载和定义了两次
我还有一个想法(我真的不想批评您的解决方案,只是试图找到替代解决方案:)):您的问题是将全局配置选项从外部源(如测试脚本配置)传递给您的被测代码。 你有没有想过将它们作为环境变量传递? 您可以使用(System/getenv "baseuri")
或environ轻松读取它们。
也许出于非常具体的原因,您有一个动态变量,但是,由于您没有明确说明,我在这里试一试。
避免动态重新绑定变量。 在最好的情况下,完全避免全局状态,而是重新定义您的函数以将 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 而不重新绑定它。
也许您可以将存储库的链接添加到最小的可重现测试用例以更好地理解它?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.