📄 chap02.htm
字号:
};
<font color=#0000ff>inline</font> Test::Test(ostream* osptr) {
<font color=#0000ff>this</font>->osptr = osptr;
assert(osptr);
nPass = nFail = 0;
}
<font color=#0000ff>inline</font> <font color=#0000ff>long</font> Test::getNumPassed() <font color=#0000ff>const</font> {
<font color=#0000ff>return</font> nPass;
}
<font color=#0000ff>inline</font> <font color=#0000ff>long</font> Test::getNumFailed() <font color=#0000ff>const</font> {
<font color=#0000ff>return</font> nFail;
}
<font color=#0000ff>inline</font> <font color=#0000ff>const</font> ostream* Test::getStream() <font color=#0000ff>const</font> {
<font color=#0000ff>return</font> osptr;
}
<font color=#0000ff>inline</font> <font color=#0000ff>void</font> Test::setStream(ostream* osptr) {
<font color=#0000ff>this</font>->osptr = osptr;
}
<font color=#0000ff>inline</font> <font color=#0000ff>void</font> Test::succeed_() {
++nPass;
}
<font color=#0000ff>inline</font> <font color=#0000ff>void</font> Test::reset() {
nPass = nFail = 0;
}
#endif <font color=#009900>// TEST_H ///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Explanation of code here</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here is the implmentation of
<B>Test</B>:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: TestSuite:Test.cpp {O}</font>
#include <font color=#004488>"Test.h"</font>
#include <iostream>
#include <typeinfo> <font color=#009900>// Visual C++ requires /GR""</font>
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;
<font color=#0000ff>void</font> Test::do_test(<font color=#0000ff>bool</font> cond,
<font color=#0000ff>const</font> std::string& lbl,
<font color=#0000ff>const</font> <font color=#0000ff>char</font>* fname,
<font color=#0000ff>long</font> lineno){
<font color=#0000ff>if</font> (!cond)
do_fail(lbl, fname, lineno);
<font color=#0000ff>else</font>
succeed_();
}
<font color=#0000ff>void</font> Test::do_fail(<font color=#0000ff>const</font> std::string& lbl,
<font color=#0000ff>const</font> <font color=#0000ff>char</font>* fname,
<font color=#0000ff>long</font> lineno){
++nFail;
<font color=#0000ff>if</font> (osptr){
*osptr << <font color=#0000ff>typeid</font>(*<font color=#0000ff>this</font>).name()
<< <font color=#004488>"failure: ("</font> << lbl << <font color=#004488>") , "</font>
<< fname
<< <font color=#004488>" (line "</font> << lineno << <font color=#004488>")\n"</font>;
}
}
<font color=#0000ff>long</font> Test::report() <font color=#0000ff>const</font> {
<font color=#0000ff>if</font> (osptr){
*osptr << <font color=#004488>"Test \"</font>" << <font color=#0000ff>typeid</font>(*<font color=#0000ff>this</font>).name()
<< <font color=#004488>"\"</font>:\n\tPassed: " << nPass
<< <font color=#004488>"\tFailed: "</font> << nFail
<< endl;
}
<font color=#0000ff>return</font> nFail;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">No rocket science here. <B>Test</B> just
keeps track of the number of successes and failures as well as the stream where
you want <B>Test::report( )</B> to print the results. <B>test_</B> and
<B>fail_</B> are macros so that they can include filename and line number
information available from the preprocessor.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here is the header file for
<B>Suite</B>:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: TestSuite:Suite.h</font>
#ifndef SUITE_H
#define SUITE_H
#include <font color=#004488>"..</font><font color=#004488>/TestSuite</font><font color=#004488>/Test.h"</font>
#include <vector>
#include <stdexcept>
<font color=#0000ff>using</font> std::vector;
<font color=#0000ff>using</font> std::logic_error;
<font color=#0000ff>class</font> TestSuiteError : <font color=#0000ff>public</font> logic_error {
<font color=#0000ff>public</font>:
TestSuiteError(<font color=#0000ff>const</font> string& s = <font color=#004488>""</font>)
: logic_error(s) {}
};
<font color=#0000ff>class</font> Suite {
<font color=#0000ff>public</font>:
Suite(<font color=#0000ff>const</font> string& name, ostream* osptr = &cout);
string getName() <font color=#0000ff>const</font>;
<font color=#0000ff>long</font> getNumPassed() <font color=#0000ff>const</font>;
<font color=#0000ff>long</font> getNumFailed() <font color=#0000ff>const</font>;
<font color=#0000ff>const</font> ostream* getStream() <font color=#0000ff>const</font>;
<font color=#0000ff>void</font> setStream(ostream* osptr);
<font color=#0000ff>void</font> addTest(Test* t) <font color=#0000ff>throw</font> (TestSuiteError);
<font color=#0000ff>void</font> addSuite(<font color=#0000ff>const</font> Suite&)
<font color=#0000ff>throw</font>(TestSuiteError);
<font color=#0000ff>void</font> run(); <font color=#009900>// Calls Test::run() repeatedly</font>
<font color=#0000ff>long</font> report() <font color=#0000ff>const</font>;
<font color=#0000ff>void</font> free(); <font color=#009900>// Deletes tests</font>
<font color=#0000ff>private</font>:
string name;
ostream* osptr;
vector<Test*> tests;
<font color=#0000ff>void</font> reset();
<font color=#009900>// Disallowed ops:</font>
Suite(<font color=#0000ff>const</font> Suite&);
Suite& <font color=#0000ff>operator</font>=(<font color=#0000ff>const</font> Suite&);
};
<font color=#0000ff>inline</font>
Suite::Suite(<font color=#0000ff>const</font> string& name, ostream* osptr)
: name(name) {
<font color=#0000ff>this</font>->osptr = osptr;
}
<font color=#0000ff>inline</font> string Suite::getName() <font color=#0000ff>const</font> {
<font color=#0000ff>return</font> name;
}
<font color=#0000ff>inline</font> <font color=#0000ff>const</font> ostream* Suite::getStream() <font color=#0000ff>const</font> {
<font color=#0000ff>return</font> osptr;
}
<font color=#0000ff>inline</font> <font color=#0000ff>void</font> Suite::setStream(ostream* osptr) {
<font color=#0000ff>this</font>->osptr = osptr;
}
#endif <font color=#009900>// SUITE_H ///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Explanation of code here</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here is the implementation of
<B>Suite</B>:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: TestSuite:Suite.cpp {O}</font>
#include <font color=#004488>"Suite.h"</font>
#include <iostream>
#include <cassert>
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;
<font color=#0000ff>void</font> Suite::addTest(Test* t)
<font color=#0000ff>throw</font>(TestSuiteError) {
<font color=#009900>// Make sure test has a stream:</font>
<font color=#0000ff>if</font> (t == 0)
<font color=#0000ff>throw</font> TestSuiteError(
<font color=#004488>"Null test in Suite::addTest"</font>);
<font color=#0000ff>else</font> <font color=#0000ff>if</font> (osptr != 0 && t->getStream() == 0)
t->setStream(osptr);
tests.push_back(t);
t->reset();
}
<font color=#0000ff>void</font> Suite::addSuite(<font color=#0000ff>const</font> Suite& s)
<font color=#0000ff>throw</font>(TestSuiteError) {
<font color=#0000ff>for</font> (size_t i = 0; i < s.tests.size(); ++i)
addTest(s.tests[i]);
}
<font color=#0000ff>void</font> Suite::free() {
<font color=#009900>// This is not a destructor because tests</font>
<font color=#009900>// don't have to be on the heap.</font>
<font color=#0000ff>for</font> (size_t i = 0; i < tests.size(); ++i) {
<font color=#0000ff>delete</font> tests[i];
tests[i] = 0;
}
}
<font color=#0000ff>void</font> Suite::run() {
reset();
<font color=#0000ff>for</font> (size_t i = 0; i < tests.size(); ++i) {
assert(tests[i]);
tests[i]->run();
}
}
<font color=#0000ff>long</font> Suite::report() <font color=#0000ff>const</font> {
<font color=#0000ff>if</font> (osptr) {
<font color=#0000ff>long</font> totFail = 0;
*osptr << <font color=#004488>"Suite \"</font>" << name
<< <font color=#004488>"\"</font>\n=======";
size_t i;
<font color=#0000ff>for</font> (i = 0; i < name.size(); ++i)
*osptr << '=';
*osptr << <font color=#004488>"=\n"</font>;
<font color=#0000ff>for</font> (i = 0; i < tests.size(); ++i) {
assert(tests[i]);
totFail += tests[i]->report();
}
*osptr << <font color=#004488>"======="</font>;
<font color=#0000ff>for</font> (i = 0; i < name.size(); ++i)
*osptr << '=';
*osptr << <font color=#004488>"=\n"</font>;
<font color=#0000ff>return</font> totFail;
}
<font color=#0000ff>else</font>
<font color=#0000ff>return</font> getNumFailed();
}
<font color=#0000ff>long</font> Suite::getNumPassed() <font color=#0000ff>const</font> {
<font color=#0000ff>long</font> totPass = 0;
<font color=#0000ff>for</font> (size_t i = 0; i < tests.size(); ++i) {
assert(tests[i]);
totPass += tests[i]->getNumPassed();
}
<font color=#0000ff>return</font> totPass;
}
<font color=#0000ff>long</font> Suite::getNumFailed() <font color=#0000ff>const</font> {
<font color=#0000ff>long</font> totFail = 0;
<font color=#0000ff>for</font> (size_t i = 0; i < tests.size(); ++i) {
assert(tests[i]);
totFail += tests[i]->getNumFailed();
}
<font color=#0000ff>return</font> totFail;
}
<font color=#0000ff>void</font> Suite::reset() {
<font color=#0000ff>for</font> (size_t i = 0; i < tests.size(); ++i) {
assert(tests[i]);
tests[i]->reset();
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Explanation of code here</FONT><BR></P></DIV>
<A NAME="Heading68"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H2 ALIGN="LEFT">
Exercises</H2></FONT>
<OL>
<LI><FONT FACE="Verdana"> </FONT><FONT FACE="Georgia">Exercise
1</FONT><LI><FONT FACE="Verdana"> </FONT><FONT FACE="Georgia">Exercise
2</FONT><LI><FONT FACE="Verdana"> </FONT><FONT FACE="Georgia">Exercise
3</FONT><LI><FONT FACE="Verdana"> </FONT><FONT FACE="Georgia">Etc.</FONT></OL>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"> </FONT><BR></P></DIV>
<HR><DIV ALIGN="LEFT"><P><A NAME="fn5" HREF="#fnB5">[5]</A><FONT FACE="Georgia" SIZE=2>
See Kent Beck's book, <I>eXtreme Programming Explained: Embrace Change</I>
(Addison-Wesley, 2000, ISBN 0-201-61641-6), or visit www.Xprogramming.com for
more information on XP. The XP theme from which this section derives its title
is DoTheSimplestThingThatCouldPossiblyWork.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><A NAME="fn6" HREF="#fnB6">[6]</A><FONT FACE="Georgia" SIZE=2>
The seminal work on this subject is Martin Fowler's <I>Refactoring: Improving
the Design of Existing Code</I> (Addison-Wesley, 2000, ISBN 0-201-48567-2). See
www.refactoring.com.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><A NAME="fn7" HREF="#fnB7">[7]</A><FONT FACE="Georgia" SIZE=2>
If you're using Microsoft Visual C++, you need to specify the compile option
/GR. If you don't, you'll get an access violation at run time.</FONT><BR></P></DIV>
<DIV ALIGN="CENTER">
<FONT FACE="Verdana, Tahoma, Arial, Helvetica, Sans" size = "-1">
[ <a href="Chap01.htm">Previous Chapter</a> ]
[ <a href="SimpCont.htm">Short TOC</a> ]
[ <a href="Contents.htm">Table of Contents</a> ]
[ <a href="DocIdx.htm">Index</a> ]
[ <a href="Chap03.htm">Next Chapter</a> ]
</FONT>
<BR>
Last Update:09/26/2001</P></DIV>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -