forked from carpentries-incubator/python-testing
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy path02-assertions.html
More file actions
109 lines (109 loc) · 6.93 KB
/
02-assertions.html
File metadata and controls
109 lines (109 loc) · 6.93 KB
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<title>Software Carpentry: Testing</title>
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap-theme.css" />
<link rel="stylesheet" type="text/css" href="css/swc.css" />
<link rel="alternate" type="application/rss+xml" title="Software Carpentry Blog" href="http://software-carpentry.org/feed.xml"/>
<meta charset="UTF-8" />
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body class="lesson">
<div class="container card">
<div class="banner">
<a href="http://software-carpentry.org" title="Software Carpentry">
<img alt="Software Carpentry banner" src="img/software-carpentry-banner.png" />
</a>
</div>
<article>
<div class="row">
<div class="col-md-10 col-md-offset-1">
<a href="index.html"><h1 class="title">Testing</h1></a>
<h2 class="subtitle">Assertions</h2>
<section class="objectives panel panel-warning">
<div class="panel-heading">
<h2 id="learning-objectives"><span class="glyphicon glyphicon-certificate"></span>Learning Objectives</h2>
</div>
<div class="panel-body">
<ul>
<li>Assertions are one line tests embedded in code.</li>
<li>Assertions can halt execution if something unexpected happens.</li>
<li>Assertions are the building blocks of tests.</li>
</ul>
</div>
</section>
<p>Assertions are the simplest type of test. They are used as a tool for bounding acceptable behavior during runtime. The assert keyword in python has the following behavior:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="op">>>></span> <span class="cf">assert</span> <span class="va">True</span> <span class="op">==</span> <span class="va">False</span></code></pre></div>
<pre class="output"><code>Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError</code></pre>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"> <span class="op">>>></span> <span class="cf">assert</span> <span class="va">True</span> <span class="op">==</span> <span class="va">True</span></code></pre></div>
<pre class="output"><code> >>></code></pre>
<p>That is, assertions halt code execution instantly if the comparison is false. It does nothing at all if the comparison is true. These are therefore a very good tool for guarding the function against foolish (e.g. human) input:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="cf">assert</span> <span class="bu">len</span>(num_list) <span class="op">!=</span> <span class="dv">0</span>
<span class="cf">return</span> <span class="bu">sum</span>(num_list)<span class="op">/</span><span class="bu">len</span>(num_list)</code></pre></div>
<p>The advantage of assertions is their ease of use. They are rarely more than one line of code. The disadvantage is that assertions halt execution indiscriminately and the helpfulness of the resulting error message is usually quite limited.</p>
<p>Also, input checking may require decending a rabbit hole of exceptional cases. What happens when the input provided to the mean function is a string, rather than a list of numbers?</p>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2 id="insert-an-assertion"><span class="glyphicon glyphicon-pencil"></span>Insert an Assertion</h2>
</div>
<div class="panel-body">
<ol style="list-style-type: decimal">
<li>Open an IPython Notebook</li>
<li>Create the following function:</li>
</ol>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="cf">return</span> <span class="bu">sum</span>(num_list)<span class="op">/</span><span class="bu">len</span>(num_list)</code></pre></div>
<ol start="3" style="list-style-type: decimal">
<li>In the function, insert an assertion that checks whether the input is actually a list.</li>
</ol>
<p>Hint: Use the <a href="https://docs.python.org/2/library/functions.html#isinstance">isinstance function</a>.</p>
</div>
</section>
<p>Assertions are also helpful for catching abnormal behaviors, such as those that arise with floating point arithmetic.</p>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2 id="almost-equal"><span class="glyphicon glyphicon-pencil"></span>Almost Equal</h2>
</div>
<div class="panel-body">
<p>Assertions are also helpful for catching abnormal behaviors, such as those that arise with floating point arithmetic. Using the assert keyword, how could you test whether some value is almost the same as another value?</p>
<ul>
<li>My package, mynum, provides the number a.</li>
<li>Use the <code>assert</code> keyword to check whether the number a is greater than 2.</li>
<li>Use the <code>assert</code> keyword to check that a is equal to 2 within an error of 0.003.</li>
</ul>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="im">from</span> mynum <span class="im">import</span> a
<span class="co"># greater than 2 assertion here</span>
<span class="co"># 0.003 assertion here</span></code></pre></div>
</div>
</section>
<h2 id="numpy">NumPy</h2>
<p>The NumPy numerical computing library has a built-in function <code>assert_allclose</code> for comparing numbers within a tolerance:</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="im">from</span> numpy.testing <span class="im">import</span> assert_allclose
<span class="im">from</span> mynum <span class="im">import</span> a
assert_allclose(a, <span class="dv">2</span>, atol<span class="op">=</span><span class="fl">0.003</span>, rtol<span class="op">=</span><span class="dv">0</span>)</code></pre></div>
</div>
</div>
</article>
<div class="footer">
<a class="label swc-blue-bg" href="http://software-carpentry.org">Software Carpentry</a>
<a class="label swc-blue-bg" href="https://github.com/swcarpentry/lesson-template">Source</a>
<a class="label swc-blue-bg" href="mailto:admin@software-carpentry.org">Contact</a>
<a class="label swc-blue-bg" href="LICENSE.html">License</a>
</div>
</div>
<!-- Javascript placed at the end of the document so the pages load faster -->
<script src="http://software-carpentry.org/v5/js/jquery-1.9.1.min.js"></script>
<script src="css/bootstrap/bootstrap-js/bootstrap.js"></script>
</body>
</html>