我遇到了Generative Testing in Clojure with spec
概念,想了解它。
另外提供一些例子非常有用。
答案 0 :(得分:12)
作为介绍性阅读,我们得到Rationale and Overview以及Guide,它应该为您提供有关原因和方式的信息。
如果您想要一个有点复杂的示例,我们可以使用string->semantic-version
的{{1}}函数:
leiningen.release
它需要一个字符串并尝试将其解析为一个程序可读的映射,表示某个工件的版本号。它的规格可能如下:
首先是一些依赖
(defn string->semantic-version [version-string]
"Create map representing the given version string. Returns nil if the
string does not follow guidelines setforth by Semantic Versioning 2.0.0,
http://semver.org/"
;; <MajorVersion>.<MinorVersion>.<PatchVersion>[-<Qualifier>][-SNAPSHOT]
(if-let [[_ major minor patch qualifier snapshot]
(re-matches
#"(\d+)\.(\d+)\.(\d+)(?:-(?!SNAPSHOT)([^\-]+))?(?:-(SNAPSHOT))?"
version-string)]
(->> [major minor patch]
(map #(Integer/parseInt %))
(zipmap [:major :minor :patch])
(merge {:qualifier qualifier
:snapshot snapshot}))))
然后是辅助宏
(ns leiningen.core.spec.util
(:require
[clojure.spec :as spec]
[clojure.spec.gen :as gen]
[miner.strgen :as strgen]
[clojure.spec.test :as test]
[leiningen.release :as release]))
后面是语义版本的定义
(defmacro stregex
"Defines a spec which matches a string based on a given string
regular expression. This the classical type of regex as in the
clojure regex literal #\"\""
[string-regex]
`(spec/with-gen
(spec/and string? #(re-matches ~string-regex %))
#(strgen/string-generator ~string-regex)))
和一些帮助规范
(spec/def ::semantic-version-string
(stregex #"(\d+)\.(\d+)\.(\d+)(-\w+)?(-SNAPSHOT)?"))
用于在结果地图中定义键
(spec/def ::non-blank-string
(spec/and string? #(not (str/blank? %))))
(spec/def ::natural-number
(spec/int-in 0 Integer/MAX_VALUE))
和地图本身
(spec/def ::release/major ::natural-number)
(spec/def ::release/minor ::natural-number)
(spec/def ::release/patch ::natural-number)
(spec/def ::release/qualifier ::non-blank-string)
(spec/def ::release/snapshot #{"SNAPSHOT"})
后跟功能规范:
(spec/def ::release/semantic-version-map
(spec/keys :req-un [::release/major ::release/minor ::release/patch
::release/qualifier ::release/snapshot]))
现在我们可以让Clojure Spec生成测试数据并将其提供给函数本身,以测试它是否满足我们为它设置的约束:
(spec/fdef release/string->semantic-version
:args (spec/cat :version-str ::release/semantic-version-string)
:ret ::release/semantic-version-map)
这告诉我们,在为我们生成的1000个测试用例中,函数通过了每一个。
答案 1 :(得分:6)
在潜入 DATE HOUR LCU MVS ACTIVE
NUMBER SYSTEM RATE
ID
2017-04-03 0 004D PROD 12.15
2017-04-03 0 005F PROD 9.82
2017-04-03 0 0060 PROD 5.99
之前,您可能会发现最容易开始查看 DATE HOUR LCU MVS ACTIVE
NUMBER SYSTEM RATE
ID
2017-04-03 0 004D PROD 12.15
2017-04-03 0 005F PROD 9.82
2017-04-03 0 0060 PROD 5.99
。 From the project page:
DATE,HOUR,LCU,MVS,ACTIVE
,,NUMBER,SYSTEM,RATE
,,,ID,
2017-04-03,0,004D,PROD,12.15
2017-04-03,0,005F,PROD,9.82
2017-04-03,0,0060,PROD,5.99
在散文中,这个测试读取:对于所有整数向量,v,排序v等于排序v两次。
如果我们的测试失败会怎样? test.check将尝试找到仍然失败的“较小”输入。这个过程称为收缩。 让我们看看它的实际效果:
clojure/test.check