mithril-vndb/archive/v1.0.0-rc.8/testing.html
2017-01-26 20:46:32 -05:00

122 lines
5.7 KiB
HTML

<html>
<head>
<meta charset="UTF-8" />
<title>Mithril.js</title>
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css' />
<link href="lib/prism/prism.css" rel="stylesheet" />
<link href="style.css" rel="stylesheet" />
</head>
<body>
<header>
<section>
<h1>Mithril <small>1.0.0-rc.8</small></h1>
<nav>
<a href="index.html">Guide</a>
<a href="api.html">API</a>
<a href="https://gitter.im/lhorie/mithril.js">Chat</a>
<a href="https://github.com/lhorie/mithril.js">Github</a>
</nav>
</section>
</header>
<main>
<section>
<h1 id="testing">Testing</h1>
<ul>
<li>Tutorials<ul>
<li><a href="installation.html">Installation</a></li>
<li><a href="index.html">Introduction</a></li>
<li><a href="simple-application.html">Tutorial</a></li>
</ul>
</li>
<li>Resources<ul>
<li><a href="jsx.html">JSX</a></li>
<li><a href="es6.html">ES6</a></li>
<li><a href="css.html">CSS</a></li>
<li><a href="animation.html">Animation</a></li>
<li><strong><a href="testing.html">Testing</a></strong></li>
<li><a href="examples.html">Examples</a></li>
</ul>
</li>
<li>Key concepts<ul>
<li><a href="vnodes.html">Vnodes</a></li>
<li><a href="components.html">Components</a></li>
<li><a href="lifecycle-methods.html">Lifecycle methods</a></li>
<li><a href="keys.html">Keys</a></li>
<li><a href="autoredraw.html">Autoredraw system</a></li>
</ul>
</li>
<li>Social<ul>
<li><a href="https://github.com/lhorie/mithril.js/wiki/JOBS">Mithril Jobs</a></li>
<li><a href="contributing.html">How to contribute</a></li>
<li><a href="credits.html">Credits</a></li>
</ul>
</li>
<li>Misc<ul>
<li><a href="framework-comparison.html">Framework comparison</a></li>
<li><a href="change-log.html">Change log/Migration</a></li>
</ul>
</li>
</ul>
<p>Mithril comes with a testing framework called <a href="https://github.com/lhorie/mithril.js/tree/rewrite/ospec">ospec</a>. What makes it different from most test frameworks is that it avoids all configurability for the sake of avoiding <a href="http://catb.org/jargon/html/Y/yak-shaving.html">yak shaving</a> and <a href="https://en.wikipedia.org/wiki/Analysis_paralysis">analysis paralysis</a>.</p>
<p>The easist way to setup the test runner is to create an NPM script for it. Open your project&#39;s <code>package.json</code> file and edit the <code>test</code> line under the <code>scripts</code> section:</p>
<pre><code>{
&quot;name&quot;: &quot;my-project&quot;,
&quot;scripts&quot;: {
&quot;test&quot;: &quot;ospec&quot;
}
}
</code></pre><p>Remember this is a JSON file, so object key names such as <code>&quot;test&quot;</code> must be inside of double quotes.</p>
<p>To setup a test suite, create a <code>tests</code> folder and inside of it, create a test file:</p>
<pre><code class="lang-javascript">// file: tests/math-test.js
var o = require(&quot;mithril/ospec/ospec&quot;)
o.spec(&quot;math&quot;, function() {
o(&quot;addition works&quot;, function() {
o(1 + 2).equals(3)
})
})
</code></pre>
<p>To run the test, use the command <code>npm test</code>. Ospec considers any Javascript file inside of a <code>tests</code> folder (anywhere in the project) to be a test.</p>
<pre><code>npm test
</code></pre><hr>
<h3 id="good-testing-practices">Good testing practices</h3>
<p>Generally speaking, there are two ways to write tests: upfront and after the fact.</p>
<p>Writing tests upfront requires specifications to be frozen. Upfront tests are a great way of codifying the rules that a yet-to-be-implemented API must obey. However, writing tests upfront may not be a suitable strategy if you don&#39;t have a reasonable idea of what your project will look like, if the scope of the API is not well known or if it&#39;s likely to change (e.g. based on previous history at the company).</p>
<p>Writing tests after the fact is a way to document the behavior of a system and avoid regressions. They are useful to ensure that obscure corner cases are not inadvertedly broken and that previously fixed bugs do not get re-introduced by unrelated changes.</p>
<hr>
<h3 id="unit-testing">Unit testing</h3>
<p>Unit testing is the practice of isolating a part of an application (typically a single module), and asserting that, given some inputs, it produces the expected outputs.</p>
<p>Testing a Mithril component is easy. Let&#39;s assume we have a simple component like this:</p>
<pre><code class="lang-javascript">// MyComponent.js
var m = require(&quot;mithril&quot;)
module.exports = {
view: function() {
return m(&quot;div&quot;, &quot;Hello world&quot;)
}
}
</code></pre>
<p>We can then create a <code>tests/MyComponent.js</code> file and create a test for this component like this:</p>
<pre><code class="lang-javascript">var MyComponent = require(&quot;MyComponent&quot;)
o.spec(&quot;MyComponent&quot;, function() {
o(&quot;returns a div&quot;, function() {
var vnode = MyComponent.view()
o(vnode.tag).equals(&quot;div&quot;)
o(vnode.children.length).equals(1)
o(vnode.children[0].tag).equals(&quot;#&quot;)
o(vnode.children[0].children).equals(&quot;Hello world&quot;)
})
})
</code></pre>
<p>Typically, you wouldn&#39;t test the structure of the vnode tree so granularly, and you would instead only test non-trivial, dynamic aspects of the view. A tool that can help making testing easier with deep vnode trees is <a href="https://github.com/StephanHoyer/mithril-query">Mithril Query</a>.</p>
<p>Sometimes, you need to mock the dependencies of a module in order to test the module in isolation. <a href="https://github.com/mfncooper/mockery">Mockery</a> is one tool that allows you to do that.</p>
<hr />
<small>License: MIT. &copy; Leo Horie.</small>
</section>
</main>
<script src="lib/prism/prism.js"></script>
</body>
</html