gpt4 book ai didi

reflection - 在运行时导入脚本

转载 作者:行者123 更新时间:2023-12-04 02:52:08 25 4
gpt4 key购买 nike

我正在使用 Clojure 编写一个小型测试框架。

(ns pvt.core.runner
(use
[pvt.tests.deployment]
[pvt.tests.files]
[pvt.tests.jms]))

(defn- run-test
[test-name]
{test-name (test-and-log test-name)})

(defn- run-all-tests-in-namespace
[namespace-name]
(map
run-test
(vals (ns-publics (symbol namespace-name))))
)

(defn run-all-tests
[namespace-list]
(map run-all-tests-in-namespace namespace-list))

我的 run-all-tests 函数接受一个 clojure 脚本列表,加载这些脚本中的所有公共(public)函数并运行它们。这很棒,只是我必须实际导入这些脚本。我这样调用我的函数 (run-all-tests ["pvt.tests.deployment""pvt.tests.files""pvt.tests.jms"]),但这只有在我导入每个脚本,如我的代码摘录开头所示。这不行,因为我不知道谁会调用 run-all-tests,也不知道会使用什么参数。

我想知道是否有一种在运行时导入这些脚本的方法。我已经知道每个脚本的 namespace ,因此我拥有所有必需的信息。这可以做到吗?谢谢

最佳答案

是的,您可以使用 load-file 从任意文件路径导入 Clojure 源文件。如果源文件包含命名空间声明,那么这些命名空间现在可用于您的 Clojure 应用程序(框架)。

显然,您至少必须编写一些代码,从命令行获取 Clojure 源文件的名称,或者指向源文件所在的目录。然后您的代码将使用 (load-file) 加载文件。

您陈述的问题是您希望在事先不知道命名空间名称的情况下从命名空间执行一些测试。有两种方法可以实现这一点:

1) 使用命名约定。 即为名称与约定匹配的每个命名空间运行测试,即

user=> (load-file "/home/noahlz/foo.clj") 
#<Var@1e955d29: #<core$foo foo.test.core$foo@48a7a9bd>>
user=> (filter #(re-matches #".*\.test\..*" %) (map str (all-ns)))
("foo.test.core")

使用上述代码,您已经获得了一个命名空间列表,您可以在这些命名空间上执行您的框架代码。

2) 使用元数据。要求框架的用户将元数据添加到他们的命名空间,而不是遵循命名约定。这减少了意外测试意外遵循您的约定的命名空间的机会。

(参见:What are some uses of Clojure metadata?)

请注意,这是 Clojure 自己的 clojure.test/deftest 宏使用的方法。

这是一个使用自定义元数据查找命名空间的示例。您在定义测试的源文件中的命名空间声明:

(ns ^{:doc "some documentation" :my-framework-tests true}
foo.test.core)

在 REPL 中,一个如何以编程方式获取这些内容的示例:

user=> (load-file "foo.clj")

user=> (filter (fn [[n m]] (:my-framework-tests m))
(map #(vector (str %) (meta %)) (all-ns)))
(["foo.test.core" {:my-framework-tests true, :doc "some documentation"}])

现在您有一个 namespace 列表,这些 namespace 已被标记为包含您的自定义测试框架的测试。您甚至可以在命名空间函数中使用元数据,以避免它们也需要命名约定。

可能有一种更简洁的方法来获取具有特定元数据的命名空间(如果有人知道,一定要发表评论!)

另一个重要说明:我正在加载任意文件以证明这是可能的,购买您真的应该考虑遵循 Leiningen、Maven 或其他构建框架遵循的约定。例如,参见 lein-perforate

祝你好运!

关于reflection - 在运行时导入脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17470630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com