|
|
(2 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
− | == Your First Test ==
| + | * [[Your First Test]] |
− | | + | * [[State Interface Test]] |
− | Let's create a [[Test Suite]] with a few [http://docs.tinyos.net/index.php/TUnit_Assertions assertions] in it to see what TUnit can do. This test won't really be testing anything, it's just going to make some assertions and exit.
| + | * [[Module Isolation Testing]] |
− | | + | * [[Characterization Testing with Statistics]] |
− | First, create a directory to store this test. This directory can go anywhere, but I'll put it in ''tinyos-2.x-contrib/tunit/tests/MyFirstTest'' for now:
| + | * [[Applying suite.properties Rules]] |
− | | |
− | tinyos-2.x-contrib
| |
− | |-- tunit
| |
− | | |-- tests
| |
− | | | |-- MyFirstTest
| |
− | | |
− | === Test Configuration File ===
| |
− | | |
− | Create a configuration file, called ''MyFirstTestC.nc'', and start writing it like you would any other TinyOS application. This will be the main entry point for your program.
| |
− | | |
− | '''tinyos-2.x-contrib/tunit/tests/MyFirstTest/MyFirstTestC.nc'''
| |
− |
| |
− | ''0|'' configuration MyFirstTestC {
| |
− | ''1|'' }
| |
− | ''2|''
| |
− | ''3|'' implementation {
| |
− | ''4|''
| |
− | ''5|'' components '''new TestCaseC() ''as'' BasicAssertionTestC''';
| |
− | ''6|''
| |
− | ''7|'' components MyFirstTestP;
| |
− | ''8|''
| |
− | ''9|'' MyFirstTestP.BasicAssertionTest -> BasicAssertionTestC;
| |
− | ''10|''
| |
− | ''11|'' }
| |
− | | |
− | On line 6, we create a new instance of '''TestCaseC'''. This is saying "Add a new test to our suite". Notice we immediately rename all instances of TestCaseC's as ''SomeReallyLongAndDescriptiveTestNameC''. In this case, we called it ''BasicAssertionTestC''.
| |
− | | |
− | '''TUnit Tip'''
| |
− | ''It's important to rename your TestCaseC instances with descriptive names. ''
| |
− | ''When that test fails, TUnit will magically tell you the name of the offending ''
| |
− | ''test so you can go look it up.''
| |
− | | |
− | If you're worried about what the [http://tinyos.cvs.sourceforge.net/*checkout*/tinyos/tinyos-2.x-contrib/tunit/tos/lib/tunit/TestCaseC.nc?content-type=text%2Fplain TestCaseC] component actually refers to, it comes from the TUnit embedded libraries. The library is found in ''tinyos-2.x-contrib/tunit/tos''. TUnit will take care of referencing this entire library for you at compile time so you don't have to think about it.
| |
− | | |
− | The signature of the TestCaseC component looks like this:
| |
− | | |
− | generic configuration TestCaseC() {
| |
− | provides {
| |
− | interface TestCase;
| |
− | interface TestControl as SetUpOneTime @atmostonce();
| |
− | interface TestControl as SetUp @atmostonce();
| |
− | interface TestControl as TearDown @atmostonce();
| |
− | interface TestControl as TearDownOneTime @atmostonce();
| |
− | }
| |
− | }
| |
− | | |
− | The interface we're interested in to run our basic assertion test is the TestCase interface. The TestCase interface is defined in [http://tinyos.cvs.sourceforge.net/*checkout*/tinyos/tinyos-2.x-contrib/tunit/tos/interfaces/TestCase.nc?content-type=text%2Fplain tinyos-2.x-contrib/tunit/tos/interfaces/TestCase.nc]:
| |
− | | |
− | interface TestCase {
| |
− |
| |
− | event void run();
| |
− |
| |
− | async command void done();
| |
− |
| |
− | }
| |
− | | |
− | Pretty simple interface, right? Your TestCase signals you to run(), and you '''must''' call back when your test is done(). With that in mind, we have a module to build...
| |
− | | |
− | === Test Module File ===
| |
− | | |
− | As the configuration file above dictated, we need to have a module called MyFirstTestP that ''uses'' the interface ''TestCase as BasicAssertionTest''. Let's create the MyFirstTestP module now:
| |
− | | |
− |
| |
− | '''tinyos-2.x-contrib/tunit/tests/MyFirstTest/MyFirstTestP.nc'''
| |
− |
| |
− | ''0|'' #include "TestCase.h"
| |
− | ''1|''
| |
− | ''2|'' configuration MyFirstTestP {
| |
− | ''3|'' uses {
| |
− | ''4|'' interface TestCase as BasicAssertionTest;
| |
− | ''5|'' }
| |
− | ''6|'' }
| |
− | ''7|''
| |
− | ''8|'' implementation {
| |
− | ''9|''
| |
− | ''10|'' event void BasicAssertionTest.run() {
| |
− | ''11|'' assertSuccess();
| |
− | ''12|'' call BasicAssertionTest.done();
| |
− | ''13|'' }
| |
− | ''14|''
| |
− | ''15|'' }
| |
− | | |
− | | |
− |
| |
− | | |
− | | |
− | | |
− | | |
− | == State Test ==
| |
− | | |
− | Let's create a test to verify the behavior of the State interface, provided in the tinyos-2.x baseline by the State component (tinyos-2.x/tos/system/StateC.nc). Here's a look at the State interface:
| |
− | | |
− | '''tinyos-2.x/tos/interfaces/State.nc'''
| |
− |
| |
− | interface State {
| |
− |
| |
− | /**
| |
− | * This will allow a state change so long as the current
| |
− | * state is S_IDLE.
| |
− | * @return SUCCESS if the state is change, FAIL if it isn't
| |
− | */
| |
− | async command error_t requestState(''uint8_t reqState'');
| |
− |
| |
− | /**
| |
− | * Force the state machine to go into a certain state,
| |
− | * regardless of the current state it's in.
| |
− | */
| |
− | async command void forceState(''uint8_t reqState'');
| |
− |
| |
− | /**
| |
− | * Set the current state back to S_IDLE
| |
− | */
| |
− | async command void toIdle();
| |
− |
| |
− | /**
| |
− | * @return TRUE if the state machine is in S_IDLE
| |
− | */
| |
− | async command bool isIdle();
| |
− |
| |
− | /**
| |
− | * @return TRUE if the state machine is in the given state
| |
− | */
| |
− | async command bool isState(''uint8_t myState'');
| |
− |
| |
− | /**
| |
− | * Get the current state
| |
− | */
| |
− | async command uint8_t getState();
| |
− |
| |
− | }
| |
− | | |
− | | |
− | === Setup ===
| |
− | | |
− | First, create a new directory to store your test in.
| |
− | | |
− | tinyos-2.x-contrib
| |
− | | |
− | | |
− | === Configuration ===
| |