digitalmars.D - Seperating unit tests from programs
- Alex Stevenson (36/36) Feb 07 2005 Hi,
- Andy Friesen (8/27) Feb 07 2005 This would be a huge timesaver for just about any project using
- pragma (18/30) Feb 07 2005 It's not a bad suggestion. In fact, similar things have been brought up...
- Matthew (14/49) Feb 07 2005 Seems quite sensible to me. STLSoft has unittests in all (well, that's
- Walter (2/2) Feb 08 2005 It would be pretty simple to modify internal\dmain2.d for your applicati...
- Alex Stevenson (10/13) Feb 08 2005 Yes, looking at the code it seems like a fairly trivial matter, but is
- Walter (4/17) Feb 10 2005 They're not really meant for including in a released binary. Just an eas...
- Benji Smith (23/25) Feb 10 2005 I'm not too familiar with the D unit tests, so please ignore my
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (13/24) Feb 10 2005 D makes quite a deal of including unittest { } into the core language.
- =?iso-8859-1?q?Knud_S=F8rensen?= (17/19) Feb 11 2005 Hi
- Derek (6/20) Feb 11 2005 And don't forget the desire to run *all* the unittests rather than crash
- Alex Stevenson (8/26) Feb 11 2005 Yes, this is very useful for large projects which do nightly builds.
- Ben Hinkle (12/39) Feb 11 2005 I see the D unittests as something that a code change must pass in order...
- Alex Stevenson (20/71) Feb 11 2005 I agree, that's how I see unit tests - but since multiple code changes m...
- Walter (4/6) Feb 11 2005 Sometimes having more compiler switches is more confusing than simply
- Walter (26/28) Feb 11 2005 No problem. There are many options:
- Derek (5/39) Feb 12 2005 D'oh! Of course! Thanks for these hints, Walter.
Hi, I've been a lurker on the D newsgroup for a while now and I'm a definite D devotee - after having done several months of C, I appreciate the features of D greatly. I _finally_ have something to say... It's a feature suggestion to throw to the wolves: Would it be possible/desirable/moronic to add a command line option to get DMD to generate unit tests as a seperate executable to the main code? There are situations where it is desirable to run unit tests seperately and not with the main program. I'm not very good at explaining things, so I'll give an example from my experience: I've done a little work in a large-ish C project (30ish developers, similar number of testers) where code is built on a machine that is not capable of running the program produced (due to software setup/hardware present) even though both the build and target machine use Linux and x86 hardware. In this case, unit tests were built and run on the build machine after the main program had successfully built since none of the unit tests relied on the specific hardware of the target machines. The build was not 'released' to the testers unless the unit tests had completed successfully. Having the unit tests seperate from the program let the unit tests be run on the build machine without tying up test machines. Also in this case once the unit tests (possibly time-consuming and complex) have been successful once for each build, there is no additional benefit from running them on program start - in fact it could be harmful as the program ran as part of a cluster and made guarantees about time taken to start up/restart the program. As far as I can see generating a unit test only executable would be as simple as generating a main function which only ran _moduleCtor(); _moduleUnitTests(); and _not_ run the user-supplied main Hopefully someone can get my meaning from these ramblings - I think seperating unit test code from program could be a useful aid to large scale projects or programs which rely on specific hardware. Alex Stevenson
Feb 07 2005
Alex Stevenson wrote:Hi, I've been a lurker on the D newsgroup for a while now and I'm a definite D devotee - after having done several months of C, I appreciate the features of D greatly. I _finally_ have something to say... It's a feature suggestion to throw to the wolves: Would it be possible/desirable/moronic to add a command line option to get DMD to generate unit tests as a seperate executable to the main code? There are situations where it is desirable to run unit tests seperately and not with the main program. As far as I can see generating a unit test only executable would be as simple as generating a main function which only ran _moduleCtor(); _moduleUnitTests(); and _not_ run the user-supplied mainThis would be a huge timesaver for just about any project using test-driven development. Two other things that would be exceptionally useful, especially in combination with this, would be the ability to name unit tests, and having the resulting executable run every single test instead of stopping at the first failure. -- andy
Feb 07 2005
In article <cu88hv$2uq6$1 digitaldaemon.com>, Alex Stevenson says...Would it be possible/desirable/moronic to add a command line option to get DMD to generate unit tests as a seperate executable to the main code?It's not a bad suggestion. In fact, similar things have been brought up in the past on this group. However, it has also been noted that DMD is really designed to be at the bottom of a tool-chain, hence why a behavior like this may not be justifiable for the compiler itself. my $0.02: In your particular build environment, it looks like all you need are some custom bits added to your makefile and/or use a shell script. Just don't use the 'unittest{}' block and compile your application against a unit-test oriented 'int main()' as a separate build step. With a little clever coding, you can use this to catch exceptions so you can run a report of which tests failed, and which passed; its much more flexible than a basic 'unittest{}' this way. The shell-script option would also allow you to branch based on the result of 'unittest.exe' (or whatever you want to call it), so you can skip the call to compile the target application. If the test passes, then the script can then build your main executable and run it (if need be). If shell scripting's not your thing, you could just write your builder in D.// builder program (untested, w/o useful error messages) import std.process; static const int SUCCESS = 0; //errors are usually non-zero void main(){ int result; if(std.process.system("make unittest") != SUCCESS) return; if(std.process.system("unittest.exe") != SUCCESS) return; if(std.process.system("make application") != SUCCESS) return; std.process.system("application.exe"); }- EricAnderton at yahoo
Feb 07 2005
Hi, I've been a lurker on the D newsgroup for a while now and I'm a definite D devotee - after having done several months of C, I appreciate the features of D greatly. I _finally_ have something to say... It's a feature suggestion to throw to the wolves: Would it be possible/desirable/moronic to add a command line option to get DMD to generate unit tests as a seperate executable to the main code? There are situations where it is desirable to run unit tests seperately and not with the main program. I'm not very good at explaining things, so I'll give an example from my experience: I've done a little work in a large-ish C project (30ish developers, similar number of testers) where code is built on a machine that is not capable of running the program produced (due to software setup/hardware present) even though both the build and target machine use Linux and x86 hardware. In this case, unit tests were built and run on the build machine after the main program had successfully built since none of the unit tests relied on the specific hardware of the target machines. The build was not 'released' to the testers unless the unit tests had completed successfully. Having the unit tests seperate from the program let the unit tests be run on the build machine without tying up test machines. Also in this case once the unit tests (possibly time-consuming and complex) have been successful once for each build, there is no additional benefit from running them on program start - in fact it could be harmful as the program ran as part of a cluster and made guarantees about time taken to start up/restart the program. As far as I can see generating a unit test only executable would be as simple as generating a main function which only ran _moduleCtor(); _moduleUnitTests(); and _not_ run the user-supplied main Hopefully someone can get my meaning from these ramblings - I think seperating unit test code from program could be a useful aid to large scale projects or programs which rely on specific hardware.Seems quite sensible to me. STLSoft has unittests in all (well, that's the theory) components, which are enabled by definition of the STLSOFT_UNITTEST preprocessor symbol. One needs to include any/all STLSoft headers in a main program and compile/link to a (ridiculously) simple component that iterates through them and executes them. There's no automatic provision for unit-tests to be run as part of programs using STLSoft code, and while people _could_ do that if they wished, it seems a very odd thing to want to do, since, as you say, once they've run successfully, they will always do so. (Notwithstanding cosmic rays, overclocking and quantum fluctuations, of course. <g>) IMO, unit-tests are quite different (at least in terms of their purpose) from contracts. Your post is very useful, since I don't think anyone's pointed this out before, yet it's one of those things that seem both obvious and important once raised.
Feb 07 2005
It would be pretty simple to modify internal\dmain2.d for your application to just run the unit tests and not call main().
Feb 08 2005
On Tue, 8 Feb 2005 12:55:42 -0800, Walter <newshound digitalmars.com> wrote:It would be pretty simple to modify internal\dmain2.d for your application to just run the unit tests and not call main().Yes, looking at the code it seems like a fairly trivial matter, but is there any advantage to running unit tests on every program start? Once they've passed once the binary will always pass them unless you're using them for purposes of a non-unit test nature (like testing for the original Pentium FP problems). Unless there's something I'm overlooking, I can't think of a case where you'd want to run integrated unit tests and program. -- Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
Feb 08 2005
"Alex Stevenson" <ans104 cs.york.ac.uk> wrote in message news:opslwfn3ir08qma6 mjolnir.spamnet.local...On Tue, 8 Feb 2005 12:55:42 -0800, Walter <newshound digitalmars.com> wrote:They're not really meant for including in a released binary. Just an easy way to get them run.It would be pretty simple to modify internal\dmain2.d for your application to just run the unit tests and not call main().Yes, looking at the code it seems like a fairly trivial matter, but is there any advantage to running unit tests on every program start? Once they've passed once the binary will always pass them unless you're using them for purposes of a non-unit test nature (like testing for the original Pentium FP problems). Unless there's something I'm overlooking, I can't think of a case where you'd want to run integrated unit tests and program.
Feb 10 2005
On Thu, 10 Feb 2005 00:13:24 -0800, "Walter" <newshound digitalmars.com> wrote:They're not really meant for including in a released binary. Just an easy way to get them run.I'm not too familiar with the D unit tests, so please ignore my suggestion if it's already possible. But when I do my java development, I always put my unit tests into a different source tree than my application code. The test_src directory has a package structure that mirrors the package hierarchy of the application code's src directory. Here's an example... /src /net /benjismith /myproject /MyClass.java /test_src /net /benjismith /myproject /MyTestClass.java When I build my project, it's easy to either include or exclude the classes in my unit-testing hierarchy. I don't know whether such a separation is possible in D, but this is how I prefer to structure my projects. --Benji Smith
Feb 10 2005
Benji Smith wrote:I'm not too familiar with the D unit tests, so please ignore my suggestion if it's already possible. But when I do my java development, I always put my unit tests into a different source tree than my application code. The test_src directory has a package structure that mirrors the package hierarchy of the application code's src directory. Here's an example...When I build my project, it's easy to either include or exclude the classes in my unit-testing hierarchy. I don't know whether such a separation is possible in D, but this is how I prefer to structure my projects.D makes quite a deal of including unittest { } into the core language. Thus the tests go in the usual code, and not in a separate hierarchy. They are enabled with the use of -unittest, and disabled with -release (actually just by not adding the -unittest option in the first place) See the various Phobos std modules for examples on how this looks... Building the "main" program for the unit test is much more of a manual process with D, since you have to make sure to reference all modules that you want to test, and since there is no reflection like in Java. Again, see "phobos/unittest.d" that comes with DMD for an example. --anders PS. In case you ask about "JavaDoc", that's usually done with Doxygen... Ant is working on some replacement: http://leds.sourceforge.net/
Feb 10 2005
On Thu, 10 Feb 2005 00:13:24 -0800, Walter wrote:They're not really meant for including in a released binary. Just an easy way to get them run.Hi So, far I seen that people would like to: 1) Split the test program from the main program.(Alex) 2) Make sure that the tests get executed. (Walter) 3) Be able to run single named tests (Andy) 4) Be able to run unit test on -release programs. (Anders) A way to make all this happen would be for the compiler to generate a separate unit test executable (1) and make the compiler run the test executable as the last step (2). If the test executable could be called with parameters we got (3) and if dynamic linked to the main code would give us (4). Knud ps.) Some time ago I posted some unit test suggestions on the dlanguage wiki at http://dlanguage.netunify.com/59 But the wiki seams to have gone away.
Feb 11 2005
On Fri, 11 Feb 2005 22:40:56 +0100, Knud Sørensen wrote:On Thu, 10 Feb 2005 00:13:24 -0800, Walter wrote:And don't forget the desire to run *all* the unittests rather than crash out on the first assert failure. -- Derek Melbourne, AustraliaThey're not really meant for including in a released binary. Just an easy way to get them run.Hi So, far I seen that people would like to: 1) Split the test program from the main program.(Alex) 2) Make sure that the tests get executed. (Walter) 3) Be able to run single named tests (Andy) 4) Be able to run unit test on -release programs. (Anders)
Feb 11 2005
On Sat, 12 Feb 2005 08:53:45 +1100, Derek <derek psych.ward> wrote:On Fri, 11 Feb 2005 22:40:56 +0100, Knud Sørensen wrote:Yes, this is very useful for large projects which do nightly builds. Checking unit test output can be a part of the build team's duties - they can arrive at work, find all the failures from the build and throw them at the appropriate person. (Who would catch them, rethrow them etc until it's time to go home). -- Using Opera's revolutionary e-mail client: http://www.opera.com/m2/On Thu, 10 Feb 2005 00:13:24 -0800, Walter wrote:And don't forget the desire to run *all* the unittests rather than crash out on the first assert failure.They're not really meant for including in a released binary. Just an easy way to get them run.Hi So, far I seen that people would like to: 1) Split the test program from the main program.(Alex) 2) Make sure that the tests get executed. (Walter) 3) Be able to run single named tests (Andy) 4) Be able to run unit test on -release programs. (Anders)
Feb 11 2005
"Alex Stevenson" <ans104 cs.york.ac.uk> wrote in message news:opsl183yzi08qma6 mjolnir.spamnet.local...On Sat, 12 Feb 2005 08:53:45 +1100, Derek <derek psych.ward> wrote:I see the D unittests as something that a code change must pass in order to get accepted. I can't see checking in code that breaks the unittests - such code should be rejected. If by some accident a change breaks a unittest it should be backed out. A complete testing infrastructure would catch more subtle system bugs that could creep in by mistake when a change in one area accidentally causes another to fail. For that system I would want to catch failures and generate nice logs etc etc. Then if one really wants to control the unittest harness it isn't hard to do that by hand or by modifying phobos.On Fri, 11 Feb 2005 22:40:56 +0100, Knud Sørensen wrote:Yes, this is very useful for large projects which do nightly builds. Checking unit test output can be a part of the build team's duties - they can arrive at work, find all the failures from the build and throw them at the appropriate person. (Who would catch them, rethrow them etc until it's time to go home).On Thu, 10 Feb 2005 00:13:24 -0800, Walter wrote:And don't forget the desire to run *all* the unittests rather than crash out on the first assert failure.They're not really meant for including in a released binary. Just an easy way to get them run.Hi So, far I seen that people would like to: 1) Split the test program from the main program.(Alex) 2) Make sure that the tests get executed. (Walter) 3) Be able to run single named tests (Andy) 4) Be able to run unit test on -release programs. (Anders)
Feb 11 2005
On Fri, 11 Feb 2005 20:46:08 -0500, Ben Hinkle <ben.hinkle gmail.com> wrote:"Alex Stevenson" <ans104 cs.york.ac.uk> wrote in message news:opsl183yzi08qma6 mjolnir.spamnet.local...I agree, that's how I see unit tests - but since multiple code changes may be simultaneously integrated in a multiple developer environment, the unit test is a necessary first line of defence for catching code which causes problems when a formal build is produced. It's not that developers shouldn't run the unit tests before checking in code (they should!), but that it's also a good first step towards verifying a particular build of code, since you can't always trust programmers to folow procedure and lots of code/code changes interacting can produce unforseen complications.On Sat, 12 Feb 2005 08:53:45 +1100, Derek <derek psych.ward> wrote:I see the D unittests as something that a code change must pass in order to get accepted. I can't see checking in code that breaks the unittests - such code should be rejected. If by some accident a change breaks a unittest it should be backed out.On Fri, 11 Feb 2005 22:40:56 +0100, Knud Sørensen wrote:Yes, this is very useful for large projects which do nightly builds. Checking unit test output can be a part of the build team's duties - they can arrive at work, find all the failures from the build and throw them at the appropriate person. (Who would catch them, rethrow them etc until it's time to go home).On Thu, 10 Feb 2005 00:13:24 -0800, Walter wrote:And don't forget the desire to run *all* the unittests rather than crash out on the first assert failure.They're not really meant for including in a released binary. Just an easy way to get them run.Hi So, far I seen that people would like to: 1) Split the test program from the main program.(Alex) 2) Make sure that the tests get executed. (Walter) 3) Be able to run single named tests (Andy) 4) Be able to run unit test on -release programs. (Anders)A complete testing infrastructure would catch more subtle system bugs that could creep in by mistake when a change in one area accidentally causes another to fail. For that system I would want to catch failures and generate nice logs etc etc.Of course unit testing is just the first stage of testing - A set of automatic sanity checks for code consistency to help determine whether code does what you think it does (later testing should pick up more subtle things, like whether what it does is really what you wanted). Unit testing is great for catching inconsistencies before the testing proceeds to more involved tests which tie up test resource (Hardware or personnel)Then if one really wants to control the unittest harness it isn't hard to do that by hand or by modifying phobos.True. It is easy enough to do manually, but is it sufficiently useful to warrent automation (as a compiler option or version flag)?-- Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
Feb 11 2005
"Alex Stevenson" <ans104 cs.york.ac.uk> wrote in message news:opsl2aeynd08qma6 mjolnir.spamnet.local...True. It is easy enough to do manually, but is it sufficiently useful to warrent automation (as a compiler option or version flag)?Sometimes having more compiler switches is more confusing than simply editting dmain2.d to do what you need.
Feb 11 2005
"Derek" <derek psych.ward> wrote in message news:hmd6k9c3pmlc$.1q2ml1nysyh0$.dlg 40tude.net...And don't forget the desire to run *all* the unittests rather than crash out on the first assert failure.No problem. There are many options: 1) Instead of using: assert(e); in the unit tests, write: myassert(e, "message"); and write the myassert() to log any errors to the suitable log file. 2) Provide a custom implementation of std.asserterror to do the logging. 3) Catch any AssertError exceptions, log them, and proceed with the unit tests: unittest { try { assert(...); ... } catch (AssertError ae) { ae.print(); } } The compiler & language doesn't care what code is between the { } of the unittest blocks. It can be any valid D code that does whatever you need it to do.
Feb 11 2005
On Fri, 11 Feb 2005 22:19:58 -0800, Walter wrote:"Derek" <derek psych.ward> wrote in message news:hmd6k9c3pmlc$.1q2ml1nysyh0$.dlg 40tude.net...D'oh! Of course! Thanks for these hints, Walter. -- Derek Melbourne, AustraliaAnd don't forget the desire to run *all* the unittests rather than crash out on the first assert failure.No problem. There are many options: 1) Instead of using: assert(e); in the unit tests, write: myassert(e, "message"); and write the myassert() to log any errors to the suitable log file. 2) Provide a custom implementation of std.asserterror to do the logging. 3) Catch any AssertError exceptions, log them, and proceed with the unit tests: unittest { try { assert(...); ... } catch (AssertError ae) { ae.print(); } } The compiler & language doesn't care what code is between the { } of the unittest blocks. It can be any valid D code that does whatever you need it to do.
Feb 12 2005