2010-11-24 192 views
16

让组织接受备用JVM语言的方法之一是首先将其用于单元测试Java代码 - “老板,我只是要在XXX中编写一些单元测试。它永远不会投入生产。“使用Clojure进行单元测试Java

有没有在Clojure做这个任何教程?

我刚开始使用Scala来测试Java REST服务器。在Scala中编写测试允许我嵌入预期的XML输出,用数字对象等模拟数据库调用,更不用说特性使得抽象出测试的通用代码变得非常容易。

+5

我认为scala标签在这里有误导性。它真的需要吗? – 2010-11-24 18:10:44

回答

10

基本上你需要的是clojure.test(或许多其他clojure测试库之一)和标准Clojure Java interop

例子:

(ns example.test-java-util 
    (:use 
    [clojure.test]) 
    (:import [java.util HashSet])) 

(defn new-empty-set [] 
    (HashSet.)) 

(deftest test-empty-set 
    (is (= 0 (.size (new-empty-set)))) 
    (is (= true (.isEmpty (new-empty-set)))) 
    (is (= (new-empty-set) (new-empty-set)))) 

(deftest test-add-remove 
    (is (= (new-empty-set) 
     (doto (new-empty-set) 
      (.add "xyz") 
      (.remove "xyz"))))) 

然后你会在各种不同的方式运行。使用maven clojure插件构建像Maven这样的工具可以自动运行它们作为“mvn测试”的一部分。是一个示例使用Leiningentest.check假设一个标准的Maven布局

example.test-java-util> (run-tests 'example.test-java-util) 

Testing example.test-java-util 

Ran 1 tests containing 4 assertions. 
0 failures, 0 errors. 
{:type :summary, :test 1, :pass 4, :fail 0, :error 0} 
+0

在我看来,你的答案根据问题的标题不包含任何真正有用的信息。你能否解释一下在标准Java JUnit环境中插入一些clojure测试的最佳方式是什么?在当前状态下,我们使用TeamCity,算法如下:所有使用特定注释注解的类都从classpath加载并传递给JUnit,它只调用所有的@Test方法。任何帮助,将不胜感激。 – hsestupin 2012-12-21 09:00:01

+1

好吧,如果您碰巧使用Maven,那么我认为它提供了一些有关如何编写测试并将其集成到您的环境中的有用信息。我不知道用Clojure编写的测试成为TeamCity/JUnit执行的一部分。应该可以编写一个能够找到并调用测试的测试运行器,但这看起来似乎比付出更多的努力。 – 2012-12-21 17:51:36

4

这里:

pom.xml 
project.clj 
src 
    main 
    java 
     quicktest 
     Discontinuities.java 
    test 
    clojure 
     quicktest 
     test_discontinuities.clj 

Java的功能测试:

package quicktest; 
public class Discontinuities { 
    public static double f5(double x) { 
     return x/(x-5); 
    } 
} 
在REPL,你可以这样做

Clojure测试用例:

(ns quicktest.test-discontinuities 
    (:import [quicktest Discontinuities]) 
    (:require [clojure.test :refer :all] 
    [clojure.test.check :as tc] 
    [clojure.test.check.generators :as gen] 
    [clojure.test.check.properties :as prop] 
    [clojure.test.check.clojure-test :as ct :refer (defspec)])) 

(deftest test-single-case 
    (is (= 2.0 (Discontinuities/f5 10)))) 

(defspec test-discontinuities 1e4 
     (prop/for-all [x gen/nat ] 
         (let [y (Discontinuities/f5 x)] 
          (is (<= y x))))) 

项目:

(defproject quicktest/discontinuities "0.1" 
      :dependencies [[org.clojure/clojure "1.8.0"] 
          [org.clojure/test.check "0.9.0"]] 
      :java-source-paths ["src/main/java"] 
      :test-paths ["src/test/clojure"]) 

的POM:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>quicktest</groupId> 
    <artifactId>discontinuities</artifactId> 
    <version>0.1</version> 
</project> 

运行带:

mvn compile 
lein deps 
lein test 

结果

函数中的缺陷很快发现:

FAIL in (test-discontinuities) (test_discontinuities.clj:13) 
expected: (<= y x) 
actual: (not (<= Infinity 5)) 
{:test-var "test-discontinuities", 
:result false, 
:seed 1431128331945, 
:failing-size 23, 
:num-tests 24, 
:fail [5], 
:shrunk {:total-nodes-visited 3, :depth 0, :result false, :smallest [5]}}