All Projects → ccfontes → eg

ccfontes / eg

Licence: MIT license
eg delivers clojure.test function tests with conciseness

Programming Languages

clojure
4091 projects
shell
77523 projects

Projects that are alternatives of or similar to eg

Test Time
A helper to control the flow of time
Stars: ✭ 169 (+604.17%)
Mutual labels:  tests
Testimo
Testimo is PowerShell module for running health checks for Active Directory (and later on any other server type) against a bunch of different tests
Stars: ✭ 249 (+937.5%)
Mutual labels:  tests
KAI
KAI is a distributed computing model written in modern C++ and is cross-plaftorm. Using custom language translators and an executor, KAI provides full reflection, persistence and cross-process communications without having to modify existing source code. KAI Comes with an automated, generational tricolor garbage collector, and Console- and Windo…
Stars: ✭ 13 (-45.83%)
Mutual labels:  tests
Learn Elm Architecture In Javascript
🦄 Learn how to build web apps using the Elm Architecture in "vanilla" JavaScript (step-by-step TDD tutorial)!
Stars: ✭ 173 (+620.83%)
Mutual labels:  tests
Syntaxnet
reference code for syntaxnet
Stars: ✭ 189 (+687.5%)
Mutual labels:  tests
Manual Testing
This repository contains the General Test Cases for performing Manual Testing on the Web/Mobile application. It also has Test cases related to API Testing. Templates related to Test Plan and BugBash are also updated.
Stars: ✭ 134 (+458.33%)
Mutual labels:  tests
Modern Wasm Starter
🛸 Run C++ code on web and create blazingly fast websites! A starter template to easily create WebAssembly packages using type-safe C++ bindings with automatic TypeScript declarations.
Stars: ✭ 140 (+483.33%)
Mutual labels:  tests
testable
QT/QML Test Runner and Utilities
Stars: ✭ 53 (+120.83%)
Mutual labels:  tests
Brainmonkey
Mocking utility for PHP functions and WordPress plugin API
Stars: ✭ 191 (+695.83%)
Mutual labels:  tests
clonings
A project for learning Clojure, based on rustlings.
Stars: ✭ 32 (+33.33%)
Mutual labels:  tests
Xamarin.forms.mocks
Library for running Xamarin.Forms inside of unit tests
Stars: ✭ 179 (+645.83%)
Mutual labels:  tests
Ember Native Dom Helpers
Test helpers for your integration tests that fire native events
Stars: ✭ 187 (+679.17%)
Mutual labels:  tests
go-recipes
🦩 Tools for Go projects
Stars: ✭ 2,490 (+10275%)
Mutual labels:  tests
Acutest
Simple header-only C/C++ unit testing facility.
Stars: ✭ 170 (+608.33%)
Mutual labels:  tests
openjpeg-data
Test files for the OpenJPEG libraries and utilities
Stars: ✭ 37 (+54.17%)
Mutual labels:  tests
Should.js
BDD style assertions for node.js -- test framework agnostic
Stars: ✭ 1,908 (+7850%)
Mutual labels:  tests
book-library
📚 A book library app for both Android & IOS ~ Flutter.dev project in Dart
Stars: ✭ 89 (+270.83%)
Mutual labels:  tests
xharness
C# command line tool for running tests on Android / iOS / tvOS devices and simulators
Stars: ✭ 123 (+412.5%)
Mutual labels:  tests
EntityFrameworkCore.AutoFixture
A library aimed to minimize the boilerplate required to unit-test Entity Framework Core code using AutoFixture and in-memory providers.
Stars: ✭ 31 (+29.17%)
Mutual labels:  tests
perseus
Perseus is a set of scripts (docker+javascript) to investigate a distributed database's responsiveness when one of its three nodes is isolated from the peers
Stars: ✭ 49 (+104.17%)
Mutual labels:  tests

eg Clojars Project CircleCI codecov Universal Permissive License v1.0

(deftest inc-test
  (is (= 1 (inc 0))))

in eg becomes:

(eg inc 0 1)

eg supports Clojure, ClojureScript JVM, and ClojureScript JS, the same as clojure.test.

