Schema, Validation and
Generative Testing
Laurence Chen
twitter: humorless
https://replware.dev
developer@ LINE
CLOSING THE DISTANCEBringing people, information and services closer together
Agenda
● Use case: schema validation
○ Predicates are constraints, not types.
○ Does Clojure.spec compose?
● Clojure.spec provides uniform error message
○ explain-data
○ Application caller has the right to decide how to format the error.
● Generative Testing
○ Example-based testing v.s. Property-based testing
○ Three common ways to write property-based testing
○ Leverage Clojure.spec to generate input
Dynamic language needs schema validation
Data input
Software system
(1) API
(2) Web UI
(3) ETL reading from
file
Using schema validation to ensure data is
correct.
Predicates are constraints, not types.
Does Clojure.spec compose? (and)
Does Clojure.spec compose? (or)
Clojure.spec provides uniform error message
Data input
Software system
(1) API
(2) Web UI
(3) ETL reading
from file
Validation error message
spec/explain-data
Example
(def input-data
{:name “Peter”
:age 21
:sex :male})
(s/def ::name string?)
(s/def ::age #(< % 18))
(s/def ::sex #{:male :female})
(s/def ::child
(s/keys :req-un [::name ::age ::sex]))
;; -------------------------------------
(s/valid? ::child input-data)
;; => false
(s/explain-data ::child input-data)
;; => Validation failed reason in data form
spec/explain-data in Example
● Library callee only returns the error in data form. (output of spec/explain-
data)
● Application caller has the right to decide how to format the error.
Example-based testing
● The correct F needs to satisify certain input, output condition.
● If for all (input, output) pairs in a known set satisfying output = Fn(input),
then Fn is correct.
(To be tested) function
or component
Input:
Known set of values.
Output:
Known set of values.
Generative Testing (Property-based testing)
● output = F1(input).
● F1 is an existing implementation.
● When we generate a large enough random input set and for all input
satisfying F1(input) = Fn(input), then Fn is equivalent to F1.
Large enough
generated random
input set.
F1
Fn
The output set
is equivalent.
Three common ways to write property-based tests
● Existing implementation
● Inverse function
● Describe the traits of the output
Large enough
generated random
input set.
F1
Fn
The output set
is equivalent.
Leverage Clojure.spec to generate input
Q & A

Schema, validation and generative testing

  • 1.
    Schema, Validation and GenerativeTesting Laurence Chen twitter: humorless https://replware.dev developer@ LINE
  • 2.
    CLOSING THE DISTANCEBringingpeople, information and services closer together
  • 3.
    Agenda ● Use case:schema validation ○ Predicates are constraints, not types. ○ Does Clojure.spec compose? ● Clojure.spec provides uniform error message ○ explain-data ○ Application caller has the right to decide how to format the error. ● Generative Testing ○ Example-based testing v.s. Property-based testing ○ Three common ways to write property-based testing ○ Leverage Clojure.spec to generate input
  • 4.
    Dynamic language needsschema validation Data input Software system (1) API (2) Web UI (3) ETL reading from file Using schema validation to ensure data is correct.
  • 5.
  • 6.
  • 7.
  • 8.
    Clojure.spec provides uniformerror message Data input Software system (1) API (2) Web UI (3) ETL reading from file Validation error message
  • 9.
  • 10.
    Example (def input-data {:name “Peter” :age21 :sex :male}) (s/def ::name string?) (s/def ::age #(< % 18)) (s/def ::sex #{:male :female}) (s/def ::child (s/keys :req-un [::name ::age ::sex])) ;; ------------------------------------- (s/valid? ::child input-data) ;; => false (s/explain-data ::child input-data) ;; => Validation failed reason in data form
  • 11.
    spec/explain-data in Example ●Library callee only returns the error in data form. (output of spec/explain- data) ● Application caller has the right to decide how to format the error.
  • 12.
    Example-based testing ● Thecorrect F needs to satisify certain input, output condition. ● If for all (input, output) pairs in a known set satisfying output = Fn(input), then Fn is correct. (To be tested) function or component Input: Known set of values. Output: Known set of values.
  • 13.
    Generative Testing (Property-basedtesting) ● output = F1(input). ● F1 is an existing implementation. ● When we generate a large enough random input set and for all input satisfying F1(input) = Fn(input), then Fn is equivalent to F1. Large enough generated random input set. F1 Fn The output set is equivalent.
  • 14.
    Three common waysto write property-based tests ● Existing implementation ● Inverse function ● Describe the traits of the output Large enough generated random input set. F1 Fn The output set is equivalent.
  • 15.
  • 16.