?? cppunit_cookbook.html
字號:
suite.run( &result );</div></pre><h2><a class="anchor" name="test_runner">TestRunner</a></h2>How do you run your tests and collect their results?<p>Once you have a test suite, you'll want to run it. CppUnit provides tools to define the suite to be run and to display its results. You make your suite accessible to a <a class="el" href="group___executing_test.html">TestRunner </a> program with a static method <em>suite</em> that returns a test suite.<p>For example, to make a ComplexNumberTest suite available to a <a class="el" href="group___executing_test.html">TestRunner </a>, add the following code to ComplexNumberTest:<p><pre><div class="fragment"><span class="keyword">public</span>: <span class="keyword">static</span> CppUnit::Test *suite() { CppUnit::TestSuite *suiteOfTests = <span class="keyword">new</span> CppUnit::TestSuite( <span class="stringliteral">"ComplexNumberTest"</span> ); suiteOfTests->addTest( <span class="keyword">new</span> CppUnit::TestCaller<ComplexNumberTest>( <span class="stringliteral">"testEquality"</span>, &ComplexNumberTest::testEquality ) ); suiteOfTests->addTest( <span class="keyword">new</span> CppUnit::TestCaller<ComplexNumberTest>( <span class="stringliteral">"testAddition"</span>, &ComplexNumberTest::testAddition ) ); <span class="keywordflow">return</span> suiteOfTests; }</div></pre><p><a class="anchor" name="test_runner_code"></a> To use the text version, include the header files for the tests in Main.cpp:<p><pre><div class="fragment"><span class="preprocessor">#include <<a class="code" href="cppunit_2ui_2text_2_test_runner_8h.html">cppunit/ui/text/TestRunner.h</a>></span><span class="preprocessor">#include "ExampleTestCase.h"</span><span class="preprocessor">#include "ComplexNumberTest.h"</span></div></pre><p>And add a call to <a class="el" href="">addTest(CppUnit::Test *) </a> in the <code>main()</code> function:<p><pre><div class="fragment"><span class="keywordtype">int</span> main( <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv){ CppUnit::TextUi::TestRunner runner; runner.addTest( ExampleTestCase::suite() ); runner.addTest( ComplexNumberTest::suite() ); runner.run(); <span class="keywordflow">return</span> 0;}</div></pre><p>The <a class="el" href="group___executing_test.html">TestRunner </a> will run the tests. If all the tests pass, you'll get an informative message. If any fail, you'll get the following information:<p><ul><li>The name of the test case that failed</li><li>The name of the source file that contains the test</li><li>The line number where the failure occurred</li><li>All of the text inside the call to <a class="el" href="group___assertions.html#ga0">CPPUNIT_ASSERT()</a> which detected the failure</li></ul><p>CppUnit distinguishes between <em>failures</em> and <em>errors</em>. A failure is anticipated and checked for with assertions. Errors are unanticipated problems like division by zero and other exceptions thrown by the C++ runtime or your code.<h2><a class="anchor" name="helper_macros">Helper Macros</a></h2>As you might have noticed, implementing the fixture static <code>suite()</code> method is a repetitive and error prone task. A <a class="el" href="group___writing_test_fixture.html">Writing test fixture</a> set of macros have been created to automatically implements the static <code>suite()</code> method.<p>The following code is a rewrite of ComplexNumberTest using those macros:<p><pre><div class="fragment"><span class="preprocessor">#include <<a class="code" href="_helper_macros_8h.html">cppunit/extensions/HelperMacros.h</a>></span><span class="keyword">class </span>ComplexNumberTest : <span class="keyword">public</span> CppUnit::<a class="code" href="class_test_fixture.html">TestFixture</a> {</div></pre>First, we declare the suite, passing the class name to the macro: <pre><div class="fragment"><a class="code" href="group___writing_test_fixture.html#ga0">CPPUNIT_TEST_SUITE</a>( ComplexNumberTest );</div></pre>The suite created by the static <code>suite()</code> method is named after the class name. Then, we declare each test case of the fixture: <pre><div class="fragment"><a class="code" href="group___writing_test_fixture.html#ga5">CPPUNIT_TEST</a>( testEquality );<a class="code" href="group___writing_test_fixture.html#ga5">CPPUNIT_TEST</a>( testAddition );</div></pre>Finally, we end the suite declaration: <pre><div class="fragment"><a class="code" href="group___writing_test_fixture.html#ga2">CPPUNIT_TEST_SUITE_END</a>();</div></pre>At this point, a method with the following signature has been implemented: <pre><div class="fragment"><span class="keyword">static</span> CppUnit::TestSuite *suite();</div></pre>The rest of the fixture is left unchanged: <pre><div class="fragment"><span class="keyword">private</span>: Complex *m_10_1, *m_1_1, *m_11_2;<span class="keyword">public</span>: <span class="keywordtype">void</span> setUp() { m_10_1 = <span class="keyword">new</span> Complex( 10, 1 ); m_1_1 = <span class="keyword">new</span> Complex( 1, 1 ); m_11_2 = <span class="keyword">new</span> Complex( 11, 2 ); } <span class="keywordtype">void</span> tearDown() { <span class="keyword">delete</span> m_10_1; <span class="keyword">delete</span> m_1_1; <span class="keyword">delete</span> m_11_2; } <span class="keywordtype">void</span> testEquality() { <a class="code" href="group___assertions.html#ga0">CPPUNIT_ASSERT</a>( *m_10_1 == *m_10_1 ); <a class="code" href="group___assertions.html#ga0">CPPUNIT_ASSERT</a>( !(*m_10_1 == *m_11_2) ); } <span class="keywordtype">void</span> testAddition() { <a class="code" href="group___assertions.html#ga0">CPPUNIT_ASSERT</a>( *m_10_1 + *m_1_1 == *m_11_2 ); }};</div></pre><p>The name of the <a class="el" href="">TestCaller </a> added to the suite are a composition of the fixture name and the method name.<p>In the present case, the names would be: "ComplexNumberTest.testEquality" and "ComplexNumberTest.testAddition".<p>The <a class="el" href="group___writing_test_fixture.html">helper macros </a> help you write comon assertion. For example, to check that ComplexNumber throws a MathException when dividing a number by 0:<ul><li>add the test to the suite using CPPUNIT_TEST_EXCEPTION, specifying the expected exception type.</li><li>write the test case method</li></ul><p><pre><div class="fragment"><a class="code" href="group___writing_test_fixture.html#ga0">CPPUNIT_TEST_SUITE</a>( ComplexNumberTest );<span class="comment">// [...]</span><a class="code" href="group___writing_test_fixture.html#ga6">CPPUNIT_TEST_EXCEPTION</a>( testDivideByZeroThrows, MathException );<a class="code" href="group___writing_test_fixture.html#ga2">CPPUNIT_TEST_SUITE_END</a>();<span class="comment">// [...]</span> <span class="keywordtype">void</span> testDivideByZeroThrows() { <span class="comment">// The following line should throw a MathException.</span> *m_10_1 / ComplexNumber(0); }</div></pre><p>If the expected exception is not thrown, then a assertion failure is reported.<h2><a class="anchor" name="test_factory_registry">TestFactoryRegistry</a></h2>The <a class="el" href="class_test_factory_registry.html">TestFactoryRegistry</a> was created to solve two pitfalls:<ul><li>forgetting to add your fixture suite to the test runner (since it is in another file, it is easy to forget)</li><li>compilation bottleneck caused by the inclusion of all test case headers (see <a class="el" href="cppunit_cookbook.html#test_runner_code">previous example</a>)</li></ul><p>The <a class="el" href="class_test_factory_registry.html">TestFactoryRegistry</a> is a place where suites can be registered at initialization time.<p>To register the ComplexNumber suite, in the .cpp file, you add:<p><pre><div class="fragment"><span class="preprocessor">#include <<a class="code" href="_helper_macros_8h.html">cppunit/extensions/HelperMacros.h</a>></span><a class="code" href="group___creating_test_suite.html#ga0">CPPUNIT_TEST_SUITE_REGISTRATION</a>( ComplexNumberTest );</div></pre><p>Behind the scene, a static variable type of <a class="el" href="">AutoRegisterSuite </a> is declared. On construction, it will <a class="el" href="">register </a> a <a class="el" href="">TestSuiteFactory </a> into the <a class="el" href="">TestFactoryRegistry </a>. The <a class="el" href="">TestSuiteFactory </a> returns the <a class="el" href="">TestSuite </a> returned by ComplexNumber::suite().<p>To run the tests, using the text test runner, we don't need to include the fixture anymore:<p><pre><div class="fragment"><span class="preprocessor">#include <<a class="code" href="_test_factory_registry_8h.html">cppunit/extensions/TestFactoryRegistry.h</a>></span><span class="preprocessor">#include <<a class="code" href="cppunit_2ui_2text_2_test_runner_8h.html">cppunit/ui/text/TestRunner.h</a>></span><span class="keywordtype">int</span> main( <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv){ CppUnit::TextUi::TestRunner runner;</div></pre>First, we retreive the instance of the <a class="el" href="">TestFactoryRegistry </a>: <pre><div class="fragment"> CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();</div></pre>Then, we obtain and add a new <a class="el" href="">TestSuite </a> created by the <a class="el" href="">TestFactoryRegistry </a> that contains all the test suite registered using <a class="el" href="group___creating_test_suite.html#ga0">CPPUNIT_TEST_SUITE_REGISTRATION()</a>. <pre><div class="fragment"> runner.addTest( registry.makeTest() ); runner.run(); <span class="keywordflow">return</span> 0;}</div></pre><h2><a class="anchor" name="post_build_check">Post-build check</a></h2>Well, now that we have our unit tests running, how about integrating unit testing to our build process ?<p>To do that, the application must returns a value different than 0 to indicate that there was an error.<p><a class="el" href="">TestRunner::run() </a> returns a boolean indicating if the run was successful.<p>Updating our main programm, we obtains: <pre><div class="fragment"><span class="preprocessor">#include <<a class="code" href="_test_factory_registry_8h.html">cppunit/extensions/TestFactoryRegistry.h</a>></span><span class="preprocessor">#include <<a class="code" href="cppunit_2ui_2text_2_test_runner_8h.html">cppunit/ui/text/TestRunner.h</a>></span><span class="keywordtype">int</span> main( <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv){ CppUnit::TextUi::TestRunner runner; CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry(); runner.addTest( registry.makeTest() ); <span class="keywordtype">bool</span> wasSuccessful = runner.run( <span class="stringliteral">""</span>, <span class="keyword">false</span> ); <span class="keywordflow">return</span> wasSuccessful;}</div></pre><p>Now, you need to run your application after compilation.<p>With Visual C++, this is done in <em>Project Settings/Post-Build step</em>, by adding the following command: <code></code>. It is expanded to the application executable path. Look up the project <code>examples/cppunittest/CppUnitTestMain.dsp</code> which use that technic.<p>Original version by Michael Feathers. Doxygen conversion and update by Baptiste Lepilleur. <hr><table width="100%"> <tr> <td width="10%" align="left" valign="center"> <a href="http://sourceforge.net"> <img src="http://sourceforge.net/sflogo.php?group_id=11795" width="88" height="31" border="0" alt="SourceForge Logo"></a> </td> <td width="20%" align="left" valign="center"> hosts this site. </td> <td> </td> <td align="right" valign="center"> Send comments to:<br> <a href="mailto:cppunit-devel@lists.sourceforge.net">CppUnit Developers</a> </td> </tr></table></body> </html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -