2010-11-24 4 views
16

L'une des façons d'amener une organisation à accepter un langage JVM alternatif est de l'utiliser d'abord pour tester les unités de code Java - "Boss, je vais juste écrire des tests unitaires dans XXX. Ça ne sortira jamais en production. "Utilisation de Clojure pour tester l'unité Java

Existe-t-il des didacticiels pour faire cela dans Clojure?

Je viens de commencer à utiliser Scala pour tester un serveur Java REST. L'écriture des tests dans Scala me permet d'intégrer la sortie XML attendue, de mocker les appels de base de données avec des objets littéraux List, sans oublier que les traits rendent très facile l'extraction du code commun pour les tests.

+5

Je pense que l'étiquette scala est trompeuse ici. Est-ce vraiment nécessaire? –

Répondre

10

Fondamentalement, ce dont vous avez besoin est clojure.test (ou l'une des nombreuses autres bibliothèques de test clojure) et standard Clojure Java interop.

Exemple:

(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"))))) 

Et alors vous les exécuter dans une variété de façons. Construire des outils comme Maven en utilisant le plugin maven clojure les exécuter automatiquement dans le cadre du "test mvn". Dans un rempl, vous pouvez faire quelque chose comme:

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

Il me semble que votre réponse ne contient pas d'informations vraiment utiles selon l'en-tête de la question. Pourriez-vous expliquer quelle est la meilleure façon d'insérer des tests de clojure dans un environnement Java JUnit standard? Dans l'état actuel, nous utilisons TeamCity et l'algorithme est le suivant: toutes les classes annotées avec des annotations spécifiques sont chargées à partir de classpath et transférées à JUnit qui appelle simplement toutes les méthodes @Test. Toute aide serait appréciée. – hsestupin

+1

Eh bien, si vous utilisez Maven, je pense que vous avez fourni des informations utiles sur la façon d'écrire et d'intégrer des tests dans votre environnement. Je ne connais aucun moyen de faire écrire des tests dans Clojure dans le cadre d'une exécution TeamCity/JUnit. Il devrait être possible d'écrire un coureur de test qui trouverait et invoquerait les tests, mais cela semble être plus d'efforts que de valeur. –

4

Voici un exemple d'utilisation Leiningen, test.check et en supposant une mise en page standard Maven:

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

La fonction Java à tester:

package quicktest; 
public class Discontinuities { 
    public static double f5(double x) { 
     return x/(x-5); 
    } 
} 

Le scénario de test 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))))) 

Le projet:

(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"]) 

Le 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> 

Run avec:

mvn compile 
lein deps 
lein test 

Résultats

La faille dans la fonction est vite trouvée:

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]}} 
+0

J'ai essayé de suivre vos instructions, devstopfix, et j'ai obtenu une exception lors de l'exécution de 'lein test' que le'.Le fichier clj' est introuvable: 'Exception dans le thread" principal "java.io.FileNotFoundException: Impossible de localiser quicktest/test_discontinuities__init.class ou quicktest/test_discontinuities.clj sur classpath:,' J'ai rédigé des instructions plus complètes pour la reproduction l'erreur. https://gist.github.com/gregory-nisbet/dc4e67380caad8bf21a3314c84c8d06b –

+0

J'ai donné le code ci-dessus un essai et trouvé deux problèmes: 1.- le test de clojure devrait être sauvegardé dans un fichier appelé test_discontinuities.clj (soulignement entre test et discontinuités), en raison d'un problème spécifique à Java avec des tirets dans les noms de classe. 2.- Le fichier project.clj devrait avoir "test/clojure" dans l'entrée: test-paths, pas seulement "test". Après avoir réparé ces 2 choses, j'ai pu lancer les tests avec le test de Lein. –

+0

@ denis-fuenzalida merci à vous deux - j'ai corrigé la faute de frappe dans l'exemple – devstopfix

Questions connexes