-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmock.html
170 lines (144 loc) · 13.7 KB
/
mock.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
166
167
168
169
170
<!DOCTYPE html>
<html lang="en">
<head>
<title>2 weeks into internship. Mock Module and more!</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="http://lita.github.io/theme/css/main.css" type="text/css" />
<link rel="stylesheet" href="http://lita.github.io/theme/css/syntax.css" type="text/css" />
<link rel="stylesheet" href="http://lita.github.io/theme/css/social.css" type="text/css" />
<link rel="stylesheet" href="http://lita.github.io/theme/css/monokai.css" type="text/css" />
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<!--[if lte IE 7]>
<link rel="stylesheet" type="text/css" media="all" href="http://lita.github.io/css/ie.css"/>
<script src="http://lita.github.io/js/IE8.js" type="text/javascript"></script><![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" media="all" href="http://lita.github.io/css/ie6.css"/><![endif]-->
</head>
<body id="index" class="home">
<header id="banner" class="body">
<div class="social">
<a href='http://www.facebook.com/litacho' class='icon facebook'></a>
<a href='http://www.twitter.com/litacho' class='icon twitter'></a>
<a href='https://www.linkedin.com/profile/view?id=11701021' class='icon linkedin'></a>
<a href='http://www.github.com/lita' class='icon github'></a>
<a href='/feeds/all.atom.xml' class='icon rss'></a>
</div>
<h1><a href="http://lita.github.io/index.html">Lita Cho </a></h1>
<nav><ul class="main">
<li ><a href="http://lita.github.io/index.html">Home</a>|</li>
<!--Displays Pages on Menu -->
<li ><a href="http://lita.github.io/pages/about.html">About</a>|</li>
<li ><a href="http://lita.github.io/pages/projects.html">Projects</a>|</li>
<!--
<li class="dropdown">
Blog
<ul class="dropdown">
<li class="test"><a href="http://lita.github.io/category/blog.html">Blog</a></li>
<li class="test"><a href="http://lita.github.io/category/personal.html">personal</a></li>
<li class="test"><a href="http://lita.github.io/category/programming.html">programming</a></li>
</ul>
</li>
-->
<!--Displays Categories on Menu -->
<li class="active"><a href="http://lita.github.io/category/blog.html">Blog</a></li>
<!--
<li class="active"><a href="http://lita.github.io/category/blog.html">Blog</a></li>
<li ><a href="http://lita.github.io/category/personal.html">personal</a></li>
<li ><a href="http://lita.github.io/category/programming.html">programming</a></li>
</ul>
-->
</nav>
</header><!-- /#banner -->
<section id="content" class="body">
<article>
<header>
<h1 class="entry-title">
<a href="mock.html" rel="bookmark"
title="Permalink to 2 weeks into internship. Mock Module and more!">2 weeks into internship. Mock Module and more!</a></h1>
</header>
<div class="entry-content">
<footer class="post-info">
<abbr class="published" title="2014-06-17T16:18:00">
Tue 17 June 2014
</abbr>
<address class="vcard author">
By <a class="url fn" href="http://lita.github.io/author/lita-cho.html">Lita Cho</a>
</address>
<p>In <a href="http://lita.github.io/category/blog.html">Blog</a>. </p>
<p>tags: <a href="http://lita.github.io/tag/opw.html">opw</a><a href="http://lita.github.io/tag/python.html">python</a><a href="http://lita.github.io/tag/tkinter.html">tkinter</a></p></footer><!-- /.post-info --> <p>I was inspired by <a href="http://jvns.ca/blog/2014/06/13/asking-questions-is-a-superpower/">Julia Evan's blog</a> post about listing what she knows and what she doesn't know, and how asking questions is a super power! I try to be good about asking questions when I don't know something, but I feel like my questions are too vague. I really want to get better at boiling my question down!</p>
<p>Thus, I thought I take some time to list out what I don't know, specifically about unit testing, since that is all I have been doing this week! I'm been tasked with writing unit tests for the entire Turtle module! Can you believe there isn't a single unit test for this module at all, even though it is a standard library?! It also surprises me that the Turtle module is all in one file, but that's a different story.</p>
<h2>What I don't know</h2>
<h4>GUI Testing</h4>
<p>I am still not 100% sure how GUIs are run through unit testing. In Tkinter, it looks like the widget is initialized and test just the internal variables within the widget class. I thought they would compare pixel by pixel, checking if the GUI is the same or not. That might be because I often did that at Dreamworks for testing the renderer.</p>
<p>After talking with Ingrid, it looks like you can mock mouse-events by generating your own events through Tkinter. Then you pass in those events to Turtle to see how it reacts. The <code>mock</code> module would be perfect for this! More on the <code>mock</code> module later!</p>
<p>We are still learning as we develop our test coverage. In most cases, I create a GUI object and just test the internal state of Turtle rather than the Tkinter objects themselves. Everything seems to be coming together! As my tests run, all these GUI windows appear and disappear like I am being hacked. Soon, I can scare all my friends by running my tests on their computer! >:D</p>
<h4>The test.support module</h4>
<p>CPython has an internal module called <code>test.support</code>, which holds all the utility functions for its unit tests. It has useful features, such as <code>use_resource</code>, where you can pass along command-line flags to your unit tests. We use this a lot for Turtle/Tkinter testing, as we need to check if GUIs are enabled in our environment. Thus rather than running the check for every module, an outside program that checks if GUIs are enabled and passes a 'gui' flag to all the other GUI unit tests if it passes. If not, then a warning appears, and the GUI unit tests don't run.</p>
<p>However, the support module has a LOT of stuff in it that I don't know about. I really want to study it more so I know what is available to me when I write my tests.</p>
<h4>The mock module</h4>
<p>Another thing I don't know really well is the <code>mock</code> module. I definitely feel like my tests can be more robust and cleaner with this module. This module has so many features! My favorite so far is the <code>patch</code> decorator, where you can override the behavior of a function specifically for that test case. I have used it on programs that print to <code>stdout</code>. Before, I would have to override <code>sys.stdout</code> manually and make sure to set it back correctly, or my print function is borked.</p>
<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">unittest</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">StringIO</span>
<span class="k">def</span> <span class="nf">lets_print_something</span><span class="p">():</span>
<span class="k">print</span><span class="p">(</span><span class="s">"Dude, I totally printed"</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">TestPrinting</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">test_lets_print_something</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">sysout</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">io</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>
<span class="n">lets_print_something</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">getvalue</span><span class="p">(),</span>
<span class="s">"Dude, I totally printed</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">sysout</span>
</pre></div>
<p>This totally felt ugly to me. It's like remembering to <code>close</code> your file objects. I never do that anymore due to the <code>with</code> statement. However, with the <code>patch</code> decorator, this test looks so much cleaner!</p>
<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">unittest</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">StringIO</span>
<span class="kn">from</span> <span class="nn">unittest.mock</span> <span class="kn">import</span> <span class="n">patch</span>
<span class="k">def</span> <span class="nf">lets_print_something</span><span class="p">():</span>
<span class="k">print</span><span class="p">(</span><span class="s">"Dude, I totally printed"</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">TestPrintingMock</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="nd">@patch</span><span class="p">(</span><span class="s">'sys.stdout'</span><span class="p">,</span> <span class="n">new_callable</span><span class="o">=</span><span class="n">StringIO</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_lets_print_something</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mock_stdout</span><span class="p">):</span>
<span class="n">lets_print_something</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="n">mock_stdout</span><span class="o">.</span><span class="n">getvalue</span><span class="p">(),</span>
<span class="s">"Dude, I totally printed</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
</pre></div>
<p>The patch decorator passes a <code>MagicMock</code> object by default, but I've changed it to give me a <code>StringIO</code> object using the <code>new_callable</code> argument. The decorator will handle passing this argument in, so you don't need to pass it anything to make it run.</p>
<p>I just barely scratched the surface. Your unit tests don't need to create side affects! <a href="http://www.toptal.com/python/an-introduction-to-mocking-in-python">Naftuli Tzvi Kay</a> has a great blog post about mocking in Python and how to test if your program called <code>rm</code> without generating any files!</p>
<p><a href="https://docs.python.org/3.5/library/unittest.mock.html#module-unittest.mock">The Python documentation on mocking</a> is also very good. However, it is only available on 3.3 and up. You will need to <code>pip install mock</code> for earlier versions of python.</p>
<p>Alex Marandon also has a great blog post about <a href="http://alexmarandon.com/articles/python_mock_gotchas/">Python Mock Gotchas</a>. I haven't gotten enough experience with the module where I have run into these, but I feel like it is a time saver!</p>
<p>This blog post has gotten way bigger than I expected. I really want to thank Amandine Lee, a fellow Hacker Schooler, about showing me the <code>mock</code> module, and her general insights regarding unit testing! Also, my fellow intern, Ingrid Cheung, for helping me with GUI testing! Together, Turtle will have better test coverage!!!</p>
<p>I need to write a blog post about the basics of Turtle. I hope to get to it soon!</p>
</div><!-- /.entry-content -->
<div class="comments">
<h2>Comments !</h2>
<div id="disqus_thread"></div>
<script type="text/javascript">
var disqus_identifier = "mock.html";
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://litacho.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
</div>
</article>
</section>
<section id="extras" class="body">
</section><!-- /#extras -->
<footer id="contentinfo" class="body">
</footer><!-- /#contentinfo -->
<script type="text/javascript">
var disqus_shortname = 'litacho';
(function () {
var s = document.createElement('script'); s.async = true;
s.type = 'text/javascript';
s.src = 'http://' + disqus_shortname + '.disqus.com/count.js';
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
}());
</script>
</body>
</html>