-
Notifications
You must be signed in to change notification settings - Fork 2
/
advanced.html
165 lines (145 loc) · 8.37 KB
/
advanced.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Expectations by jaycfields</title>
<link rel="stylesheet" href="stylesheets/styles.css">
<link rel="stylesheet" href="stylesheets/pygment_trac.css">
<script src="javascripts/scale.fix.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<header>
<h1 class="header">Expectations</h1>
<p class="header">a minimalist's unit testing framework</p>
<ul>
<li><a class="buttons" href="index.html">Home</a></li>
<li><a class="buttons" href="installing.html">Installing</a></li>
<li><a class="buttons" href="introduction.html">Introduction</a></li>
<li><a class="buttons" href="advanced.html">Advanced</a></li>
<li><a class="buttons" href="collections.html">Collections</a></li>
<li><a class="buttons" href="templating.html">Expect More</a></li>
<li><a class="buttons" href="odds-ends.html">Odds & Ends</a></li>
<li><a class="buttons" href="in-context.html">Around Each</a></li>
<li><a class="buttons" href="before-run-hook.html">Around Suite</a></li>
<li><a class="buttons" href="state-warnings.html">State Warnings</a></li>
<li><a class="buttons" href="redef-state.html">Redef State</a></li>
<li><a class="buttons" href="interactions.html">Side Effects</a></li>
<li><a class="buttons" href="freeze-time.html">Freeze Time</a></li>
<li><a class="buttons" href="env-tweaks.html">ENV Tweaks</a></li>
<li><a class="buttons" href="emacs-tweaks.html">emacs Tweaks</a></li>
<li><a class="buttons" href="clojure-test.html">clojure.test</a></li>
<li><a class="buttons github" href="https://github.com/clojure-expectations/expectations">View On GitHub</a></li>
</ul>
<p class="header">This project is maintained by <a class="header name" href="https://github.com/seancorfield">seancorfield</a> and <a class="header name" href="https://github.com/jaycfields">jaycfields</a></p>
</header>
<section>
<h1>
<a name="expectations" class="anchor" href="#expectations"><span class="octicon octicon-link"></span></a>expectations</h1>
<blockquote>
<p>adding signal, removing noise</p>
</blockquote>
<h2>
<a name="advanced" class="anchor" href="#advanced"><span class="octicon octicon-link"></span></a>Advanced Usage</h2>
In the <a href="introduction.html">last section</a> I gave examples of how to use <a href="https://github.com/clojure-expectations/expectations">expectations</a> to test for equality. This section focus on non-equality expectations that are also available.<br />
<br />
<span style="font-weight: bold;">Regex</span><br />
expectations allows you to use a regex as your expected value, and if the 'actual' string matches that regex the expectation passes. The following example shows both the successful and failing expectations that use regexes.<br />
<pre>
(expect #"in 14" "in 1400 and 92")
jfields$ lein expectations
Ran 1 tests containing 1 assertions in 4 msecs
0 failures, 0 errors.
(expect #"in 14" "in 1300 and 92")
jfields$ lein expectations
failure in (core.clj:17) : sample.test.core
(expect in 14 in 1300 and 92)
regex #"in 14" not found in "in 1300 and 92"
Ran 1 tests containing 1 assertions in 5 msecs
1 failures, 0 errors.</pre>
As you can see from the previous example, writing an expectation using a regex is syntactically the same as writing an equality expectation -
and this is true for all of the non-equality expectations. In expectations there is only one syntax for expect - it's always (expect expected actual).<br />
<br />
<span style="font-weight: bold;">Almost Equal</span><br />
When you provide a numeric expected value, expectations will check that it is
<em>equal</em> to the actual value. That's fine for integer values but not good
for floating point values, so expectations provides a predicate that lets you
expect "almost equal" values:
<pre>
(expect (approximately 0.333) (/ 1 3)) ;; succeeds
(expect (approximately 0.333 0.001) (/ 1 3)) ;; equivalent to this</pre>
You can specify a delta value for how close the actual value must be. As shown
above, the default is 0.001 and the test is equivalent to:
<pre>
(expect true (<= 0.332 (/ 1 3) 0.334))</pre>
<br />
<span style="font-weight: bold;">Functionally Equivalent</span><br />
Sometimes your expected and actual values are computed via functions from the
same underlying value. If you're trying to do this with <tt>from-each</tt>, it
can be a bit awkward as you need both the underlying item from the sequence (to
compute the expected value) as well as the computed actual value. The <tt>functionally</tt>
predicate is intended to help with that:
<pre>
;; compares the results of calling fn-1 and fn-2 on values from 0..99:
(expect (functionally fn-1 fn-2)
(from-each [a (range 100)]
a))</pre>
The default failure message is "not functionally equivalent" but you can provide
your own "difference" function that accepts the computed results from each function
(effectively the expected value and the actual value) and returns a string explaining
how they differ. For string results, you can use <tt>strings-difference</tt> which
is what Expectations uses internally when explaining how expected and actual strings differ.
<br />
<span style="font-weight: bold;">Testing for a certain type</span><br />
I basically never write tests that verify the result of a function is a certain type. However, for the once in a blue moon case where that's what I need,
expectations allows me to verify that the result of a function call is a certain type simply by using that type as the expected value.
The example below shows the successful and failing examples of testing that the actual is an instance of the expected type.<br />
<pre>(expect String "in 1300 and 92")
jfields$ lein expectations
Ran 1 tests containing 1 assertions in 6 msecs
0 failures, 0 errors.
(expect Integer "in 1300 and 92")
jfields$ lein expectations
failure in (core.clj:17) : sample.test.core
(expect Integer in 1300 and 92)
in 1300 and 92 is not an instance of class java.lang.Integer
Ran 1 tests containing 1 assertions in 5 msecs
1 failures, 0 errors.</pre>
<span style="font-weight: bold;">Expected Exceptions</span><br />
Expected exceptions are another test that I rarely write; however, when I find myself in need - expectations has me covered.<br />
<pre>(expect ArithmeticException (/ 12 0))
jfields$ lein expectations
Ran 1 tests containing 1 assertions in 6 msecs
0 failures, 0 errors.
(expect ClassCastException (/12 0))
jfields$ lein expectations
failure in (core.clj:19) : sample.test.core
(expect ClassCastException (/ 12 0))
(/ 12 0) did not throw ClassCastException
Ran 1 tests containing 1 assertions in 4 msecs
1 failures, 0 errors.</pre>
There's another non-equality expectation that I do use fairly often - an expectation where the 'expected' value is a function. The following simple examples demonstrate that if you pass a function as the first argument to expect it will be called with the 'actual' value and it will pass or fail based on what the function returns. (<a href="http://blog.jayfields.com/2011/02/clojure-truthy-and-falsey.html">truthy</a> results pass, <a href="http://blog.jayfields.com/2011/02/clojure-truthy-and-falsey.html">falsey</a> results fail).<br />
<pre>(expect nil? nil)
(expect true? true)
(expect false? true)
jfields$ lein expectations
failure in (core.clj:19) : sample.test.core
(expect false? true)
true is not false?
Ran 3 tests containing 3 assertions in 4 msecs
1 failures, 0 errors.</pre>
These are the majority of the non-equality expectations; however, there is one remaining non-equality expectation - in. Using 'in' is fairly straightforward,
but since it has examples for vectors, sets, and maps I felt it deserved it's own section - which is available <a href="collections.html">here</a>.
</section>
<footer>
<p><small>Hosted on <a href="https://pages.github.com">GitHub Pages</a> using the Dinky theme</small></p>
</footer>
</div>
<!--[if !IE]><script>fixScale(document);</script><![endif]-->
</body>
</html>