2016-11-19 6 views
6

क्या सामान्यीकृत परीक्षण सूट में clojure.spec'd फ़ंक्शंस को शामिल करने के लिए वैसे भी है? मुझे पता है कि हम register specs और सीधे spec functions कर सकते हैं।एक परीक्षण सूट में clojure.spec'd फ़ंक्शंस को कैसे शामिल करें

(ns foo 
    (:require [clojure.spec :as s] 
      [clojure.spec.test :as stest])) 

(defn average [list-sum list-count] 
    (/ list-sum list-count)) 

(s/fdef average 
     :args (s/and (s/cat :list-sum float? :list-count integer?) 
        #(not (zero? (:list-count %)))) 
     :ret number?) 

और बाद में, अगर मुझे लगता है कि spec'd समारोह के खिलाफ उत्पादक परीक्षण चलाना चाहते हैं, मैं stest/check उपयोग कर सकते हैं।

=> (stest/check `average) 
({:speC#object[clojure.spec$fspec_impl$reify__14282 0x68e9f37c "[email protected]"], :clojure.spec.test.check/ret {:result true, :num-tests 1000, :seed 1479587517232}, :sym edgar.core.analysis.lagging/average}) 

लेकिन i) वहाँ वैसे भी शामिल करने के लिए इन परीक्षण मेरी सामान्य परीक्षण के कमरे में चलाता है? मैं clojure.test एकीकरण के बारे में सोच रहा हूं कि test.check has। सबसे नज़दीकी चीज जो मैं देख सकता हूं ii)stest/instrument (देखें here) फ़ंक्शन। लेकिन ऐसा लगता है कि हम सिर्फ प्रतिलिपि पर जांच कर सकते हैं। मुझे जो कुछ चाहिए वो नहीं। इसके अलावा, iii) फ़ंक्शन चश्मा पंजीकृत हैं?

(defspec foo-test 
     100 

     ;; NOT this 
     #_(prop/for-all [v ...] 
      (= v ...)) 

     ;; but THIS 
     (stest/some-unknown-spec-fn foo)) 

उत्तर

7

ठीक है, इसे हल किया गया। बाहर निकलता है बॉक्स के बाहर कोई समाधान नहीं है। लेकिन क्लोजर-स्पेक स्लैक चैनल पर कुछ लोगों ने समाधान clojure.spec.test और clojure.test के साथ एक साथ रखा है।

तो प्रश्न में कोड दिया गया। आप ए)defspec-test मैक्रो को परिभाषित कर सकते हैं जो आपके परीक्षण का नाम और spec'd कार्यों की एक सूची लेता है। आप बी) अपने परीक्षण सूट में इसका उपयोग कर सकते हैं।

धन्यवाद क्लोजर समुदाय !! और उम्मीद है कि इस तरह के एक उपयोगिता समारोह इसे मूल पुस्तकालय में बनाता है।

एक)

(ns foo.test 
    (:require [clojure.test :as t] 
      [clojure.string :as str])) 

(defmacro defspec-test 
    ([name sym-or-syms] `(defspec-test ~name ~sym-or-syms nil)) 
    ([name sym-or-syms opts] 
    (when t/*load-tests* 
    `(def ~(vary-meta name assoc 
         :test `(fn [] 
           (let [check-results# (clojure.spec.test/check ~sym-or-syms ~opts) 
             checks-passed?# (every? nil? (map :failure check-results#))] 
            (if checks-passed?# 
            (t/do-report {:type :pass 
                :message (str "Generative tests pass for " 
                   (str/join ", " (map :sym check-results#)))}) 
            (doseq [failed-check# (filter :failure check-results#) 
              :let [r# (clojure.spec.test/abbrev-result failed-check#) 
                failure# (:failure r#)]] 
             (t/do-report 
             {:type  :fail 
             :message (with-out-str (clojure.spec/explain-out failure#)) 
             :expected (->> r# :spec rest (apply hash-map) :ret) 
             :actual (if (instance? Throwable failure#) 
                failure# 
                (:clojure.spec.test/val failure#))}))) 
            checks-passed?#))) 
     (fn [] (t/test-var (var ~name))))))) 

बी)

(ns foo-test 
    (:require [foo.test :refer [defspec-test]] 
      [foo])) 


(defspec-test test-average [foo/average]) 
+0

मैंने कॉल को 'clojure.specal'' के साथ 'clojure.spec' में बदल दिया, और मैं क्लोजर 1.9 का उपयोग कर रहा हूं। कोड में त्रुटियां नहीं आती हैं ... क्या आपके पास एक अद्यतन संस्करण है? – DjebbZ

1

ऊपर example मामले में असफल हो सकता है जहां :failurefalse है की वजह से कैसे विफलता के लिए stest/abbrev-result परीक्षण। अधिक जानकारी के लिए CLJ-2246 देखें। आप abbrev-result के अपने संस्करण को परिभाषित करके इस पर काम कर सकते हैं। साथ ही, विफलता डेटा का स्वरूपण बदल गया है।

(require 
'[clojure.string :as str] 
'[clojure.test :as test] 
'[clojure.spec.alpha :as s] 
'[clojure.spec.test.alpha :as stest]) 

;; extracted from clojure.spec.test.alpha 
(defn failure-type [x] (::s/failure (ex-data x))) 
(defn unwrap-failure [x] (if (failure-type x) (ex-data x) x)) 
(defn failure? [{:keys [:failure]}] (not (or (true? failure) (nil? failure)))) 

;; modified from clojure.spec.test.alpha 
(defn abbrev-result [x] 
    (let [failure (:failure x)] 
    (if (failure? x) 
     (-> (dissoc x ::stc/ret) 
      (update :spec s/describe) 
      (update :failure unwrap-failure)) 
     (dissoc x :spec ::stc/ret)))) 

(defn throwable? [x] 
    (instance? Throwable x)) 

(defn failure-report [failure] 
    (let [expected (->> (abbrev-result failure) :spec rest (apply hash-map) :ret)] 
    (if (throwable? failure) 
     {:type :error 
     :message "Exception thrown in check" 
     :expected expected 
     :actual failure} 
     (let [data (ex-data (get-in failure 
            [::stc/ret 
            :result-data 
            :clojure.test.check.properties/error]))] 
     {:type  :fail 
     :message (with-out-str (s/explain-out data)) 
     :expected expected 
     :actual (::s/value data)})))) 

(defn check? 
    [msg [_ body :as form]] 
    `(let [results# ~body 
     failures# (filter failure? results#)] 
    (if (empty? failures#) 
     [{:type :pass 
     :message (str "Generative tests pass for " 
         (str/join ", " (map :sym results#)))}] 
     (map failure-report failures#)))) 

(defmethod test/assert-expr 'check? 
    [msg form] 
    `(dorun (map test/do-report ~(check? msg form)))) 
संबंधित मुद्दे