-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtesting.html
442 lines (418 loc) · 40.7 KB
/
testing.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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Development — wonambi 7.11 documentation</title>
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="shortcut icon" href="_static/wonambi.ico"/>
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/sphinx_highlight.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Change Log" href="changelog.html" />
<link rel="prev" title="wonambi.graphoelement module" href="api/wonambi.graphoelement.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> wonambi
<img src="_static/wonambi.png" class="logo" alt="Logo"/>
</a>
<div class="version">
7.11
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="introduction.html">WONAMBI</a><ul>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#features">Features</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#installation">Installation</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#run-it">Run it!</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#documentation">Documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#change-log">Change Log</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#requirements">Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#optional-requirements">Optional Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#status">Status</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#license">License</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="installation.html">Installation</a><ul>
<li class="toctree-l2"><a class="reference internal" href="installation.html#linux-mac-os-x">Linux / Mac OS X</a></li>
<li class="toctree-l2"><a class="reference internal" href="installation.html#windows">Windows</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="analysis/index.html">Tutorial / Analysis</a><ul>
<li class="toctree-l2"><a class="reference internal" href="analysis/tutorial.html">Get Started</a></li>
<li class="toctree-l2"><a class="reference internal" href="analysis/spectrum.html">Frequency Domain</a></li>
<li class="toctree-l2"><a class="reference internal" href="analysis/plot3d.html">Plot 3D images</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="cmd.html">Command Line</a><ul>
<li class="toctree-l2"><a class="reference internal" href="cmd.html#wonambi">wonambi</a></li>
<li class="toctree-l2"><a class="reference internal" href="cmd.html#won-convert">won_convert</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="gui/index.html">Graphical User Interface</a><ul>
<li class="toctree-l2"><a class="reference internal" href="gui/open.html">Open Dataset</a></li>
<li class="toctree-l2"><a class="reference internal" href="gui/labels.html">Edit Labels</a></li>
<li class="toctree-l2"><a class="reference internal" href="gui/channels.html">Plot Channels</a></li>
<li class="toctree-l2"><a class="reference internal" href="gui/traces.html">Navigation</a></li>
<li class="toctree-l2"><a class="reference internal" href="gui/notes.html">Annotations</a></li>
<li class="toctree-l2"><a class="reference internal" href="gui/detect.html">Event detection</a></li>
<li class="toctree-l2"><a class="reference internal" href="gui/methods.html">Detection methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="gui/analysis.html">Analysis console</a></li>
<li class="toctree-l2"><a class="reference internal" href="gui/screenshot.html">Screenshot</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="api/wonambi.html">Modules, classes, functions</a><ul>
<li class="toctree-l2"><a class="reference internal" href="api/wonambi.html#subpackages">Subpackages</a></li>
<li class="toctree-l2"><a class="reference internal" href="api/wonambi.html#submodules">Submodules</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Development</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#prepare-test-environment">Prepare Test Environment</a></li>
<li class="toctree-l2"><a class="reference internal" href="#get-files">1. Get Files</a></li>
<li class="toctree-l2"><a class="reference internal" href="#run-the-tests">2. Run the Tests</a></li>
<li class="toctree-l2"><a class="reference internal" href="#coverage">3. Coverage</a></li>
<li class="toctree-l2"><a class="reference internal" href="#documentation">4. Documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="#release">5. Release</a></li>
<li class="toctree-l2"><a class="reference internal" href="#tips-and-tricks">Tips and Tricks</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html">Change Log</a><ul>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#version-7">Version 7</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#version-6">Version 6</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#version-5">Version 5</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#version-4">Version 4</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#version-3">Version 3</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#version-2">Version 2</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#version-1">Version 1</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="todo.html">TODO</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">wonambi</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a></li>
<li class="breadcrumb-item active">Development</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="development">
<h1>Development<a class="headerlink" href="#development" title="Permalink to this heading"></a></h1>
<p><strong>wonambi</strong> follows a <a class="reference external" href="https://en.wikipedia.org/wiki/Test-driven_development">test-driven development</a> paradigm, in which tests reflect real-life problems and code is added to <strong>wonambi</strong> to solve those problems.
Tests are necessary to make sure that <strong>wonambi</strong> is working correctly.</p>
<p>Development consists of separate steps:</p>
<div class="line-block">
<div class="line"><a class="reference internal" href="#testfiles"><span class="std std-ref">1. Get Files</span></a>: collect the data used in the tests,</div>
<div class="line"><a class="reference internal" href="#testtest"><span class="std std-ref">2. Run the Tests</span></a>: run the tests,</div>
<div class="line"><a class="reference internal" href="#testcov"><span class="std std-ref">3. Coverage</span></a>: check if tests cover all the relevant code,</div>
<div class="line"><a class="reference internal" href="#testdocs"><span class="std std-ref">4. Documentation</span></a>: prepare the documentation (optional),</div>
<div class="line"><a class="reference internal" href="#testrelease"><span class="std std-ref">5. Release</span></a>: make a new release (optional).</div>
</div>
<p>These steps can be run using the convenience script <code class="docutils literal notranslate"><span class="pre">setup_wonambi.py</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">usage</span><span class="p">:</span> <span class="n">setup_wonambi</span> <span class="p">[</span><span class="o">-</span><span class="n">h</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">r</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">m</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">g</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">t</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span><span class="n">test_import</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">d</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">c</span><span class="p">]</span>
<span class="p">[</span><span class="o">--</span><span class="n">clean_all</span><span class="p">]</span>
<span class="n">Run</span> <span class="n">tests</span> <span class="ow">and</span> <span class="n">documentation</span> <span class="k">for</span> <span class="n">wonambi</span>
<span class="n">optional</span> <span class="n">arguments</span><span class="p">:</span>
<span class="o">-</span><span class="n">h</span><span class="p">,</span> <span class="o">--</span><span class="n">help</span> <span class="n">show</span> <span class="n">this</span> <span class="n">help</span> <span class="n">message</span> <span class="ow">and</span> <span class="n">exit</span>
<span class="o">-</span><span class="n">r</span><span class="p">,</span> <span class="o">--</span><span class="n">release</span> <span class="n">create</span> <span class="n">a</span> <span class="n">point</span> <span class="n">release</span>
<span class="o">-</span><span class="n">m</span><span class="p">,</span> <span class="o">--</span><span class="n">major_release</span> <span class="n">create</span> <span class="n">a</span> <span class="n">major</span> <span class="n">release</span>
<span class="o">-</span><span class="n">g</span><span class="p">,</span> <span class="o">--</span><span class="n">get_files</span> <span class="n">download</span> <span class="n">datasets</span> <span class="n">to</span> <span class="n">run</span> <span class="n">tests</span>
<span class="o">-</span><span class="n">t</span><span class="p">,</span> <span class="o">--</span><span class="n">tests</span> <span class="n">run</span> <span class="n">tests</span>
<span class="o">--</span><span class="n">test_import</span> <span class="n">run</span> <span class="n">tests</span><span class="p">,</span> <span class="n">but</span> <span class="n">without</span> <span class="n">optional</span> <span class="n">depencencies</span>
<span class="o">-</span><span class="n">d</span><span class="p">,</span> <span class="o">--</span><span class="n">docs</span> <span class="n">create</span> <span class="n">documentations</span> <span class="p">(</span><span class="n">run</span> <span class="n">tests</span> <span class="n">first</span><span class="p">)</span>
<span class="o">-</span><span class="n">c</span><span class="p">,</span> <span class="o">--</span><span class="n">clean</span> <span class="n">clean</span> <span class="n">up</span> <span class="n">docs</span> <span class="p">(</span><span class="n">including</span> <span class="n">intermediate</span> <span class="n">files</span><span class="p">)</span>
<span class="o">--</span><span class="n">clean_all</span> <span class="n">clean</span> <span class="n">up</span> <span class="n">docs</span> <span class="p">(</span><span class="o">--</span><span class="n">clean</span><span class="p">)</span> <span class="ow">and</span> <span class="n">files</span> <span class="k">for</span> <span class="n">tests</span>
</pre></div>
</div>
<section id="prepare-test-environment">
<h2>Prepare Test Environment<a class="headerlink" href="#prepare-test-environment" title="Permalink to this heading"></a></h2>
<p>Testing and documentation have additional requirements.
Tests rely on <code class="docutils literal notranslate"><span class="pre">pytest</span></code>, with the add-ons (<code class="docutils literal notranslate"><span class="pre">pytest-qt</span></code> and <code class="docutils literal notranslate"><span class="pre">pytest-cov</span></code>), while documentation runs on <code class="docutils literal notranslate"><span class="pre">sphinx</span></code>.</p>
<p>Install all the requirements this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">pytest</span> <span class="n">pytest</span><span class="o">-</span><span class="n">qt</span> <span class="n">pytest</span><span class="o">-</span><span class="n">cov</span>
<span class="n">pip</span> <span class="n">install</span> <span class="n">sphinx</span> <span class="n">sphinx_rtd_theme</span>
</pre></div>
</div>
</section>
<section id="get-files">
<span id="testfiles"></span><h2>1. Get Files<a class="headerlink" href="#get-files" title="Permalink to this heading"></a></h2>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">setup_wonambi</span><span class="o">.</span><span class="n">py</span> <span class="o">--</span><span class="n">get_files</span>
</pre></div>
</div>
<p>Before you can run the tests, you need to collect the data.
Data comes from publicly available repositories (see source code for <code class="docutils literal notranslate"><span class="pre">setup_wonambi.py</span></code> for links).
Sometimes, however, data is not readily available and might contain information that cannot be publicly shared.
These datasets are stored on a cloud service with a private URL.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Before you run <code class="docutils literal notranslate"><span class="pre">setup_wonambi.py</span> <span class="pre">--get_files</span></code>, you need to specify these environmental variables:
* <code class="docutils literal notranslate"><span class="pre">DATA_URL</span></code> : the private URL (contact the authors for info)
* <code class="docutils literal notranslate"><span class="pre">BCI2000_USER</span></code>, <code class="docutils literal notranslate"><span class="pre">BCI2000_PASSWORD</span></code> : the username and password of the BCI2000 svn repo (create a new account on the <a class="reference external" href="https://www.bci2000.org/useradmin/">BCI2000 website</a>)</p>
</div>
<p>This function will create new folders in <code class="docutils literal notranslate"><span class="pre">wonambi/tests/downloads</span></code> (where the downloaded files are cached) and <code class="docutils literal notranslate"><span class="pre">wonambi/tests/data</span></code> (the data that will be used for the tests).
There is an additional folder (<code class="docutils literal notranslate"><span class="pre">wonambi/tests/exported</span></code>), where files created during the tests are stored.</p>
</section>
<section id="run-the-tests">
<span id="testtest"></span><h2>2. Run the Tests<a class="headerlink" href="#run-the-tests" title="Permalink to this heading"></a></h2>
<section id="run-all-the-tests">
<h3>Run all the tests<a class="headerlink" href="#run-all-the-tests" title="Permalink to this heading"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">setup_wonambi</span><span class="o">.</span><span class="n">py</span> <span class="o">--</span><span class="n">tests</span>
</pre></div>
</div>
<p>This function will run all the tests.
Note that quite some tests will show an image or a window, do not click on those windows while the tests are running.</p>
<p>See <a class="reference internal" href="#testtricks"><span class="std std-ref">Tips and Tricks</span></a> for suggestions on how to write tests.</p>
</section>
<section id="run-a-specific-test">
<h3>Run a specific test<a class="headerlink" href="#run-a-specific-test" title="Permalink to this heading"></a></h3>
<p>Running all the tests might be quite time consuming.
If you want to run only one specific file in the test directory do:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pytest</span> <span class="n">tests</span><span class="o">/</span><span class="n">test_datatype</span><span class="o">.</span><span class="n">py</span>
</pre></div>
</div>
</section>
<section id="test-importerror">
<h3>Test ImportError<a class="headerlink" href="#test-importerror" title="Permalink to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">wonambi</span></code> should run on a minimal environment with only <code class="docutils literal notranslate"><span class="pre">numpy</span></code> and <code class="docutils literal notranslate"><span class="pre">scipy</span></code> installed.
It should not throw any <code class="docutils literal notranslate"><span class="pre">ImportError</span></code> if other optional packages (f.e. <code class="docutils literal notranslate"><span class="pre">PyQt5</span></code> or <code class="docutils literal notranslate"><span class="pre">nibabel</span></code>) are not installed, but you should get an informative <code class="docutils literal notranslate"><span class="pre">ImportError</span></code> if you do try to run a function that requires an optional dependency (in other words, no errors when importing the program, only when running the program).</p>
<p>To test that the <code class="docutils literal notranslate"><span class="pre">ImportError</span></code> is correctly raised when you need functions from optional dependencies, you should run:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">setup_wonambi</span><span class="o">.</span><span class="n">py</span> <span class="o">--</span><span class="n">test_import</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>You should run this only in an environment that does not have the optional dependencies installed.
Use <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-m</span> <span class="pre">venv</span></code> to create a minimal environment.
Then install <code class="docutils literal notranslate"><span class="pre">numpy</span></code> and <code class="docutils literal notranslate"><span class="pre">scipy</span></code> with <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">numpy</span> <span class="pre">scipy</span></code>.
Also remember to install the packages needed for the tests (<code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">pytest</span> <span class="pre">pytest-cov</span></code>).</p>
</div>
<p>When importing a function from an optional module, you should wrap the import statement in this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">..utils</span> <span class="kn">import</span> <span class="n">MissingDependency</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">optionalmodule</span> <span class="kn">import</span> <span class="n">function</span>
<span class="k">except</span> <span class="ne">ImportError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="n">function</span> <span class="o">=</span> <span class="n">MissingDependency</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
</pre></div>
</div>
<p>Note that <code class="docutils literal notranslate"><span class="pre">optionalmodule</span></code> and <code class="docutils literal notranslate"><span class="pre">function</span></code> are placeholders.
You need to change only those two names.
Also, you might need to adjust the relative import of <code class="docutils literal notranslate"><span class="pre">..utils</span></code> depending on which module you’re working on.</p>
<p>All the import tests should be in <code class="docutils literal notranslate"><span class="pre">wonambi/tests/test_import.py</span></code>.</p>
</section>
</section>
<section id="coverage">
<span id="testcov"></span><h2>3. Coverage<a class="headerlink" href="#coverage" title="Permalink to this heading"></a></h2>
<p>After running <code class="docutils literal notranslate"><span class="pre">setup_wonambi.py</span> <span class="pre">--tests</span></code>, you can open (with a browser) the file <code class="docutils literal notranslate"><span class="pre">wonambi/htmlcov/index.html</span></code> which will give you a report of the lines being covered by the tests.</p>
</section>
<section id="documentation">
<span id="testdocs"></span><h2>4. Documentation<a class="headerlink" href="#documentation" title="Permalink to this heading"></a></h2>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">setup_wonambi</span><span class="o">.</span><span class="n">py</span> <span class="o">--</span><span class="n">docs</span>
</pre></div>
</div>
<p>The documentation consists of a mix of normal <code class="docutils literal notranslate"><span class="pre">.rst</span></code> pages (such as this one), <code class="docutils literal notranslate"><span class="pre">.rst</span></code> pages that contains images, and pages containing the API.
The images and the API pages (<code class="docutils literal notranslate"><span class="pre">wonambi/docs/source/api</span></code>) are generated automatically.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The images are all generated automatically by the tests, so you always need to first run the tests and then generate the documentation.</p>
</div>
<p>To read the documentation, open <code class="docutils literal notranslate"><span class="pre">wonambi/docs/build/html/index.html</span></code> with your browser.</p>
</section>
<section id="release">
<span id="testrelease"></span><h2>5. Release<a class="headerlink" href="#release" title="Permalink to this heading"></a></h2>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">setup_wonambi</span><span class="o">.</span><span class="n">py</span> <span class="o">--</span><span class="n">release</span>
</pre></div>
</div>
<p>for minor releases or</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">setup_wonambi</span><span class="o">.</span><span class="n">py</span> <span class="o">--</span><span class="n">major</span>
</pre></div>
</div>
<p>for major releases.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The script will ask you for a release comment, which will be used in the <a class="reference internal" href="changelog.html#changelog"><span class="std std-ref">Change Log</span></a>.</p>
</div>
<p>New features or major bug-fixes deserve their own release.
<code class="docutils literal notranslate"><span class="pre">wonambi</span></code> has a major and a minor release number, and version 1 is when the program was initially released (not the stable API, which will never be achieved for a work-in-progress).
This keeps the version number clear and avoids version numbers starting with a zero.</p>
<p>Releases are handled by <code class="docutils literal notranslate"><span class="pre">github</span></code> and <code class="docutils literal notranslate"><span class="pre">travis</span></code>.
A new release consists of a <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">tag</span></code>, which is uploaded to <code class="docutils literal notranslate"><span class="pre">github</span></code>.
<code class="docutils literal notranslate"><span class="pre">travis</span></code> takes care of creating a complete package and uploading it to <a class="reference external" href="https://pypi.python.org/pypi/wonambi">pypi</a>.</p>
</section>
<section id="tips-and-tricks">
<span id="testtricks"></span><h2>Tips and Tricks<a class="headerlink" href="#tips-and-tricks" title="Permalink to this heading"></a></h2>
<p>Writing tests with <code class="docutils literal notranslate"><span class="pre">pytest</span></code> is quite straightforward.
Simply add a function called <code class="docutils literal notranslate"><span class="pre">test_...</span></code> and write the code you want to test.
To check if the result is what you expect, use <code class="docutils literal notranslate"><span class="pre">assert</span></code>.
Floating-point errors can be prevented by using <code class="docutils literal notranslate"><span class="pre">pytest.approx</span></code>.</p>
<section id="files">
<h3>Files<a class="headerlink" href="#files" title="Permalink to this heading"></a></h3>
<p>All the files to be used in the tests and those generated by tests should be enumerated in <code class="docutils literal notranslate"><span class="pre">tests/paths.py</span></code>.</p>
</section>
<section id="raises-tests">
<h3>Raises tests<a class="headerlink" href="#raises-tests" title="Permalink to this heading"></a></h3>
<p>To test if a specific call raises an exception, write:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pytest</span> <span class="kn">import</span> <span class="n">raises</span>
<span class="k">def</span> <span class="nf">test_raises</span><span class="p">():</span>
<span class="k">with</span> <span class="n">raises</span><span class="p">(</span><span class="ne">SyntaxError</span><span class="p">):</span>
<span class="kc">True</span> <span class="o">=</span> <span class="kc">False</span>
</pre></div>
</div>
</section>
<section id="images">
<h3>Images<a class="headerlink" href="#images" title="Permalink to this heading"></a></h3>
<p>All images in the documentation should be generated by the tests (so that we don’t have images belonging to old versions).</p>
<section id="vispy">
<h4>Vispy<a class="headerlink" href="#vispy" title="Permalink to this heading"></a></h4>
<p><code class="docutils literal notranslate"><span class="pre">vispy</span></code> is a highly efficient package to plot OpenGL images.
This is particularly useful for 3D images.
Unfortunately, <code class="docutils literal notranslate"><span class="pre">vispy</span></code> requires some complicated syntax to make simpler plots (for that, you can use <code class="docutils literal notranslate"><span class="pre">plotly</span></code>).</p>
<p>Images belonging to the <code class="docutils literal notranslate"><span class="pre">viz</span></code> module using <code class="docutils literal notranslate"><span class="pre">vispy</span></code> should be stored in the <code class="docutils literal notranslate"><span class="pre">VIZ_PATH</span></code> directory.
Save the images in that directory (making sure to use a unique name for each figure).
Then when you write the documentation (in the <code class="docutils literal notranslate"><span class="pre">wonambi/docs/source/analysis/</span></code> folder), simply point to that figure:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">..</span> <span class="n">image</span><span class="p">::</span> <span class="n">images</span><span class="o">/</span><span class="n">viz3_01_XXX</span><span class="o">.</span><span class="n">png</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If you want to show in the documentation the code that was used to generate the image, you can refer to the test script using this syntax:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">..</span> <span class="n">literalinclude</span><span class="p">::</span> <span class="o">../../../</span><span class="n">tests</span><span class="o">/</span><span class="n">test_viz_plot3d</span><span class="o">.</span><span class="n">py</span>
<span class="p">:</span><span class="n">lines</span><span class="p">:</span> <span class="mi">23</span><span class="o">-</span><span class="mi">26</span>
</pre></div>
</div>
</div>
</section>
<section id="plotly">
<h4>Plotly<a class="headerlink" href="#plotly" title="Permalink to this heading"></a></h4>
<p><code class="docutils literal notranslate"><span class="pre">plotly</span></code> can be used to plot interactive plots.
The syntax is very intuitive, but unfortunately it doesn’t work well for 3D plots with lots of points (for that, use <code class="docutils literal notranslate"><span class="pre">vispy</span></code>).</p>
<p>In the documentation, we can use interactive plots as well.
You can create a test by simply preparing a figure (here called <code class="docutils literal notranslate"><span class="pre">example_interactive_image</span></code>) and saving it with the function <code class="docutils literal notranslate"><span class="pre">tests.utils.save_plotly_fig</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">fig</span> <span class="o">=</span> <span class="n">go</span><span class="o">.</span><span class="n">Figure</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="p">[{</span><span class="s1">'y'</span><span class="p">:</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)}])</span>
<span class="n">save_plotly_fig</span><span class="p">(</span><span class="n">fig</span><span class="p">,</span> <span class="s1">'example_interactive_image'</span><span class="p">)</span>
</pre></div>
</div>
<p>Then, in the documentation (in the <code class="docutils literal notranslate"><span class="pre">wonambi/docs/source/analysis/</span></code> folder), first you need to use this line at the very top:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">..</span> <span class="n">raw</span><span class="p">::</span> <span class="n">html</span>
<span class="o"><</span><span class="n">script</span> <span class="n">src</span><span class="o">=</span><span class="s2">"https://cdn.plot.ly/plotly-latest.min.js"</span><span class="o">></</span><span class="n">script</span><span class="o">></span>
</pre></div>
</div>
<p>In the same doc file, to insert the interactive image, you can use:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">..</span> <span class="n">raw</span><span class="p">::</span> <span class="n">html</span>
<span class="p">:</span><span class="n">file</span><span class="p">:</span> <span class="n">plotly</span><span class="o">/</span><span class="n">example_interactive_image</span><span class="o">.</span><span class="n">html</span>
</pre></div>
</div>
<p>You can use <code class="docutils literal notranslate"><span class="pre">literalinclude</span></code> to show the actual code in the tests.</p>
</section>
</section>
<section id="qt-test">
<h3>Qt test<a class="headerlink" href="#qt-test" title="Permalink to this heading"></a></h3>
<p>Testing using Qt is often complicated and verbose, but it’s still very important to test it right.
A simple test should be written as:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">test_mainwindow</span><span class="p">(</span><span class="n">qtbot</span><span class="p">):</span>
<span class="n">w</span> <span class="o">=</span> <span class="n">MainWindow</span><span class="p">()</span>
<span class="n">qtbot</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">w</span><span class="p">)</span>
</pre></div>
</div>
<section id="modal-dialog">
<h4>Modal Dialog<a class="headerlink" href="#modal-dialog" title="Permalink to this heading"></a></h4>
<p>Modal dialogs are those dialog that block the main window and keep it on the background.
I don’t know how to interact with the modal dialog, so we just skip the dialog and we pass <code class="docutils literal notranslate"><span class="pre">test_filename</span></code> as additional argument to the method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">make_new_group</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">checked</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">test_name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">test_name</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">new_name</span> <span class="o">=</span> <span class="n">QInputDialog</span><span class="o">.</span><span class="n">getText</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'New Group'</span><span class="p">,</span>
<span class="s1">'Enter Name'</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">new_name</span> <span class="o">=</span> <span class="p">[</span><span class="n">test_name</span><span class="p">,</span> <span class="kc">True</span><span class="p">]</span> <span class="c1"># like output of getText</span>
</pre></div>
</div>
</section>
<section id="screenshots">
<h4>Screenshots<a class="headerlink" href="#screenshots" title="Permalink to this heading"></a></h4>
<p>Screenshot of a window or a part of a window (widget), you can highlight a widget in red and create a screenshot with:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">test_grab_screenshot</span><span class="p">(</span><span class="n">qtbot</span><span class="p">):</span>
<span class="n">w</span> <span class="o">=</span> <span class="n">MainWindow</span><span class="p">()</span>
<span class="n">qtbot</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">w</span><span class="p">)</span>
<span class="n">w</span><span class="o">.</span><span class="n">labels</span><span class="o">.</span><span class="n">setStyleSheet</span><span class="p">(</span><span class="s2">"background-color: red;"</span><span class="p">)</span>
<span class="n">w</span><span class="o">.</span><span class="n">grab</span><span class="p">()</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">GUI_PATH</span> <span class="o">/</span> <span class="s1">'xxx.png'</span><span class="p">))</span>
<span class="n">w</span><span class="o">.</span><span class="n">labels</span><span class="o">.</span><span class="n">setStyleSheet</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
</pre></div>
</div>
<p>If you use a menubar, there is no simple way to get a screenshot, so you need to capture the whole screen:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">test_widget_notes_import_fasst</span><span class="p">(</span><span class="n">qtbot</span><span class="p">):</span>
<span class="n">w</span> <span class="o">=</span> <span class="n">MainWindow</span><span class="p">()</span>
<span class="n">qtbot</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">w</span><span class="p">)</span>
<span class="n">menubar</span> <span class="o">=</span> <span class="n">w</span><span class="o">.</span><span class="n">menuBar</span><span class="p">()</span>
<span class="c1"># --- Complex code to capture screenshot of menubar ---#</span>
<span class="k">def</span> <span class="nf">screenshot</span><span class="p">():</span>
<span class="n">screen</span> <span class="o">=</span> <span class="n">QApplication</span><span class="o">.</span><span class="n">primaryScreen</span><span class="p">()</span>
<span class="n">png_name</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">GUI_PATH</span> <span class="o">/</span> <span class="s1">'notes_04_import_fasst.png'</span><span class="p">)</span>
<span class="n">screen</span><span class="o">.</span><span class="n">grabWindow</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">w</span><span class="o">.</span><span class="n">x</span><span class="p">(),</span> <span class="n">w</span><span class="o">.</span><span class="n">y</span><span class="p">(),</span> <span class="n">w</span><span class="o">.</span><span class="n">width</span><span class="p">(),</span> <span class="n">w</span><span class="o">.</span><span class="n">height</span><span class="p">())</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">png_name</span><span class="p">)</span>
<span class="c1"># lots of processEvents needed</span>
<span class="n">QApplication</span><span class="o">.</span><span class="n">processEvents</span><span class="p">()</span>
<span class="n">QTimer</span><span class="o">.</span><span class="n">singleShot</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="n">screenshot</span><span class="p">)</span>
<span class="n">QApplication</span><span class="o">.</span><span class="n">processEvents</span><span class="p">()</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="n">QApplication</span><span class="o">.</span><span class="n">processEvents</span><span class="p">()</span>
<span class="n">w</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="c1"># --- ---#</span>
</pre></div>
</div>
</section>
</section>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="api/wonambi.graphoelement.html" class="btn btn-neutral float-left" title="wonambi.graphoelement module" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="changelog.html" class="btn btn-neutral float-right" title="Change Log" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>© Copyright 2013-2022, Gio Piantoni / Jordan O'Byrne.</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(false);
});
</script>
</body>
</html>