Clojure:如何在测试中使用fixtues

17

我正在编写一些与数据库交互的单元测试。因此,在我的单元测试中,拥有设置(setup)和拆卸(teardown)方法来创建并删除表是很有用的。然而use-fixtures方法没有文档 :O。

这是我需要做的:

 (setup-tests)
 (run-tests)
 (teardown-tests)

我目前不想在每个测试之前和之后都运行安装和拆卸,但是想在一组测试之前运行一次安装,然后在一组测试之后运行一次拆卸。你该如何做到这一点?


很高兴看到链接的URL现在有大量文档 :) 还有https://clojure.github.io/clojure/clojure.test-api.html上的文档。 - Dave Liepmann
2个回答

25

您无法使用use-fixtures为自定义测试组提供设置和拆卸代码,但是您可以使用:once为每个名称空间提供设置和拆卸代码:

你无法用use-fixtures 来为自由定义的测试分组提供安装和拆卸代码,但可以使用 :once 为每个命名空间提供安装和拆卸代码:

;; my/test/config.clj
(ns my.test.config)

(defn wrap-setup
  [f]
  (println "wrapping setup")
  ;; note that you generally want to run teardown-tests in a try ...
  ;; finally construct, but this is just an example
  (setup-test)
  (f)
  (teardown-test))    


;; my/package_test.clj
(ns my.package-test
  (:use clojure.test
        my.test.config))

(use-fixtures :once wrap-setup) ; wrap-setup around the whole namespace of tests. 
                                ; use :each to wrap around each individual test 
                                ; in this package.

(testing ... )

这种方法会在测试代码的安装和拆卸代码之间以及测试所在的包之间产生一些耦合,但通常这不是一个很大的问题。您始终可以在 testing 部分中进行自己的手动封装,例如请参见此博客文章的下半部分


谢谢,最终我使用了类似这样的代码:(defn test-ns-hook [] (create-table) (put-4) (put-5) (get-2) (get-3) (get-4) (scan-2) (scan-3) (scan-4) (drop-table)) - David Williams
1
@DavidWilliams,你不应该把测试放在wrap/hook中。fixture的整个意义就是将设置代码与测试分离。这就是hook参数(例如我的示例中的f)的作用;它是回调函数,在fixture代码的正确位置运行测试(以及任何其他hooks)。然后,你只需像平常一样定义你的测试(例如使用deftest)。 - Joost Diepenmaat
我认为ThornyDev博客文章很好地总结了clojure.test中使用fixtures的部分。http://thornydev.blogspot.com/2012/09/before-and-after-logic-in-clojuretest.html - Alan Thompson

1
根据clojure.test的API

Fixtures allow you to run code before and after tests, to set up the context in which tests should be run.

A fixture is just a function that calls another function passed as an argument. It looks like this:

(defn my-fixture [f]    
  ;; Perform setup, establish bindings, whatever.   
  (f) ;; Then call the function we were passed.    
  ;; Tear-down / clean-up code here.  
)

在单个测试的设置和拆卸周围有“每个”夹具,但您写道您想要“一次性”夹具提供的东西:

[A] "once" fixture is only run once, around ALL the tests in the namespace. "once" fixtures are useful for tasks that only need to be performed once, like establishing database connections, or for time-consuming tasks.

Attach "once" fixtures to the current namespace like this:

(use-fixtures :once fixture1 fixture2 ...)
我可能会这样编写你的装置:

(use-fixtures :once (fn [f] 
                      (setup-tests)
                      (f)
                      (teardown-tests)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接