Vanilla clojure.test and eg test results are included in the same report. Also, no custom test runner is required – run your clojure.test tests as usual.

Check the ideas driving eg.

Installation

Leiningen/Boot

[eg "0.5.5-alpha"]

Clojure CLI/deps.edn

eg {:mvn/version "0.5.5-alpha"}

Usage

Let's try eg! Start by creating a REPL session and then requiring eg and ge:

(require '[eg :refer [eg ge]])

eg stands for e.g. (short for example), and ge is just eg reversed.

Each eg test tests one function using examples. You could think of it as a function's test definition:

(eg not  ; testing clojure.core/not
  false  ; with input parameter `false`
  true)  ; returning expected value `true`

a clojure.test test named not-test was generated.

If a function under test takes multiple parameters, we need to wrap these with []:

(eg * [3 2] 6)

When parameter is a vector, it needs to be wrapped with [] as well:

(eg set
  [[1 2]] #{1 2}) ; cannot do: [1 2] #{1 2}

Each eg test can contain an arbitrary number of examples:

(eg *
  [3]   3
  [3 2] 6)

There are times when we prefer to have expected values on the left, and input parameters on the right. For that we use ge, a useful mnemonic for the inverted flow of the test example:

(ge + 10 [3 7])

Expected values can be checked against a predicate or a spec:

(require '[clojure.spec.alpha :as spec])

(spec/def ::int integer?)

(eg dec
  [4] integer?
  [5] ::int)

=> or <= operators between input parameters and expected value can be used to improve readability, or override the default example direction of eg or ge.

(eg hash-map
  [:d 1] {:d 1}
  [:a 1 :b 2 :c 3 :d 4] => {:a 1 :b 2 :c 3 :d 4})

=> or <= could be read as is. {:a 1 :b 2 :c 3 :d 4} is a map?:

(eg hash-map
  map? <= {:a 1}
  {:a 1} coll?) ; when no operator is used, 'is' operator semantics are assumed

ex makes it possible to test the result from evaluating an arbitrary s-expression. Typical scenarios include testing the result of calling a macro (eg, and ge only support function testing), or decomposing the assertion of different properties or values from calling a form:

; let must be used outside of 'ex' when surrounding examples
(let [test-eg-ret (ex (inc 0) => 1)
      f-len (count "eg-test-")]
  ; using arrows/equal is compulsory
(let [test-eg-ret (ex (inc 0) 1)
      f-len (count "eg-test-")]
  (ex var? <= test-eg-ret)
  (ex (-> test-eg-ret meta :test) => boolean)
  (ex (-> test-eg-ret meta :test) => fn?)
  (ex (-> test-eg-ret meta :name name (subs f-len)) => not-empty))
  ;=> eg-test-<rand-id>

  (ex (true? false) => false) ;=> eg-test-<rand-id>

; when '=>' is omitted, <expected | checker> and <actual> placeholders are
; reversed. This syntax is ideal for multiline tests

(ex "Long string to examplify 'ex' syntax that is ideal for multiline tests"
    (identity "Long string to examplify 'ex' syntax that is ideal for multiline tests"))
;=> eg-test-<rand-id>

(ex string?
    "Long string to examplify 'ex' syntax that is ideal for multiline tests")
;=> eg-test-<rand-id>

; tests truthy expression
(ex "bar")
;=> eg-test-<rand-id>

; checks expression against a spec
; recommended to do (eg ::fixtures/string "foo") instead,
; but implemented for consistency
(ex "foo" => ::fixtures/string)
;=> eg-test-<rand-id>

If we want to check if the expected value is a function or a spec, the operator = is used:

(defn foo [] inc)

(eg foo [] = inc)
; or
(ge foo [] = 2)

(ex (foo 2) = inc)

(ex inc = (foo))

(ex (foo) = inc)

(defn bar [] ::inc)

(eg bar [] ::inc)

There are times when we just want to test a certain input parameter value, but fill the remainder input parameters nevertheless. eg provides a don't care placeholder _, for these cases:

(eg vector
  [1 2 3 4] [1 2 3 4]
  [5 6 _ 8] vector?
  [4 _ 5]   vector?)

We can arbitrarily name a don't care parameter by prefixing its name with $. A named don't care can also be bound with parts on the expected result. Don't care parameters are generated from parameters on the same argument position:

(eg assoc-in
  [{} [:a :b] {:eggs "boiled"}] => {:a {:b {:eggs "boiled"}}}
  [_ $spam _] => map?
  [_ _ $eggs] => {:a {:b $eggs}})

When writing examples, don't cares enable us to spend less time writting fillers, and the reader is able to better understand the focus of the example.

Expecting arbitrarily nested JavaScript objects or arrays works out of the box:

(eg identity
  #js {:a [1]} => #js {:a [1]}
  #js {:a [1]} => (clj->js {:a [1]}))

(ex (identity #js {:a [1]}) => #js {:a [1]}))

Check if your specs are on the right track using examples. eg validates examples against a spec defined with a qualified keyword:

(require '[clojure.spec.alpha :as spec])

(spec/def ::string (spec/nilable string?))
(spec/def ::pos-int pos-int?)

(eg ::string nil "foo") ; `^:focus` cannot be used here at the moment
;=> <current-ns>-:string-test

(ge ::pos-int
  1
  ; test invalid examples, i.e., near a spec's boundary, using `!`
  ! 0
  (! -1 -2 -3)) ; equivalent to: ! -1 ! -2 ! -3

Quite often, writing tests becomes an afterthought, because creating test boilerblate like a new test namespace, requiring test forms and functions under test is too much of a hassle, while being immersed in writing code. It would make sense to have test forms globally available that we use almost as often as defn. Introducing set-eg! – call it at the development entrypoint of your program:

(require '[eg :refer [set-eg!]])

To use eg, ge, and ex in any namespace without additional requires, run:

(set-eg!)
;=> :reloading ()

To use eg, and ge in any namespace without additional requires, run:

(set-eg! 'eg 'ge)

PS - This functionality is only supported in Clojure.

It's possible to run only selected tests by using metadata ^:focus on eg or ge:

(eg ^:focus false? [false] true)

There are some caveats to consider when using ^:focus with ClojureScript:

  1. The tests report counts towards non focused tests, although examples under such tests are not executed.
  2. Assertions for tests defined directly with clojure.test/deftest will still be executed, despite the presence of focused eg, or ge tests.

Skip running certain tests or examples using vanilla Clojure(Script) code:

#_(eg count '(9 8 7)
            3)

(eg count
 ; '(9 8 7) 3
 '(9 8 7 6) 4)

Between eg, and ge, choose the form that is most convenient for your combination of function examples and use it only once for testing a function. For example, don't do this:

(ge inc [1] 2)
(ge inc [0] 1)

or this:

(eg inc [1] 2)
(ge inc [0] 1)

When building with ClojureScript JVM, remove WARNING: eg is a single segment namespace warning with the compiler option single-segment-namespace:

{:cljsbuild
  {:builds
    [{:compiler
       {:warnings
         {:single-segment-namespace false}}}]}}

Run your tests

Finally, run your tests as you normally would with clojure.test.

Clojure tests in the REPL

(clojure.test/run-all-tests)
; or
(clojure.test/run-tests some.ns)

Clojure tests in the terminal

> lein test

ClojureScript tests in the REPL

Also see below Enable line information for ClojureScript (JVM) tests on Node.js.

(cljs.test/run-all-tests)
; or
(cljs.test/run-tests some.ns)

Enable line information for ClojureScript (JVM) tests on Node.js

Get accurate test line information on reports.

First install source maps support node package:

npm install source-map-support

Enable source maps on your project.clj test build config:

{:cljsbuild
  {:builds
    {...
      {:compiler {:source-map true}}}}}

Run eg's own tests

Run eg's own tests expected to pass, fail, targeting Clojure, ClojureScript JVM, and ClojureScript JS.

Test libraries which work great with eg

  • eftest – Eftest is a fast and pretty Clojure test runner.
  • humane-test-output – Humane test output for clojure.test

Background readings

License

Copyright (c) 2020 Carlos da Cunha Fontes

The MIT License

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].