cppunit-devel Mailing List for CppUnit - C++ port of JUnit (Page 61)
Brought to you by:
blep
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
(21) |
May
(96) |
Jun
(109) |
Jul
(42) |
Aug
(6) |
Sep
(106) |
Oct
(60) |
Nov
(20) |
Dec
(6) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(7) |
Feb
(11) |
Mar
(49) |
Apr
(124) |
May
(30) |
Jun
(37) |
Jul
(53) |
Aug
(33) |
Sep
(21) |
Oct
(22) |
Nov
(19) |
Dec
(15) |
2003 |
Jan
(34) |
Feb
(25) |
Mar
(11) |
Apr
(12) |
May
(16) |
Jun
(24) |
Jul
(23) |
Aug
(23) |
Sep
(42) |
Oct
(7) |
Nov
(32) |
Dec
(33) |
2004 |
Jan
(41) |
Feb
(41) |
Mar
(24) |
Apr
(25) |
May
(18) |
Jun
(13) |
Jul
(11) |
Aug
(15) |
Sep
(22) |
Oct
(10) |
Nov
(15) |
Dec
(9) |
2005 |
Jan
(4) |
Feb
(15) |
Mar
(11) |
Apr
(16) |
May
(29) |
Jun
(17) |
Jul
(27) |
Aug
(12) |
Sep
(9) |
Oct
(10) |
Nov
(5) |
Dec
(6) |
2006 |
Jan
(2) |
Feb
(6) |
Mar
(7) |
Apr
(2) |
May
(1) |
Jun
(5) |
Jul
(8) |
Aug
(6) |
Sep
(10) |
Oct
(11) |
Nov
(15) |
Dec
(2) |
2007 |
Jan
(12) |
Feb
(22) |
Mar
(10) |
Apr
(7) |
May
(1) |
Jun
(8) |
Jul
(4) |
Aug
(1) |
Sep
(2) |
Oct
(1) |
Nov
|
Dec
|
2008 |
Jan
|
Feb
(7) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(7) |
Dec
|
2010 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Baptiste L. <bl...@cl...> - 2001-05-16 19:05:33
|
> No, it breaks the interface published in CppUnitW 1.2. The change already > had been made before the release of 1.5.5. I don't know whether that > increases or decreases your horror. > I'm sorry if I haven't made clear that I made these changes in preparation > of the 1.5.5 release. Now that you've got CVS working, missing updates > should be less likely. Indeed, it seems that when I download the 1.5.5 release on sourceforge, the overwrite somehow failed and I was left with the old version you gave me for validation. > Whether you need RTTI depends on how/where you the need the name. For > example if you use your CU_TEST_SUITE HelperMacro, the Fixture name is > already available as the macro parameter. 1) macro are only there to make it easier to get started. I don't use CU_TEST_SUITE other than in old code (which used to be based on my old test framework and relied on macro to simulate reflection). 2) you can not extract template parameters that way. Trying to extract the name of the template parameter can be hell (at the top of my head, I'm thinging of traits) 3) you can't extract namespace that way > Portability is an issue: CppUnit is intented to be a cross platform library, > so the core feature set should be identical everywhere. Also the development > of CppUnit becomes messy if platform dependent code is scattered across core > classes. That's why I did not want RTTI stuff in TestSuite. Ok for the removal from TestSuite, but why haven't you move it to TestSuiteBuilder ? Why wasn't it discussed on this list ? > especially since the HelperMacros do not actually need the RTTI support. Wrong, see problem with template and namespace above. Are you invocating the use of macro ;-) ? > For an RTTI supporting TestSuiteBuilder, I suggest subclassing it to add the > RTTI based constructor. This would get messy, if somebody subclass TestSuiteBuilder to add some functionnality, it would make RTTI unusable. I don't see what's wrong by adding a constructor that is not available everywhere. Subclassing would be applying the refactoring "Introduce Local Extension" within the libary!!! Refer to the refactoring catalog, and you'll see there are many drawback with this (like the one I gave). > In any case the TestSuiteBuilder is a smaller issue because it's not a core > class, and it's only a header file: no RTTI dependent code would have been > compiled in the CppUnit library either way. > That leaves the TestFactoryRegistry class, which still has the USE_TYPEINFO > #ifdef. I like to solve the issue somehow there too, before 1.5.6. > Suggestions are welcome! This one could be removed since it is unused at the time, and I'm unsure of its use. > BTW, g++ isn't broken, the C++ standard is, because it does not specify > exactly what type_info::name() should return. The g++ people have simply > made a (for this purpose) not so useful choice of returning the mangled > name. Sorry, I misused "proper". What I intended was more akin to "useful". I don't see any use for a name that can change between run and is not human readable. > In fact, the next release of MSVC++ may return something completely > different from the current release as well. The underspecification of the > name() method, makes me suspicious of using it. Well, as long as they keep it human readable there will be no problem. I don't think this will be a problem. Even if "class" is not prepend to class and template name, it will just be left. I removed it to shorten the name. |
From: Steve M. R. <ste...@vi...> - 2001-05-15 23:09:54
|
On Wed, May 16, 2001 at 12:15:22AM +0200, Bastiaan Bakker wrote: > Hi Steve, > > Thanks for the input. Didn't know yet somebody made a debian package :-) Yep. And you can thank Christian Leutloff <leu...@de...> for it. (I thank Christian for alerting me to the existence of CppUnit.) If you wish to make a link to the Debian package on your web page, you can point to http://packages.debian.org/cppunit -Steve -- by Rocket to the Moon, by Airplane to the Rocket, by Taxi to the Airport, by Frontdoor to the Taxi, by throwing back the blanket and laying down the legs ... - They Might Be Giants |
From: Bastiaan B. <bas...@li...> - 2001-05-15 22:05:26
|
Hi Steve, Thanks for the input. Didn't know yet somebody made a debian package :-) The documentation is still rather out of sync indeed. So far Baptiste and I have focused on fixing broken stuff in 1.5.3 and remerging Micheal Feathers extensions. (1.5.3 was the last release before Eric and E.J. stopped maintaing CppUnit). We didn't have time to update the docs yet. I must confess I haven't even read them completely yet. Therefore your contributions to the documentation are very welcome! When/if you have more, please submit it. I'll try to merge asap. Thanks, Bastiaan "Steve M. Robbins" wrote: > Hi, > > CppUnit looks like a useful framework for testing, so I thought > I'd see if I can use it for my projects. I installed the debian > package and started with the "cookbook" page. > > When I started compiling the running example, I ran into several > difficulties. I tried to update the file to reflect the > current state of the library; patch is attached. > > Summary of changes: > * note the namespace > * type Complex needs a proper constructor > * SetUp() and friends need to be public > * note that calling run() member of a TestCaller is not useful > (this baffled me for a while --- I did "assert(false)", and > couldn't figure out why I got no diagnostics!) > > I ran out of steam when I got to the "TestRunner" section. None of > that worked for me, since CppUnit has no TestRunner! Now I see that > 1.5.5 has it, but only in MSWindows. I suppose the thing to do is > replace or supplement this section with a description of using > TextTestResults? > > Regards, > -Steve > > --- old/cppunit-1.5.4.orig/doc/cookbook.html Thu Oct 5 14:37:28 2000 > +++ cppunit-1.5.4/doc/cookbook.html Mon May 14 17:34:12 2001 > @@ -8,7 +8,12 @@ > <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> > </P> > <H1>CppUnit Cookbook</H1> > - <P>Here is a short cookbook to help you get started. </P> > + <P> > + Here is a short cookbook to help you get started. > + Note that all CppUnit types are defined in the CppUnit > + namespace. For brevity, the prefix <b>CppUnit::</b> > + is omitted in the following examples. > + </P> > <H2>Simple Test Case</H2> > <P> > You want to know whether your code is working. > @@ -90,9 +95,7 @@ > friend bool operator== (const Complex& a, const Complex& b); > double real, imaginary; > public: > - Complex () { > - real = imaginary = 0.0; > - } > + Complex ( double r, double i = 0 ) : real(r),imaginary(i) {} > }; > > bool operator== (const Complex& a, const Complex& b) > @@ -153,7 +156,7 @@ > <TT><PRE>	class ComplexNumberTest : public TestCase { > 	private: > Complex 	*m_10_1, *m_1_1; *m_11_2; > -	protected: > +	public: > 	void		setUp () { > 			 m_10_1 = new Complex (10, 1); > 			 m_1_1 = new Complex (1, 1); > @@ -170,21 +173,22 @@ > 			 assert (*m_10_1 + *m_1_1 == *m_11_2); > 	} > 	};</PRE> > -</TT><P>Create and run instances for each test case like this:</P> > -<TT><PRE>	test = new TestCaller<ComplexNumberTest>("testEquality", ComplexNumberTest::testEquality); > - test->run (); </PRE> > -</TT><P>The second argument to the test caller constructor is the address of a method on ComplexNumberTest. When the test caller is run, that specific method will be run.</P> > -<P>Once you have several tests, organize them into a suite.</P> > +</TT><P>One may create and run instances for each test case like this:</P> > +<TT><PRE>	TestCaller<ComplexNumberTest> test("testEquality", &ComplexNumberTest::testEquality); > + test.run (); </PRE> > +</TT><P>The second argument to the test caller constructor is the address of a method on ComplexNumberTest. When the test caller is run, that specific method will be run. This is not a useful thing to do, however, as no diagnostics will be > + displayed. One will normally use a TestRunner (see below) to display > + the results. > + </P> > + > + <P>Once you have several tests, organize them into a suite.</P> > <P> </P> > <H2>Suite</H2> > <P>How do you set up your tests so that you can run them all at once?<BR> > <BR> > -CppUnit provides a TestSuite class that runs any number of TestCases together. For example, to run a single test case, you execute:</P> > -<TT><PRE>	TestResult result; > -	TestCaller<ComplexNumberTest> test ("testAddition", ComplexNumberTest::testAddition); > -	Test.run (&result);</PRE> > -</TT><P> </P> > -<P>To create a suite of two or more tests, you do the following:</P> > +CppUnit provides a TestSuite class that runs any number of TestCases together. > + We saw, above, how to run a single test case. > +To create a suite of two or more tests, you do the following:</P> > <TT><PRE>	TestSuite suite; > 	TestResult result; > 	suite.addTest (new TestCaller<ComplexNumberTest>("testEquality", ComplexNumberTest::testEquality)); > @@ -193,6 +197,7 @@ > </PRE> > </TT><P>TestSuites don't only have to contain callers for TestCases. They can contain any object that implements the Test interface. For example, you can create a TestSuite in your code and I can create one in mine, and we can run them together by creating a TestSuite that contains both: </P> > <TT><PRE>	TestSuite suite; > +	TestResult result; > 	suite.addTest (ComplexNumberTest.suite ()); > 	suite.addTest (SurrealNumberTest.suite ()); > 	suite.run (&result);</PRE> > > -- > by Rocket to the Moon, > by Airplane to the Rocket, > by Taxi to the Airport, > by Frontdoor to the Taxi, > by throwing back the blanket and laying down the legs ... > - They Might Be Giants > > _______________________________________________ > Cppunit-devel mailing list > Cpp...@li... > http://lists.sourceforge.net/lists/listinfo/cppunit-devel |
From: Steve M. R. <ste...@vi...> - 2001-05-15 20:47:24
|
On Tue, May 15, 2001 at 10:48:52PM +0200, Bastiaan Bakker wrote: > "Steve M. Robbins" wrote: > > > Hi, > > > > I pulled down the CVS from sourceforge, and discovered that > > someone forgot to "cvs add src/cppunit/TestAssert.cpp"! > > > > Grrr, you're right. It has been added now. Thanks. > The funny thing is that it did end up in the 1.5.5 dist, because the > file was included in Makefile.am :-). Yeah, I know. That's how I got the CVS sources to compile! :-) It's a common mistake. I do it all the time. By the way, one way to reduce the probability of this is to use .cvsignore files everywhere. Then the output of "cvs -n update" is useful: it shows you all the (M)odified, (A)dded-but-not-commited and (?)unknown files in your checked-out sources. Regards, -Steve -- by Rocket to the Moon, by Airplane to the Rocket, by Taxi to the Airport, by Frontdoor to the Taxi, by throwing back the blanket and laying down the legs ... - They Might Be Giants |
From: Steve M. R. <ste...@vi...> - 2001-05-15 20:41:25
|
Hello, Using 1.5.5, I can see two flavours of assertions: assert( boolean ) and assertDoublesEqual( double, double ) [ also assertLongsEqual() ] The second form is potentially very useful, since it allows the diagnostic message to say "expected X, got Y". I'd like to extend this form of assertion to arbitrary types. To this end, I've added templatized assertEquals() and notEqualsMessage() member functions to class TestAssert, and a new assertion macro "assertEqual(x,y)". The assertion will work on any type that has operator=() and operator<<(). The patch below does work. Before I go further down this road and submit a full patch with doc changes, and the whole 9 yards, I thought I'd check to see whether you folks see a problem with this approach. Perhaps this approach has been previously considered and discarded? Comments? -Steve Index: include/cppunit/TestAssert.h =================================================================== RCS file: /cvsroot/cppunit/cppunit/include/cppunit/TestAssert.h,v retrieving revision 1.2 diff -u -b -B -r1.2 TestAssert.h --- include/cppunit/TestAssert.h 2001/05/06 16:19:31 1.2 +++ include/cppunit/TestAssert.h 2001/05/15 20:20:50 @@ -2,6 +2,7 @@ #define CPPUNIT_TESTASSERT_H #include <string> +#include <sstream> #include <cppunit/Exception.h> namespace CppUnit { @@ -19,22 +20,34 @@ long lineNumber = Exception::UNKNOWNLINENUMBER, std::string fileName = Exception::UNKNOWNFILENAME); - static void assertEquals (long expected, - long actual, + template <class T> + static void assertEquals ( + const T& expected, + const T& actual, long lineNumber = Exception::UNKNOWNLINENUMBER, - std::string fileName = Exception::UNKNOWNFILENAME); + std::string fileName = Exception::UNKNOWNFILENAME) + { + if (expected != actual) + assertImplementation (false, notEqualsMessage(expected, actual), lineNumber, fileName); + } + static void assertEquals (double expected, double actual, double delta, long lineNumber = Exception::UNKNOWNLINENUMBER, std::string fileName = Exception::UNKNOWNFILENAME); - static std::string notEqualsMessage (long expected, - long actual); + template <class T> + static std::string notEqualsMessage (const T& expected, + const T& actual) + { + ostringstream ost; + ost << "expected: " << expected + << " but was: " << actual; + return ost.str(); + } - static std::string notEqualsMessage (double expected, - double actual); }; @@ -69,6 +82,15 @@ /// Macro for primitive value comparisons #define assertLongsEqual(expected,actual)\ +(CppUnit::TestAssert::assertEquals ((expected),\ + (actual),__LINE__,__FILE__)) + +/// Generalized macro for primitive value comparisons +/** Any type that implements operator= and operator<< + * can be compared. A diagnostic is printed if the + * actual and expected values disagree. + */ +#define assertEqual(expected,actual)\ (CppUnit::TestAssert::assertEquals ((expected),\ (actual),__LINE__,__FILE__)) -- by Rocket to the Moon, by Airplane to the Rocket, by Taxi to the Airport, by Frontdoor to the Taxi, by throwing back the blanket and laying down the legs ... - They Might Be Giants |
From: Bastiaan B. <bas...@li...> - 2001-05-15 20:38:56
|
"Steve M. Robbins" wrote: > Hi, > > I pulled down the CVS from sourceforge, and discovered that > someone forgot to "cvs add src/cppunit/TestAssert.cpp"! > Grrr, you're right. It has been added now. The funny thing is that it did end up in the 1.5.5 dist, because the file was included in Makefile.am :-). Thanks, Bastiaan > > Regards, > -S > > -- > by Rocket to the Moon, > by Airplane to the Rocket, > by Taxi to the Airport, > by Frontdoor to the Taxi, > by throwing back the blanket and laying down the legs ... > - They Might Be Giants > > _______________________________________________ > Cppunit-devel mailing list > Cpp...@li... > http://lists.sourceforge.net/lists/listinfo/cppunit-devel |
From: Steve M. R. <ste...@vi...> - 2001-05-15 18:58:46
|
Hi, I pulled down the CVS from sourceforge, and discovered that someone forgot to "cvs add src/cppunit/TestAssert.cpp"! Regards, -S -- by Rocket to the Moon, by Airplane to the Rocket, by Taxi to the Airport, by Frontdoor to the Taxi, by throwing back the blanket and laying down the legs ... - They Might Be Giants |
From: Steve M. R. <ste...@vi...> - 2001-05-14 23:22:13
|
Hi, CppUnit looks like a useful framework for testing, so I thought I'd see if I can use it for my projects. I installed the debian package and started with the "cookbook" page. When I started compiling the running example, I ran into several difficulties. I tried to update the file to reflect the current state of the library; patch is attached. Summary of changes: * note the namespace * type Complex needs a proper constructor * SetUp() and friends need to be public * note that calling run() member of a TestCaller is not useful (this baffled me for a while --- I did "assert(false)", and couldn't figure out why I got no diagnostics!) I ran out of steam when I got to the "TestRunner" section. None of that worked for me, since CppUnit has no TestRunner! Now I see that 1.5.5 has it, but only in MSWindows. I suppose the thing to do is replace or supplement this section with a description of using TextTestResults? Regards, -Steve --- old/cppunit-1.5.4.orig/doc/cookbook.html Thu Oct 5 14:37:28 2000 +++ cppunit-1.5.4/doc/cookbook.html Mon May 14 17:34:12 2001 @@ -8,7 +8,12 @@ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> </P> <H1>CppUnit Cookbook</H1> - <P>Here is a short cookbook to help you get started. </P> + <P> + Here is a short cookbook to help you get started. + Note that all CppUnit types are defined in the CppUnit + namespace. For brevity, the prefix <b>CppUnit::</b> + is omitted in the following examples. + </P> <H2>Simple Test Case</H2> <P> You want to know whether your code is working. @@ -90,9 +95,7 @@ friend bool operator== (const Complex& a, const Complex& b); double real, imaginary; public: - Complex () { - real = imaginary = 0.0; - } + Complex ( double r, double i = 0 ) : real(r),imaginary(i) {} }; bool operator== (const Complex& a, const Complex& b) @@ -153,7 +156,7 @@ <TT><PRE>	class ComplexNumberTest : public TestCase { 	private: Complex 	*m_10_1, *m_1_1; *m_11_2; -	protected: +	public: 	void		setUp () { 			 m_10_1 = new Complex (10, 1); 			 m_1_1 = new Complex (1, 1); @@ -170,21 +173,22 @@ 			 assert (*m_10_1 + *m_1_1 == *m_11_2); 	} 	};</PRE> -</TT><P>Create and run instances for each test case like this:</P> -<TT><PRE>	test = new TestCaller<ComplexNumberTest>("testEquality", ComplexNumberTest::testEquality); - test->run (); </PRE> -</TT><P>The second argument to the test caller constructor is the address of a method on ComplexNumberTest. When the test caller is run, that specific method will be run.</P> -<P>Once you have several tests, organize them into a suite.</P> +</TT><P>One may create and run instances for each test case like this:</P> +<TT><PRE>	TestCaller<ComplexNumberTest> test("testEquality", &ComplexNumberTest::testEquality); + test.run (); </PRE> +</TT><P>The second argument to the test caller constructor is the address of a method on ComplexNumberTest. When the test caller is run, that specific method will be run. This is not a useful thing to do, however, as no diagnostics will be + displayed. One will normally use a TestRunner (see below) to display + the results. + </P> + + <P>Once you have several tests, organize them into a suite.</P> <P> </P> <H2>Suite</H2> <P>How do you set up your tests so that you can run them all at once?<BR> <BR> -CppUnit provides a TestSuite class that runs any number of TestCases together. For example, to run a single test case, you execute:</P> -<TT><PRE>	TestResult result; -	TestCaller<ComplexNumberTest> test ("testAddition", ComplexNumberTest::testAddition); -	Test.run (&result);</PRE> -</TT><P> </P> -<P>To create a suite of two or more tests, you do the following:</P> +CppUnit provides a TestSuite class that runs any number of TestCases together. + We saw, above, how to run a single test case. +To create a suite of two or more tests, you do the following:</P> <TT><PRE>	TestSuite suite; 	TestResult result; 	suite.addTest (new TestCaller<ComplexNumberTest>("testEquality", ComplexNumberTest::testEquality)); @@ -193,6 +197,7 @@ </PRE> </TT><P>TestSuites don't only have to contain callers for TestCases. They can contain any object that implements the Test interface. For example, you can create a TestSuite in your code and I can create one in mine, and we can run them together by creating a TestSuite that contains both: </P> <TT><PRE>	TestSuite suite; +	TestResult result; 	suite.addTest (ComplexNumberTest.suite ()); 	suite.addTest (SurrealNumberTest.suite ()); 	suite.run (&result);</PRE> -- by Rocket to the Moon, by Airplane to the Rocket, by Taxi to the Airport, by Frontdoor to the Taxi, by throwing back the blanket and laying down the legs ... - They Might Be Giants |
From: Bastiaan B. <bas...@li...> - 2001-05-14 08:32:57
|
-----Oorspronkelijk bericht----- Van: Baptiste Lepilleur [mailto:bl...@cl...] Verzonden: Sunday, May 13, 2001 11:31 AM Aan: Cpp Unit Develpment Mailing List Onderwerp: [Cppunit-devel] TestSuiteBuilder & type info... I finally managed to setup WinCvs and ssh. I checked out cppunit, Congrats. recompile, and link against TTR... Horror, all RTTI have been removed from TestSuiteBuilder and TestSuite !!! Can somebody explains me why it has been done ? That would be me :-) (You can check that with ViewCVS at SF by browsing the logs). - It breaks the interface published in release 1.5.5 No, it breaks the interface published in CppUnitW 1.2. The change already had been made before the release of 1.5.5. I don't know whether that increases or decreases your horror. I'm sorry if I haven't made clear that I made these changes in preparation of the 1.5.5 release. Now that you've got CVS working, missing updates should be less likely. - RTTI makes it easy to extract the name from template test case, which is very difficult to do otherwise. Whether you need RTTI depends on how/where you the need the name. For example if you use your CU_TEST_SUITE HelperMacro, the Fixture name is already available as the macro parameter. - Portability is not an issue (though it should be document since you would expect g++ to have a proper support for RTTI). Lots of people develops for one platform only. Portability is an issue: CppUnit is intented to be a cross platform library, so the core feature set should be identical everywhere. Also the development of CppUnit becomes messy if platform dependent code is scattered across core classes. That's why I did not want RTTI stuff in TestSuite. The #ifdefs I put in where a non-elegant temporary solution, which did not solve the development problem. Since the actual RTTI code inside TestSuite is trivial, it may as be done byt the caller, outside the TestSuite class. Likewise the TestSuiteBuilder seems useful too if you don't have RTTI, so I removed it there too; especially since the HelperMacros do not actually need the RTTI support. For an RTTI supporting TestSuiteBuilder, I suggest subclassing it to add the RTTI based constructor. In any case the TestSuiteBuilder is a smaller issue because it's not a core class, and it's only a header file: no RTTI dependent code would have been compiled in the CppUnit library either way. That leaves the TestFactoryRegistry class, which still has the USE_TYPEINFO #ifdef. I like to solve the issue somehow there too, before 1.5.6. Suggestions are welcome! BTW, g++ isn't broken, the C++ standard is, because it does not specify exactly what type_info::name() should return. The g++ people have simply made a (for this purpose) not so useful choice of returning the mangled name. In fact, the next release of MSVC++ may return something completely different from the current release as well. The underspecification of the name() method, makes me suspicious of using it. Bastiaan Baptiste. --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Author of The Text Reformatter, a tool for fanfiction readers and writers. Language: English, French (Well, I'm French). _______________________________________________ Cppunit-devel mailing list Cpp...@li... http://lists.sourceforge.net/lists/listinfo/cppunit-devel |
From: Baptiste L. <bl...@cl...> - 2001-05-13 17:45:23
|
I finally managed to setup WinCvs and ssh. I checked out cppunit, recompile, and link against TTR... Horror, all RTTI have been removed from TestSuiteBuilder and TestSuite !!! Can somebody explains me why it has been done ? - It breaks the interface published in release 1.5.5 - RTTI makes it easy to extract the name from template test case, which is very difficult to do otherwise. - Portability is not an issue (though it should be document since you would expect g++ to have a proper support for RTTI). Lots of people develops for one platform only. Baptiste. --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Author of The Text Reformatter, a tool for fanfiction readers and writers. Language: English, French (Well, I'm French). |
From: Baptiste L. <bl...@cl...> - 2001-05-12 15:45:43
|
> FWIW, I agree with the following solution. FWIW <= what does it stand for ? > > >> To do cppunit: > >> - remove TestRegistry.cpp/.h > >> - implement a TextTestRunner > >> > >> To do for the sample: > >> - add a suite() method for each test case, which returns a > >> dynamically allocated suite, > >> - add the suite of each test case to the TextTestRunner, > >> - run the TextTestRunner. > >> => this would make it similar to run suite using a graphic or text > >> TestRunner, and would show how test case should be factored. > > As a cppunit newbie, this would make a lot of sense to me. There are so > many options that it's a little overwhelming. I also don't want to > restructure all my test code when the next release comes out. The proposed > solution would allow both automated text based tests and interactive tests, > from essentially the same code. This would be best accomplished if there > were slight changes to make TestRunner have a pure virtual run() method and > then have a TextTestRunner and a GuiTestRunner. The GuiTestRunners could > changed slightly for different platforms. Having a comon base class is not really required, only having the same ownership and usage policy is required. Usualy the test runner you will use depend on the available test runner on your environnement (for a console application, you must use a text based test runner for example). The thing that matter is that you don't have to rewrite you test or suite because you need to change the test runner you are using. > > I realize I'm late to the discussion and perhaps I don't understand all the > issues. I see that there has so far been no effort to create a GUI > TestRunner for other platforms. (although I am extremely grateful that it > has been done for Windows, where I'm currently developing!!) Seems like at > least the base TestRunner class would end up in cppunit, with only the > platform specific parts in directories under src and in parallel with > cppunit and msvc6. The discussion was mainly about the use of the new TestCaller constructor which take a reference to a TestCase and the issue with the test case ownership (See explanation in previous mail). I realized that Baastian did not have this problem because in the sample, tests and suites were instantiated as automatic variable. > > Thanks for getting the Win32 support out! I was doing many of the same fixes > to get in synch with the SoureForge version, but at least compile with MSVC. > Getting it all merged in was a real bonus! Saved me a lot of time. > > > I'm not sure how much time I can spare, but I am hoping that I can > contribute to some degree, including documentation. As usual, the docs are You're welcome ! > secondary to getting working code (and getting the design bugs worked out). > I find myself jumping around a lot of different documents and geting > confused about all the new features that aren't really documented. Luckily I Could you draw a list of the "missing" documentations, and the other part you find difficult to get started. This would make our "To do" list for documenation. For the new functionnalities, you can found something akin to a "getting started" at http://gaiacrtn.free.fr/cppunit/index.html but is it somewhat short. Another problem is that g++ does not provides usable typeinfo name which make life much easier (the suite is automatically named when using the TestSuiteBuilder). So with g++ you would need to specify the suite name to TestSuiteBuilder while on Windows you can get away using typeinfo... Humm, thinking of it, introducing the generic way, then the typeinfo way would work... Also some documenation about writing test might be interesting (whitebox testing against blackbox testing), self-shunt test pattern... > can still use the basic classes and get useful work done. I've done a lot of > documentation in the past, including full databook writing and editing; and > actually don't mind it at all. (however I still have work deadlines to meet > first...) It's not clear to me however if it is worth updating the cookbook > until the next round of stuff with TestRunner is straightened up... The TextTestRunner need to be cleaned up. It prints and assumes way to much things. > > Hope this is not too much in one message, but I also suggest the suite() > method be added to either Test or TestCase. I have been seeing a lot of > discussion about this method, including in the CppUnit Cookbook document, This can't be done since suite() is a static method ! > and it's confusing for it not to be a virtual method in one of the base > classes. It would also provide a good place to add some documentation for > its use. Baptiste. --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Author of The Text Reformatter, a tool for fanfiction readers and writers. Language: English, French (Well, I'm French). |
From: Baptiste L. <bl...@cl...> - 2001-05-12 15:45:41
|
> Just one thing I realized today about the solution below: dynamically > allocating the suite in the test case could be dangerous; at least given the > current environment on Win32. The issue is that there are multiple DLLs and > the application, all of which could be using different versions of the > run-time library. It may not be safe to call delete on memory allocated in a > different module. While it is in the same process space, the actual code in > the RTLs could be different, depending on how each module was linked. (ie. > static RTL vs DLL RTL vs multi or single threaded vs different versions of > compiler). I recently read about this all too common problem in Jeffrey > Richter's "Programming Applications for Microsoft Windows - Fourth Edition" > Given his expertise level, I would have to bet it's a real problem that > should be avoided. The bottom line is that memory allocated in a given > module should be freed in that same module. This is a real problem when you release DLL which you have no control over, but that is not the case here. Unit test are of use for us, developers, not for the clients. You only have to know what you are doing when splitting your code into DLL (and its nigh impossible to successful compile against a library that is using different RTL setting, you always ends up with some conflicts at link time). Also, unit testing is of use for development, but should not be in the final published interface of the DLL. If you want to mix up RTL setting in different DLL, you will run into trouble and you would need to use the usual encapsulation technics to solve them. The same technic can be applied to the DLL published suite. You could use a encapsulating suite that delegate instantiation and destruction of the "published" suite to the DLL. I think that this problem should not be solved by cppunit, as solution depends much on the use, platform... On the other hand it may be interesting to document it, and some of the possible solution. > > The basic problem is memory leaks, which is not a _huge_ problem for these > applications, since after the test application closes, the OS will clean up > any memory allocated in that process. ( at least NT/Win2K will do that Memory leaks are very important, and you should always minimize them. If you don't destroy test, you will make memory leaks detection tools useless. You application may not be closed for weeks or months (your standard server, for example). Unit test have this marvelous property that they use the code in many way. Chasing the memory leak (when they occurs in some weird context) is usually easy that way. > properly) On the other hand, creating code that doesn't cause memory leaks > is still much preferrable. This may be an issue in other places in the code > too, although the main problem area will only be the TestRunner DLL freeing > memory allocated elsewhere. > > On the other hand, if the base TestRunner class does the memory freeing > (deletes the suite), and it ends up in the cppunit (statically linked) > library, then we're okay. Perhaps this will work out more easily than I > first thought... This wouldn't works. Some suite/test given to the test runner could be instantiated by the host application. A suite can be instantiated by test runner (it automatically creates a "all tests" suite if more than one test was registered). See above for the solution I propose. |
From: Townsend, G. <gto...@sh...> - 2001-05-11 21:06:12
|
Just one thing I realized today about the solution below: dynamically allocating the suite in the test case could be dangerous; at least given the current environment on Win32. The issue is that there are multiple DLLs and the application, all of which could be using different versions of the run-time library. It may not be safe to call delete on memory allocated in a different module. While it is in the same process space, the actual code in the RTLs could be different, depending on how each module was linked. (ie. static RTL vs DLL RTL vs multi or single threaded vs different versions of compiler). I recently read about this all too common problem in Jeffrey Richter's "Programming Applications for Microsoft Windows - Fourth Edition" Given his expertise level, I would have to bet it's a real problem that should be avoided. The bottom line is that memory allocated in a given module should be freed in that same module. The basic problem is memory leaks, which is not a _huge_ problem for these applications, since after the test application closes, the OS will clean up any memory allocated in that process. ( at least NT/Win2K will do that properly) On the other hand, creating code that doesn't cause memory leaks is still much preferrable. This may be an issue in other places in the code too, although the main problem area will only be the TestRunner DLL freeing memory allocated elsewhere. On the other hand, if the base TestRunner class does the memory freeing (deletes the suite), and it ends up in the cppunit (statically linked) library, then we're okay. Perhaps this will work out more easily than I first thought... Guy -----Original Message----- From: Townsend, Guy [mailto:gto...@sh...] Sent: Thursday, May 10, 2001 6:24 PM To: 'cpp...@li...' Subject: RE: [Cppunit-devel] hierarchy sample bug... FWIW, I agree with the following solution. >> To do cppunit: >> - remove TestRegistry.cpp/.h >> - implement a TextTestRunner >> >> To do for the sample: >> - add a suite() method for each test case, which returns a >> dynamically allocated suite, >> - add the suite of each test case to the TextTestRunner, >> - run the TextTestRunner. >> => this would make it similar to run suite using a graphic or text >> TestRunner, and would show how test case should be factored. As a cppunit newbie, this would make a lot of sense to me. There are so many options that it's a little overwhelming. I also don't want to restructure all my test code when the next release comes out. The proposed solution would allow both automated text based tests and interactive tests, from essentially the same code. This would be best accomplished if there were slight changes to make TestRunner have a pure virtual run() method and then have a TextTestRunner and a GuiTestRunner. The GuiTestRunners could changed slightly for different platforms. I realize I'm late to the discussion and perhaps I don't understand all the issues. I see that there has so far been no effort to create a GUI TestRunner for other platforms. (although I am extremely grateful that it has been done for Windows, where I'm currently developing!!) Seems like at least the base TestRunner class would end up in cppunit, with only the platform specific parts in directories under src and in parallel with cppunit and msvc6. > OK, thanks for the explanation. Unfortunately until the weekend I don't have the time to sort it out: got an exam this friday. So this would stall the release of 1.5.5 until at least somewhere next week. If otherwise the current tree is OK (and it is, isn't it?), I wouldn't want to deprive people from Win32 support until then, and release 1.5.5 as an ad interim version. May give us some useful feedback from others too. If there're are no nay-sayers, I'll put it on source forge tomorrow. Thanks for getting the Win32 support out! I was doing many of the same fixes to get in synch with the SoureForge version, but at least compile with MSVC. Getting it all merged in was a real bonus! Saved me a lot of time. I'm not sure how much time I can spare, but I am hoping that I can contribute to some degree, including documentation. As usual, the docs are secondary to getting working code (and getting the design bugs worked out). I find myself jumping around a lot of different documents and geting confused about all the new features that aren't really documented. Luckily I can still use the basic classes and get useful work done. I've done a lot of documentation in the past, including full databook writing and editing; and actually don't mind it at all. (however I still have work deadlines to meet first...) It's not clear to me however if it is worth updating the cookbook until the next round of stuff with TestRunner is straightened up... Hope this is not too much in one message, but I also suggest the suite() method be added to either Test or TestCase. I have been seeing a lot of discussion about this method, including in the CppUnit Cookbook document, and it's confusing for it not to be a virtual method in one of the base classes. It would also provide a good place to add some documentation for its use. Guy _______________________________________________ Cppunit-devel mailing list Cpp...@li... http://lists.sourceforge.net/lists/listinfo/cppunit-devel |
From: Townsend, G. <gto...@sh...> - 2001-05-11 01:27:44
|
FWIW, I agree with the following solution. >> To do cppunit: >> - remove TestRegistry.cpp/.h >> - implement a TextTestRunner >> >> To do for the sample: >> - add a suite() method for each test case, which returns a >> dynamically allocated suite, >> - add the suite of each test case to the TextTestRunner, >> - run the TextTestRunner. >> => this would make it similar to run suite using a graphic or text >> TestRunner, and would show how test case should be factored. As a cppunit newbie, this would make a lot of sense to me. There are so many options that it's a little overwhelming. I also don't want to restructure all my test code when the next release comes out. The proposed solution would allow both automated text based tests and interactive tests, from essentially the same code. This would be best accomplished if there were slight changes to make TestRunner have a pure virtual run() method and then have a TextTestRunner and a GuiTestRunner. The GuiTestRunners could changed slightly for different platforms. I realize I'm late to the discussion and perhaps I don't understand all the issues. I see that there has so far been no effort to create a GUI TestRunner for other platforms. (although I am extremely grateful that it has been done for Windows, where I'm currently developing!!) Seems like at least the base TestRunner class would end up in cppunit, with only the platform specific parts in directories under src and in parallel with cppunit and msvc6. > OK, thanks for the explanation. Unfortunately until the weekend I don't have the time to sort it out: got an exam this friday. So this would stall the release of 1.5.5 until at least somewhere next week. If otherwise the current tree is OK (and it is, isn't it?), I wouldn't want to deprive people from Win32 support until then, and release 1.5.5 as an ad interim version. May give us some useful feedback from others too. If there're are no nay-sayers, I'll put it on source forge tomorrow. Thanks for getting the Win32 support out! I was doing many of the same fixes to get in synch with the SoureForge version, but at least compile with MSVC. Getting it all merged in was a real bonus! Saved me a lot of time. I'm not sure how much time I can spare, but I am hoping that I can contribute to some degree, including documentation. As usual, the docs are secondary to getting working code (and getting the design bugs worked out). I find myself jumping around a lot of different documents and geting confused about all the new features that aren't really documented. Luckily I can still use the basic classes and get useful work done. I've done a lot of documentation in the past, including full databook writing and editing; and actually don't mind it at all. (however I still have work deadlines to meet first...) It's not clear to me however if it is worth updating the cookbook until the next round of stuff with TestRunner is straightened up... Hope this is not too much in one message, but I also suggest the suite() method be added to either Test or TestCase. I have been seeing a lot of discussion about this method, including in the CppUnit Cookbook document, and it's confusing for it not to be a virtual method in one of the base classes. It would also provide a good place to add some documentation for its use. Guy |
From: Baptiste L. <bl...@cl...> - 2001-05-09 19:39:07
|
> OK, thanks for the explanation. Unfortunately until the weekend I don't have > the time to sort it out: got an exam this friday. So this would stall the > release of 1.5.5 until at least somewhere next week. > If otherwise the current tree is OK (and it is, isn't it?), I wouldn't want to > deprive people from Win32 support until then, and release 1.5.5 as an ad > interim version. May give us some useful feedback from others too. If there're > are no nay-sayers, I'll put it on source forge tomorrow. Go ahead with release 1.5.5, I don't see any reason not to make a new release. Baptiste. --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Author of The Text Reformatter, a tool for fanfiction readers and writers. Language: English, French (Well, I'm French). |
From: Bastiaan B. <bas...@li...> - 2001-05-08 22:33:40
|
Baptiste Lepilleur wrote: > > > > Humm, just one thing that popup in my mind: who owns the fixture > given > > > > to the test caller ? That's may be the reason why it is done that > way... > > > > > > > > I guess it had something to do with the automatic test registration > thing, > > > > which has been removed anyway. > > > No, it was done that way in Michael Feather version. And if I > understood > > > thing well, it's also done that way in junit. > > > > > > > Not! > > Please take a look at the JUnit code. JUnit doesn't have a TestCaller: it > doesn't need one because it can use Java Reflection to lookup test methods > and execute them. > > Also, the only container for Tests is the TestSuite class, no Registries > or other things. > > It's simple and I like it. > They don't have a test caller class because the test caller is the test > case itself. Here is a piece of code extracted from > TestSuite.addTestMethod() (called for each public test method on > construction): > > if (isPublicTestMethod(m)) { > names.addElement(name); > > Object[] args= new Object[]{name}; > try { > addTest((Test)constructor.newInstance(args)); // <=== a new > instance is created which take the name of the method in the constructor ! > } catch (Exception t) { > addTest(warning("Cannot instantiate test case: "+name)); > } > > and in TestCase.runTest() that do what our test caller is doing: > // fname is the name specified on construction of the test case, the name of > the method to run! > runMethod= getClass().getMethod(fName, new Class[0]); > [...] > try { > runMethod.invoke(this, new Class[0]); > } > > This exactly what our test caller do... In some way we have even more > flexibility because we can decorate the test caller (adding running time > constraint, expecting some exception...). > Hmm, yes, didn't look beyond the reflection stuff in TestCase. Don't know why the Java version needs separate TestCase instances per Test though. Maybe concurrency safety, since Java doesn't have the 'object ownership' problem at least. --8<-- > > > > Sorry to be blunt, but I think this sucks, because you need to be very > careful to override makeFixture() in every subclass. Why can't the TestCase > use a reference to itself instead? > Its depends how you make your code. I use IDE macro to generate and adds > file to the project. I just check a box to say "this class is a cppunit > test case", and it adds everything I need to make the class a test case > (static suite method, inheritance, includes...). This way I remove all the > problem you have when using cut and paste to do that. > > > Ahem, the amended 'hierarchy' example seems like a perfectly valid example > of how to use the same fixture for multiple TestCallers. Any objections? > > There is a very bad thing about the way its done: you enforce the class > owning the test caller to also own a reference to the test case. Any class > you give the test caller to, must also own the instance of the test case > that was used to create the test caller. I don't see that. You only have to ensure the TestCase lives longer than the TestCallers, right? > > To me this is a big loss of flexibility. It makes it harder to use stuff > such as decorator and break the "ownership" policy that is everywhere in the > framework: > TestSuite owns all its tests (sub-suite, TestCaller, ...) > TestCaller owns all its TestCase > TestCase owns resources needed to run the test. > Each component of the hierarchy can be taken out of the system and works > on its one. The TestCaller does not need the TestSuite to be able to run. > > Usually, you don't build test case on the stack. You have a static > suite() method in the test case returning a new TestSuite object. With the > new ownership policy, you would have to subclass TestSuite so it could hold > (and own) a reference on the TestCase instance. > > To sum it up: > - the TestCaller would not be able to be a component running on its one > (you could not pass it to the TestRunner because it need something "above" > owning the test case). > - you provided a valid example of use of the test caller with a > reference on the test case. Though there are underlying constraints to that > use case (at suite level). > - this would break one of the constructor of TestSuiteBuilder since it > could not use the generic TestSuite class, but would need to instantiate its > owns subclassed TestSuite. > > Sharing the reference on the test case does not make it easier to use, > and split from the ownership policy that is in the framework. Using the > standard template factory method pattern (makeFixture()) seems a lot easier > to me and much more flexible. > > > > > > > > > The only use I can see for the test caller with fixture by reference > is if the Test Caller is stored by value in another class. > > > > > > Things to do: > > > Update TestSuiteBuilder: > > > - add a addTestCaller() method which take a pointer on the > fixture. > > > - add a constructor that take a pointer on a "makeFixture()" > methods, to make > > > subclassing easier. > > > Before you rush off to add makeFixture() methods, etc. Let us rethink this > issue a bit. My personal feeling is that this registration stuff already is > more complex than necessary, so adding more stuff is unlikely to be the > proper solution. I prefer to steal more from JUnit :-) > I was not suggesting adding the makeFixture() method in the library. > This is a user choice (just like having a registerTests() method). If the > user make a test case that can be subclassed, he must design the class so it > can be done. I was merely suggesting a way to do that. > > Conclusion: > - adding the constructor with a pointer on the fixture add a lot of > flexibility to test caller. > - enforcing the use of the constructor by reference remove a lot of > flexility. > > To do cppunit: > - remove TestRegistry.cpp/.h > - implement a TextTestRunner > > To do for the sample: > - add a suite() method for each test case, which returns a > dynamically allocated suite, > - add the suite of each test case to the TextTestRunner, > - run the TextTestRunner. > => this would make it similar to run suite using a graphic or text > TestRunner, and would show how test case should be factored. > OK, thanks for the explanation. Unfortunately until the weekend I don't have the time to sort it out: got an exam this friday. So this would stall the release of 1.5.5 until at least somewhere next week. If otherwise the current tree is OK (and it is, isn't it?), I wouldn't want to deprive people from Win32 support until then, and release 1.5.5 as an ad interim version. May give us some useful feedback from others too. If there're are no nay-sayers, I'll put it on source forge tomorrow. Bastiaan |
From: Baptiste L. <bl...@cl...> - 2001-05-08 11:21:09
|
> > > Humm, just one thing that popup in my mind: who owns the fixture given > > > to the test caller ? That's may be the reason why it is done that way... > > > > > > I guess it had something to do with the automatic test registration thing, > > > which has been removed anyway. > > No, it was done that way in Michael Feather version. And if I understood > > thing well, it's also done that way in junit. > > > > Not! > Please take a look at the JUnit code. JUnit doesn't have a TestCaller: it doesn't need one because it can use Java Reflection to lookup test methods and execute them. > Also, the only container for Tests is the TestSuite class, no Registries or other things. > It's simple and I like it. They don't have a test caller class because the test caller is the test case itself. Here is a piece of code extracted from TestSuite.addTestMethod() (called for each public test method on construction): if (isPublicTestMethod(m)) { names.addElement(name); Object[] args= new Object[]{name}; try { addTest((Test)constructor.newInstance(args)); // <=== a new instance is created which take the name of the method in the constructor ! } catch (Exception t) { addTest(warning("Cannot instantiate test case: "+name)); } and in TestCase.runTest() that do what our test caller is doing: // fname is the name specified on construction of the test case, the name of the method to run! runMethod= getClass().getMethod(fName, new Class[0]); [...] try { runMethod.invoke(this, new Class[0]); } This exactly what our test caller do... In some way we have even more flexibility because we can decorate the test caller (adding running time constraint, expecting some exception...). > > > > > > > Because I did not have a clear picture of all use cases of TestCaller, the > > > current implementation allows the TestCaller to own the Fixture or not: > > > If the Fixture is passed through a reference the TestCaller won't own it. > > > If the Fixture is passed through a pointer the TestCaller will assume > > > ownership and destroy it in its destructor. > > > > Things I want to point out: > > - in about 95% of the case, you use the default constructor for the > > fixture. > > - Even when subclassing a test case, you override the setUp() and > > tearOff() method, and would still have a default constructor. > > - non default constructor would most likely be used for a test case with > > are parameterized (a generic test case that load tests from a file for > > example). I don't see that happening often. And in all likelyhood, you would > > more likely overide runTests() than create a suite using some test > > callers... > > The main problem is not that the old TestCaller uses the default constructor, but that it is creating the wrong (base) class. I'm ok with that. > > As I see it the problem is solved by introducing a makeFixture() virtual method in test case which can be subclassed. You would have something like: > > > > void registerTest( TestSuite *suite ) > > { > > suite->addTest( > > new TestCaller<MyTestCase>( "test1", test1, makeFixture() ) ); > > suite->addTest( > > new TestCaller<MyTestCase>( "test1", test2, makeFixture() ) ); > > ... > > } > > > > Sorry to be blunt, but I think this sucks, because you need to be very careful to override makeFixture() in every subclass. Why can't the TestCase use a reference to itself instead? Its depends how you make your code. I use IDE macro to generate and adds file to the project. I just check a box to say "this class is a cppunit test case", and it adds everything I need to make the class a test case (static suite method, inheritance, includes...). This way I remove all the problem you have when using cut and paste to do that. > Ahem, the amended 'hierarchy' example seems like a perfectly valid example of how to use the same fixture for multiple TestCallers. Any objections? There is a very bad thing about the way its done: you enforce the class owning the test caller to also own a reference to the test case. Any class you give the test caller to, must also own the instance of the test case that was used to create the test caller. To me this is a big loss of flexibility. It makes it harder to use stuff such as decorator and break the "ownership" policy that is everywhere in the framework: TestSuite owns all its tests (sub-suite, TestCaller, ...) TestCaller owns all its TestCase TestCase owns resources needed to run the test. Each component of the hierarchy can be taken out of the system and works on its one. The TestCaller does not need the TestSuite to be able to run. Usually, you don't build test case on the stack. You have a static suite() method in the test case returning a new TestSuite object. With the new ownership policy, you would have to subclass TestSuite so it could hold (and own) a reference on the TestCase instance. To sum it up: - the TestCaller would not be able to be a component running on its one (you could not pass it to the TestRunner because it need something "above" owning the test case). - you provided a valid example of use of the test caller with a reference on the test case. Though there are underlying constraints to that use case (at suite level). - this would break one of the constructor of TestSuiteBuilder since it could not use the generic TestSuite class, but would need to instantiate its owns subclassed TestSuite. Sharing the reference on the test case does not make it easier to use, and split from the ownership policy that is in the framework. Using the standard template factory method pattern (makeFixture()) seems a lot easier to me and much more flexible. > > > > > The only use I can see for the test caller with fixture by reference is if the Test Caller is stored by value in another class. > > > > Things to do: > > Update TestSuiteBuilder: > > - add a addTestCaller() method which take a pointer on the fixture. > > - add a constructor that take a pointer on a "makeFixture()" methods, to make > > subclassing easier. > Before you rush off to add makeFixture() methods, etc. Let us rethink this issue a bit. My personal feeling is that this registration stuff already is more complex than necessary, so adding more stuff is unlikely to be the proper solution. I prefer to steal more from JUnit :-) I was not suggesting adding the makeFixture() method in the library. This is a user choice (just like having a registerTests() method). If the user make a test case that can be subclassed, he must design the class so it can be done. I was merely suggesting a way to do that. Conclusion: - adding the constructor with a pointer on the fixture add a lot of flexibility to test caller. - enforcing the use of the constructor by reference remove a lot of flexility. To do cppunit: - remove TestRegistry.cpp/.h - implement a TextTestRunner To do for the sample: - add a suite() method for each test case, which returns a dynamically allocated suite, - add the suite of each test case to the TextTestRunner, - run the TextTestRunner. => this would make it similar to run suite using a graphic or text TestRunner, and would show how test case should be factored. > Please try it again. Also check if you can get shell access with SSH on cppunit.sourceforge.net. OK, I'll try that. |
From: Bastiaan B. <bas...@li...> - 2001-05-08 00:15:54
|
Baptiste Lepilleur wrote: > > Humm, just one thing that popup in my mind: who owns the fixture given > > to the test caller ? That's may be the reason why it is done that way... > > > > I guess it had something to do with the automatic test registration thing, > > which has been removed anyway. > No, it was done that way in Michael Feather version. And if I understood > thing well, it's also done that way in junit. > Not! Please take a look at the JUnit code. JUnit doesn't have a TestCaller: it doesn't need one because it can use Java Reflection to lookup test methods and execute them. Also, the only container for Tests is the TestSuite class, no Registries or other things. It's simple and I like it. > > > Because I did not have a clear picture of all use cases of TestCaller, the > > current implementation allows the TestCaller to own the Fixture or not: > > If the Fixture is passed through a reference the TestCaller won't own it. > > If the Fixture is passed through a pointer the TestCaller will assume > > ownership and destroy it in its destructor. > > Things I want to point out: > - in about 95% of the case, you use the default constructor for the > fixture. > - Even when subclassing a test case, you override the setUp() and > tearOff() method, and would still have a default constructor. > - non default constructor would most likely be used for a test case with > are parameterized (a generic test case that load tests from a file for > example). I don't see that happening often. And in all likelyhood, you would > more likely overide runTests() than create a suite using some test > callers... The main problem is not that the old TestCaller uses the default constructor, but that it is creating the wrong (base) class. > > Well, here I presents the test cases of use of the TestCaller. > > The common code to create a suite is as follow: > > TestSuite *suite = new TestSuite( "MyTestCase" ); > registerTest( suite ); > > void registerTest( TestSuite *suite ) > { > suite->addTest( new TestCaller<MyTestCase>( "test1", test1 ) ); > suite->addTest( new TestCaller<MyTestCase>( "test1", test2 ) ); > ... > } > > Using the constructor with a pointer on the fixture works: > void registerTest( TestSuite *suite ) > { > > te->addTest( > new TestCaller<MyTestCase>( "test1", test1, > new MyTestCase( "file-test1.test") ) ); > > suite->addTest( > new TestCaller<MyTestCase>( "test1", test2, > new MyTestCase("file-test2.test") ) ); > ... > } > > The problem is if you want one fixture to be shared with many test caller (which is what you would do when subclassing and reusing test case): > > void registerTest( TestSuite *suite, MyTestCase &fixture ) > { > suite->addTest( > new TestCaller<MyTestCase>( "test1", test1, fixture ) ); > suite->addTest( > new TestCaller<MyTestCase>( "test1", test2, fixture ) ); > ... > } > > The problem is who owns the referenced fixture: > > MySubclassedTestCase::suite() { > TestSuite *suite = new TestSuite( "MySubClassedTestCase" ); > > // WHO owns that fixture ??? => who will delete it ? > MySubclassedTestCase *fixture = new MySubclassedTestCase(); > MyTestCase::registerTest( suite, *fixture ); > ... > } > > As I see it the problem is solved by introducing a makeFixture() virtual method in test case which can be subclassed. You would have something like: > > void registerTest( TestSuite *suite ) > { > suite->addTest( > new TestCaller<MyTestCase>( "test1", test1, makeFixture() ) ); > suite->addTest( > new TestCaller<MyTestCase>( "test1", test2, makeFixture() ) ); > ... > } > Sorry to be blunt, but I think this sucks, because you need to be very careful to override makeFixture() in every subclass. Why can't the TestCase use a reference to itself instead? > > So until a clean way is found to "share" a fixture between test callers, I'll stick to the one fixture per test caller policy (not that much of a bother after all). All the previous problem (subclassing) have been solved by the introduction constructor with a pointer on the fixture. > Ahem, the amended 'hierarchy' example seems like a perfectly valid example of how to use the same fixture for multiple TestCallers. Any objections? > > The only use I can see for the test caller with fixture by reference is if the Test Caller is stored by value in another class. > > Things to do: > Update TestSuiteBuilder: > - add a addTestCaller() method which take a pointer on the fixture. > - a > dd a constructor that take a pointer on a "makeFixture()" methods, to make > subclassing easier. > Before you rush off to add makeFixture() methods, etc. Let us rethink this issue a bit. My personal feeling is that this registration stuff already is more complex than necessary, so adding more stuff is unlikely to be the proper solution. I prefer to steal more from JUnit :-) > > Baptiste. > > PS: I tried to login with CVS and SSH this afternoon and I got a error > message. So I guess I'll have to go back to the doc ;-( I don't know when you tried it, but note that there is a 6(?) hour delay in propagation of the project membership. Your project membership may simply not have reached the CVS server at that time. Please try it again. Also check if you can get shell access with SSH on cppunit.sourceforge.net. Bastiaan > > --- > Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html > Author of The Text Reformatter, a tool for fanfiction readers and writers. > Language: English, French (Well, I'm French). > > _______________________________________________ > Cppunit-devel mailing list > Cpp...@li... > http://lists.sourceforge.net/lists/listinfo/cppunit-devel |
From: Baptiste L. <bl...@cl...> - 2001-05-07 19:16:37
|
> Humm, just one thing that popup in my mind: who owns the fixture given > to the test caller ? That's may be the reason why it is done that way... > > I guess it had something to do with the automatic test registration thing, > which has been removed anyway. No, it was done that way in Michael Feather version. And if I understood thing well, it's also done that way in junit. > Because I did not have a clear picture of all use cases of TestCaller, the > current implementation allows the TestCaller to own the Fixture or not: > If the Fixture is passed through a reference the TestCaller won't own it. > If the Fixture is passed through a pointer the TestCaller will assume > ownership and destroy it in its destructor. Things I want to point out: - in about 95% of the case, you use the default constructor for the fixture. - Even when subclassing a test case, you override the setUp() and tearOff() method, and would still have a default constructor. - non default constructor would most likely be used for a test case with are parameterized (a generic test case that load tests from a file for example). I don't see that happening often. And in all likelyhood, you would more likely overide runTests() than create a suite using some test callers... Well, here I presents the test cases of use of the TestCaller. The common code to create a suite is as follow: TestSuite *suite = new TestSuite( "MyTestCase" ); registerTest( suite ); void registerTest( TestSuite *suite ) { suite->addTest( new TestCaller<MyTestCase>( "test1", test1 ) ); suite->addTest( new TestCaller<MyTestCase>( "test1", test2 ) ); ... } Using the constructor with a pointer on the fixture works: void registerTest( TestSuite *suite ) { te->addTest( new TestCaller<MyTestCase>( "test1", test1, new MyTestCase( "file-test1.test") ) ); suite->addTest( new TestCaller<MyTestCase>( "test1", test2, new MyTestCase("file-test2.test") ) ); ... } The problem is if you want one fixture to be shared with many test caller (which is what you would do when subclassing and reusing test case): void registerTest( TestSuite *suite, MyTestCase &fixture ) { suite->addTest( new TestCaller<MyTestCase>( "test1", test1, fixture ) ); suite->addTest( new TestCaller<MyTestCase>( "test1", test2, fixture ) ); ... } The problem is who owns the referenced fixture: MySubclassedTestCase::suite() { TestSuite *suite = new TestSuite( "MySubClassedTestCase" ); // WHO owns that fixture ??? => who will delete it ? MySubclassedTestCase *fixture = new MySubclassedTestCase(); MyTestCase::registerTest( suite, *fixture ); ... } As I see it the problem is solved by introducing a makeFixture() virtual method in test case which can be subclassed. You would have something like: void registerTest( TestSuite *suite ) { suite->addTest( new TestCaller<MyTestCase>( "test1", test1, makeFixture() ) ); suite->addTest( new TestCaller<MyTestCase>( "test1", test2, makeFixture() ) ); ... } So until a clean way is found to "share" a fixture between test callers, I'll stick to the one fixture per test caller policy (not that much of a bother after all). All the previous problem (subclassing) have been solved by the introduction constructor with a pointer on the fixture. The only use I can see for the test caller with fixture by reference is if the Test Caller is stored by value in another class. Things to do: Update TestSuiteBuilder: - add a addTestCaller() method which take a pointer on the fixture. - a dd a constructor that take a pointer on a "makeFixture()" methods, to make subclassing easier. Baptiste. PS: I tried to login with CVS and SSH this afternoon and I got a error message. So I guess I'll have to go back to the doc ;-( --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Author of The Text Reformatter, a tool for fanfiction readers and writers. Language: English, French (Well, I'm French). |
From: Bastiaan B. <bas...@li...> - 2001-05-07 11:28:02
|
-----Oorspronkelijk bericht----- Van: Baptiste Lepilleur [mailto:bl...@cl...] Verzonden: Monday, May 07, 2001 12:13 PM Aan: cpp...@li... Onderwerp: Re: [Cppunit-devel] hierarchy sample bug... > I've implemented the fix I suggested yesterday: TestCaller now has two extra > constructors which accept either a reference or a pointer to an existing > fixture as an extra parameter. Now GameBoardTest constructs a TestCaller > with *this as Fixture and the correct setUp(), tearDown() and testmethod are > called. > I don't see why every TestCaller needs its own Fixture instance, so if there > aren't any objections I'd like to deprecate the old constructor. > Please let me know if you see any flaws in this approach. I would let the old constructor alone, but indicates in the documentation that the new one should be used instead. Since the old constructor leads to broken behaviour, I would like to mark it deprecated in 1.5.5 and remove it eventually. This implies that at least the code in CppUnit itself will not use this constructor anymore. Could you please look into how to do this for the code merged from CppUnitW? Humm, just one thing that popup in my mind: who owns the fixture given to the test caller ? That's may be the reason why it is done that way... I guess it had something to do with the automatic test registration thing, which has been removed anyway. Because I did not have a clear picture of all use cases of TestCaller, the current implementation allows the TestCaller to own the Fixture or not: If the Fixture is passed through a reference the TestCaller won't own it. If the Fixture is passed through a pointer the TestCaller will assume ownership and destroy it in its destructor. As far as I can see we won't need the second variant. Bastiaan > > Bastiaan > > > Baptiste. > --- > Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html > Author of The Text Reformatter, a tool for fanfiction readers and writers. > Language: English, French (Well, I'm French). > > > > _______________________________________________ > Cppunit-devel mailing list > Cpp...@li... > http://lists.sourceforge.net/lists/listinfo/cppunit-devel > > _______________________________________________ > Cppunit-devel mailing list > Cpp...@li... > http://lists.sourceforge.net/lists/listinfo/cppunit-devel > _______________________________________________ Cppunit-devel mailing list Cpp...@li... http://lists.sourceforge.net/lists/listinfo/cppunit-devel |
From: Baptiste L. <bl...@cl...> - 2001-05-07 10:15:27
|
> Haha, you want to make separate dists for Windows, just to let people read > the ChangeLog with notepad? > He, I've got a fix: I'll add a line at the beginning of README, saying 'Dear > Windoze user, read this file using WordPad, not NotePad'. > Seriously, having to dists containing essentially the same stuff is > confusing and not worth the effort. I agree about the confusing part (the stuff is supposed to be portable and you wonder why you have two dist...). And at the current time its clear that it's not worth it. Another way to solve the confusing part would be to say that both dists contains the same files but are in the OS format. I say let the problem rest for now... Baptiste. --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Author of The Text Reformatter, a tool for fanfiction readers and writers. Language: English, French (Well, I'm French). |
From: Bastiaan B. <bas...@li...> - 2001-05-07 10:05:49
|
-----Oorspronkelijk bericht----- Van: Baptiste Lepilleur [mailto:bl...@cl...] Verzonden: Monday, May 07, 2001 11:33 AM Aan: cpp...@li... Onderwerp: Re: [Cppunit-devel] CppUnitW 1.2 merge > Yup, the solution is rather simple: I added " perl -pi -e 's/\n/\r\n/g' `find > $(distdir) -name '*.ds?'` " to the dist-hook target, so all *.ds? files are > converted to CRLF endings before the tar ball is made. > I've uploaded the new tar to cryptoforge. Please try it. It's working just fine. Let's try for a release. We still might want to do a windows and a unix version. For the windows version, all text file would be converted. VC++ doesn't have any problem with unix file, but notepad can't read unix text file. It would be a problem for user trying to read "changelog", or "install"... Not really a problem for me since the tool I'm using doesn't have a problem with unix file (Windows Commander). Haha, you want to make separate dists for Windows, just to let people read the ChangeLog with notepad? He, I've got a fix: I'll add a line at the beginning of README, saying 'Dear Windoze user, read this file using WordPad, not NotePad'. Seriously, having to dists containing essentially the same stuff is confusing and not worth the effort. Bastiaan We could just wait until people ask for it, or set up a pool for that ;-) Baptiste. --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Author of The Text Reformatter, a tool for fanfiction readers and writers. Language: English, French (Well, I'm French). _______________________________________________ Cppunit-devel mailing list Cpp...@li... http://lists.sourceforge.net/lists/listinfo/cppunit-devel |
From: Baptiste L. <bl...@cl...> - 2001-05-07 09:57:51
|
> I've implemented the fix I suggested yesterday: TestCaller now has two extra > constructors which accept either a reference or a pointer to an existing > fixture as an extra parameter. Now GameBoardTest constructs a TestCaller > with *this as Fixture and the correct setUp(), tearDown() and testmethod are > called. > I don't see why every TestCaller needs its own Fixture instance, so if there > aren't any objections I'd like to deprecate the old constructor. > Please let me know if you see any flaws in this approach. I would let the old constructor alone, but indicates in the documentation that the new one should be used instead. Humm, just one thing that popup in my mind: who owns the fixture given to the test caller ? That's may be the reason why it is done that way... > > Bastiaan > > > Baptiste. > --- > Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html > Author of The Text Reformatter, a tool for fanfiction readers and writers. > Language: English, French (Well, I'm French). > > > > _______________________________________________ > Cppunit-devel mailing list > Cpp...@li... > http://lists.sourceforge.net/lists/listinfo/cppunit-devel > > _______________________________________________ > Cppunit-devel mailing list > Cpp...@li... > http://lists.sourceforge.net/lists/listinfo/cppunit-devel > |
From: Baptiste L. <bl...@cl...> - 2001-05-07 09:17:33
|
> Yup, the solution is rather simple: I added " perl -pi -e 's/\n/\r\n/g' `find > $(distdir) -name '*.ds?'` " to the dist-hook target, so all *.ds? files are > converted to CRLF endings before the tar ball is made. > I've uploaded the new tar to cryptoforge. Please try it. It's working just fine. Let's try for a release. We still might want to do a windows and a unix version. For the windows version, all text file would be converted. VC++ doesn't have any problem with unix file, but notepad can't read unix text file. It would be a problem for user trying to read "changelog", or "install"... Not really a problem for me since the tool I'm using doesn't have a problem with unix file (Windows Commander). We could just wait until people ask for it, or set up a pool for that ;-) Baptiste. --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Author of The Text Reformatter, a tool for fanfiction readers and writers. Language: English, French (Well, I'm French). |
From: Bastiaan B. <bas...@li...> - 2001-05-07 09:06:30
|
-----Oorspronkelijk bericht----- Van: Baptiste Lepilleur [mailto:bl...@cl...] Verzonden: Sunday, May 06, 2001 2:12 PM Aan: cpp...@li... Onderwerp: Re: [Cppunit-devel] hierarchy sample bug... --8<-- > That is correct behaviour. The BoardGameTest checks invariants that should hold > for all BoardGameTest instances, including Chess objects. The testReset() > method in BoardGameTest should equally apply to Chess objects. Overriding > testReset() in ChessTest is a serious indication that the design of application > is flawed. I agree with that. Though in some case you might have some "template method" (the pattern) in your test case. I can see that applying when you have some specific behavior and want to factor some testing part. An example that pop up into my mind would be testing visitor/strategy/builder. The setup of each test may be identical and you would want to factor out those part in a base class. Then, you would use the self-shunt pattern (having the test case implementing the visitor interface...), and delegate part of the actual test to the derived test case. OK, you got me there! :-) > However, there is one problem, which may be what you hint at: the current > BoardGameTest implementation implies that all BoardGame classes have a default > constructor and need no further setup. This is indeed the main problem I see. You want the setUp() and tearOff() method of your derived class to be called: initialization of the "game" class, initialization of the default database connection for the current thread... I've implemented the fix I suggested yesterday: TestCaller now has two extra constructors which accept either a reference or a pointer to an existing fixture as an extra parameter. Now GameBoardTest constructs a TestCaller with *this as Fixture and the correct setUp(), tearDown() and testmethod are called. I don't see why every TestCaller needs its own Fixture instance, so if there aren't any objections I'd like to deprecate the old constructor. Please let me know if you see any flaws in this approach. Bastiaan Baptiste. --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Author of The Text Reformatter, a tool for fanfiction readers and writers. Language: English, French (Well, I'm French). _______________________________________________ Cppunit-devel mailing list Cpp...@li... http://lists.sourceforge.net/lists/listinfo/cppunit-devel |