blob: 61ca56d072a1a48e20793aeea7ee52d35ff07d63 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- This is broken by doc revisioning.
-->
<link rel="shortcut icon" href="../../../img/favicon.ico">
<title>Write a Test Suite for a Package - Apache Mynewt</title>
<link href="../../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
<link rel="stylesheet" href="../../../css/highlight.css">
<link href="../../../css/base.css" rel="stylesheet">
<link href="../../../css/custom.css" rel="stylesheet">
<link href="../../../css/v2.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="Write a Test Suite for a Package">
<div class="container">
<div class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.12.0, Apache NimBLE 1.7.0 </a> released (April 4, 2024)
</div>
</div>
</div>
</div>
<nav id="navbar" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="150" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li
class=""
>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li
class="important"
>
<a href="/quick-start/">Quick Start</a>
</li>
<li
class=""
>
<a href="/about/">About</a>
</li>
<li
class=""
>
<a href="/talks/">Talks</a>
</li>
<li
class="active"
>
<a href="/documentation/">Documentation</a>
</li>
<li
class=""
>
<a href="/download/">Download</a>
</li>
<li
class=""
>
<a href="/community/">Community</a>
</li>
<li
class=""
>
<a href="/events/">Events</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-3 v2-sidebar sidebar-container"><div id="docSidebar" class="hidden-print" role="complementary">
<div class="top">
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search documentation" />
</div>
</form>
</div>
</div>
<ul class="toc-nav">
<li class="doc-version"><select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest">
Version: master
</option>
<option value="/v1_12_0/" >
Version: 1.12.0
</option>
<option value="/v1_11_0/" >
Version: 1.11.0
</option>
<option value="/v1_10_0/" >
Version: 1.10.0
</option>
<option value="/v1_9_0/" >
Version: 1.9.0
</option>
<option value="/v1_8_0/" >
Version: 1.8.0
</option>
<option value="/v1_7_0/" >
Version: 1.7.0
</option>
<option value="/v1_6_0/" >
Version: 1.6.0
</option>
<option value="/v1_5_0/" >
Version: 1.5.0
</option>
<option value="/v1_4_0/" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" selected="selected" >
Version: 0.9.0
</option>
</select></li>
<li ><a href="../../introduction/">Mynewt Documentation</a>
<ul>
<li ><a href="../../get_started/get_started/">Basic Setup</a>
</li>
<li >
<a href="../../get_started/vocabulary/">Concepts</a>
</li>
<li ><a href="../tutorials/">Tutorials</a>
<ul>
<li><a href="
../arduino_zero/
">Project Blinky</a>
</li>
<li ><a href="../repo/add_repos/">Work with repositories</a>
</li>
<li class="active">
<a href="./">Write a Test Suite for a Package</a>
</li>
<li >
<a href="../air_quality_sensor/">Air-quality Sensor project</a>
</li>
<li >
<a href="../event_queue/">Add task to manage multiple events</a>
</li>
<li >
<a href="../project-slinky/">Enable remote comms on sim device</a>
</li>
<li >
<a href="../project-target-slinky/">Enable remote comms on STM32 board</a>
</li>
<li >
<a href="../bletiny_project/">BLE app to check stats via console</a>
</li>
<li ><a href="../bleprph/bleprph-intro/">BLE peripheral project</a>
</li>
<li >
<a href="../ibeacon/">BLE iBeacon</a>
</li>
<li >
<a href="../blehci_project/">BLE HCI interface</a>
</li>
</ul>
</li>
<li ><a href="../../os_user_guide/">OS User Guide</a>
</li>
<li><a href="
../../../network/ble/ble_intro/
">BLE User Guide</a>
</li>
<li ><a href="../../../newt/newt_intro/">Newt Tool Guide</a>
</li>
<li ><a href="../../../newtmgr/overview/">Newt Manager Guide</a>
</li>
<li >
<a href="../../../known_issues/">Known Issues</a>
</li>
</ul>
</li>
<li><a href="
../../../faq/how_to_edit_docs/
">Appendix</a>
</li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<div class="doc-header">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="/documentation/">Docs</a></li>
<li>&raquo; <a href="os/tutorials/tutorials/">Tutorials</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li>&raquo; Write a Test Suite for a Package</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 0.9.0 is not the most recent version of the Apache Mynewt
documentation. Click <a href="/latest">here</a> to read the latest
version.
</p>
</div>
<h1 id="write-a-test-suite-for-a-package">Write a Test Suite for a Package</h1>
<p>This document presents a tutorial which guides the reader through writing
a test suite for a Mynewt package (new or existing).</p>
<h2 id="introduction">Introduction</h2>
<p>Writing a test suite involves using the <a href="../../modules/testutil/testutil/"><code>libs/testutil</code></a>
package within Mynewt core os. The <code>testutil</code> library provides the interface to
the <code>newt</code> command tool and also provides the compile time hooks to include
test suites into your code. Review the
[<code>testutil</code> introduction page ] (../modules/testutil/testutil.md)
to learn about how the library works.</p>
<h3 id="identify-your-package">Identify Your Package</h3>
<p>Identify the package for which you are writing a test suite. For this example
we will use <code>libs/json</code>. To create a new package, see <a href="">this Tutorial</a>.</p>
<h3 id="modify-pkgyml">Modify Pkg.yml</h3>
<p>Edit the package (<code>pkg.yml</code>) file for your package and add the test dependency
for the Mynewt core OS <code>libs/testutil</code>.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">pkg</span>.<span style="color: #000000">deps</span>.<span style="color: #000000">TEST:</span>
<span style="color: #000000">-</span> <span style="color: #000000">libs/testutil</span>
</code></pre></div>
<h3 id="create-your-test-suite-template">Create Your Test Suite Template</h3>
<p>Create a subdirectory <code>test</code> under your package main directory.
Create a file pair for your test code and header files within the <code>test</code>
directory created above. Below shows the <code>libs/json</code> directory within the
Mynewt core, including the test directory. In this example, we used the
convention <code>test_xxx.c/h</code> (in this case <code>test_json</code>).</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">├──</span> <span style="color: #000000">MSJSON_COPYING</span>
<span style="color: #000000">├──</span> <span style="color: #000000">include</span>
<span style="color: #000000"></span>   <span style="color: #000000">└──</span> <span style="color: #000000">json</span>
<span style="color: #000000"></span>   <span style="color: #000000">└──</span> <span style="color: #000000">json</span>.<span style="color: #000000">h</span>
<span style="color: #000000">├──</span> <span style="color: #000000">pkg</span>.<span style="color: #000000">yml</span>
<span style="color: #000000">└──</span> <span style="color: #000000">src</span>
<span style="color: #000000">├──</span> <span style="color: #000000">json_decode</span>.<span style="color: #000000">c</span>
<span style="color: #000000">├──</span> <span style="color: #000000">json_encode</span>.<span style="color: #000000">c</span>
<span style="color: #000000">└──</span> <span style="color: #000000">test</span>
<span style="color: #000000">├──</span> <span style="color: #000000">test_json</span>.<span style="color: #000000">c</span>
<span style="color: #000000">└──</span> <span style="color: #000000">test_json</span>.<span style="color: #000000">h</span>
</code></pre></div>
<h3 id="create-your-test-suite-code">Create Your Test Suite Code</h3>
<p>Edit the <code>test_json.c</code> file and add your test suite definition. NOTE that
the test suite code requires <code>#include &lt;testutil/testutil.h&gt;</code> to get the
Mynewt testutil definitions.</p>
<p>Your test suite <code>test_json.c</code> file contains at a minimum two functions:</p>
<ol>
<li>A test Suite which is empty for now, but will contain calls to your test
cases. </li>
<li>A main function which must be <code>#ifdef</code>'d using <code>MYNEWT_SELFTEST</code> to ensure
that is does not get compiled in when this test suite is run with
test suites from other packages </li>
</ol>
<p>Below shows the contents of the <code>test_json.c</code> file.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#include</span> <span style="color: #177500">&lt;testutil/testutil.h&gt;</span>
<span style="color: #000000">TEST_SUITE</span>(<span style="color: #000000">test_json_suite</span>) {
<span style="color: #177500">/* empty for now, add test cases later */</span>
}
<span style="color: #633820">#ifdef MYNEWT_SELFTEST</span>
<span style="color: #A90D91">int</span>
<span style="color: #000000">main</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
<span style="color: #000000">tu_config</span>.<span style="color: #000000">tc_print_results</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">1</span>;
<span style="color: #000000">tu_init</span>();
<span style="color: #000000">test_json_suite</span>();
<span style="color: #A90D91">return</span> <span style="color: #000000">tu_any_failed</span>;
}
<span style="color: #633820">#endif</span>
</code></pre></div>
<h3 id="try-it-out">Try It Out</h3>
<p>At this point, you have a working test suite with <strong>no</strong> tests.<br />
This will by default pass the test. Your output will look
something like this.</p>
<p>You can use the <code>newt test</code> command to run the unit tests for any package.<br />
Just include the package name. These unit tests run via the project
<code>unittest</code> which is a native project automatically included in the core
os package. Below shows some of the test output of this command.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">$</span> <span style="color: #000000">newt</span> <span style="color: #000000">test</span> <span style="color: #000000">libs/json</span>
<span style="color: #000000">Archiving</span> <span style="color: #000000">util</span>.<span style="color: #000000">a</span>
<span style="color: #000000">Linking</span> <span style="color: #000000">test_json</span>
<span style="color: #000000">Testing</span> <span style="color: #000000">package</span> <span style="color: #000000">libs/json</span>
<span style="color: #000000">Test</span> ...<span style="color: #000000">/bin/unittest/libs/json/test_json</span> <span style="color: #000000">ok!</span>
</code></pre></div>
<h3 id="create-a-test">Create a Test</h3>
<p>To create a test within your test suite, there are two things to do.</p>
<ol>
<li>Add the functions to your test suite</li>
<li>Implement the function using the <code>testutil</code> macros</li>
</ol>
<p>For this tutorial we will create two functions: one to test a simple json
encode and one to test the decode of this simple message to ensure its
coherent.</p>
<p>Follow These steps;</p>
<p>1. Create function prototypes in <code>test_json.h</code> for your test functions.
A macro in <code>testutil.h</code> hides the actual prototype, but as of this writing
the prototype is <code>int test_func(void);</code>. </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#ifndef TEST_JSON_H</span>
<span style="color: #633820">#define TEST_JSON_H</span>
<span style="color: #000000">TEST_CASE_DECL</span>(<span style="color: #000000">test_json_simple_encode</span>);
<span style="color: #000000">TEST_CASE_DECL</span>(<span style="color: #000000">test_json_simple_decode</span>);
<span style="color: #633820">#endif /* TEST_JSON_H </span>
</code></pre></div>
<p>2. create a new file <code>test_json_simple.c</code> to define these two functions. For
now you can stub these functions. Below shows the contents of this file.
The functions are defined using macros which reference back to the
<code>testutil</code> library so the test can be enumerated and recorded automatically.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#include</span> <span style="color: #177500">&quot;testutil/testutil.h&quot;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&quot;test_json.h&quot;</span>
<span style="color: #000000">TEST_CASE</span>(<span style="color: #000000">test_json_simple_encode</span>) {
}
<span style="color: #000000">TEST_CASE</span>(<span style="color: #000000">test_json_simple_decode</span>) {
}
<span style="color: #633820">#endif /* TEST_JSON_H </span>
</code></pre></div>
<p>3. Add the tests to your test suite in <code>test_json.c</code> as shown below.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">TEST_SUITE</span>(<span style="color: #000000">test_json_suite</span>) {
<span style="color: #000000">test_json_simple_encode</span>();
<span style="color: #000000">test_json_simple_decode</span>();
}
</code></pre></div>
<p>Your test suite should still pass as shown below</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">$newt</span> <span style="color: #000000">test</span> <span style="color: #000000">libs/json</span>
<span style="color: #000000">Testing</span> <span style="color: #000000">package</span> <span style="color: #000000">libs/json</span>
<span style="color: #000000">Test</span> ...<span style="color: #000000">/bin/unittest/libs/json/test_json</span> <span style="color: #000000">ok!</span>
</code></pre></div>
<h2 id="add-contents-to-your-tests">Add Contents to your Tests</h2>
<p>At this point, you can add contents to your test and verify that
the test suites pass. For now, lets just add a simple failure to show
what it would look like when running from Newt.</p>
<ul>
<li>Edit <code>test_json_simple.c</code> and add a <code>TEST_ASSERT</code> to a test function. The
test assert will fail if its argument is <code>false</code>.</li>
</ul>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">TEST_CASE</span>(<span style="color: #000000">test_json_simple_encode</span>) {
<span style="color: #000000">TEST_ASSERT</span>(<span style="color: #1C01CE">0</span>);
}
</code></pre></div>
<p>When running newt, you will see the test suite fails with something like
the message shown below.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">Testing</span> <span style="color: #000000">package</span> <span style="color: #000000">libs/json</span>
[<span style="color: #000000">FAIL</span>] <span style="color: #000000">test_json_suite/</span>(<span style="color: #000000">null</span>) <span style="color: #000000">|test_json_simple</span>.<span style="color: #000000">c:</span><span style="color: #1C01CE">24</span><span style="color: #000000">|</span> <span style="color: #000000">failed</span> <span style="color: #000000">assertion:</span> <span style="color: #1C01CE">0</span>
<span style="color: #000000">Error</span>: <span style="color: #000000">Test</span> <span style="color: #000000">crashed:</span> ..<span style="color: #000000">/bin/unittest/libs/json/test_json</span>
<span style="color: #000000">exit</span> <span style="color: #000000">status</span> <span style="color: #1C01CE">1</span>
</code></pre></div>
<h2 id="congratulations">Congratulations</h2>
<p>Now you can begin the work of adding your test cases and test.</p>
<h2 id="testing-on-your-target">Testing on your target</h2>
<div class="row">
<ul class="nav nav-pills" style="margin-bottom: 10px">
<li>
</li>
<li class="pull-right">
</li>
</ul>
</div>
<footer class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt (incubating) is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<a href="https://www.apache.org/">
<img src="/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
</a>
<p>
Copyright © 2015-2021 The Apache Software Foundation.<br>
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt
project logo are either registered trademarks or trademarks of the Apache
Software Foundation in the United States and other countries.
</small>
</p>
<a href="">
<img src="https://www.countit.com/images/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
<a href="https://www.apache.org/licenses/">
<button class="button-footer-asf">
License
</button>
</a>
<a href="https://www.apache.org/foundation/sponsorship.html">
<button class="button-footer-asf">
Sponsorship
</button>
</a>
<a href="https://www.apache.org/foundation/thanks.html">
<button class="button-footer-asf">
Thanks
</button>
</a>
<a href="https://www.apache.org/security/">
<button class="button-footer-asf">
Security
</button>
</a>
<a href="https://apache.org/events/current-event">
<button class="button-footer-asf">
ASF Events
</button>
</a>
</footer>
</div>
</div>
</div>
<script src="../../../js/jquery-1.10.2.min.js"></script>
<script src="../../../js/bootstrap-3.0.3.min.js"></script>
<script src="../../../js/highlight.pack.js"></script>
<script src="../../../js/base.js"></script>
<script src="../../../js/custom.js"></script>
<script src="search/main.js"></script>
</body>
</html>