www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Utah Valley University teaches D (using TDPL)

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
http://uvu.freshsources.com/page9/page7/files/Syllabus4450.html

Andrei
Nov 15 2010
next sibling parent David Gileadi <gileadis NSPMgmail.com> writes:
On 11/15/10 2:00 PM, Andrei Alexandrescu wrote:
 http://uvu.freshsources.com/page9/page7/files/Syllabus4450.html

 Andrei
I had a class from Chuck; he introduced me to D. He's an excellent teacher.
Nov 15 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:

 [Good Stuff=E2=84=A2]
Awesome! -- = Simen
Nov 15 2010
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 http://uvu.freshsources.com/page9/page7/files/Syllabus4450.html
This is good. Despite its bugs/unfinished parts D2 is a good language to teach certain kinds of lower level programming (and some OOP too). This is the page of the resources of the course: http://uvu.freshsources.com/page9/page7/page7.html This is the D Homework: http://uvu.freshsources.com/page9/page7/files/D%20Homework.docx It contains: Implement a deque in D using two dynamic arrays, as depicted above. The following functions should be present: push_front(x) push_back(x) pop_front() pop_back() at(uint pos) back() front() size() I see two small problems there: - uint used instead of size_t - Names like_this instead of the D idiom likeThis. He also gives a quite useful unittest that the student implementation must pass, this is a good usage of unittests. The unit test ends like this: ... writeln("unit test passed"); } Indeed, a person needs feedback that the unittests have run (and have succeed), I have used similar things in my dlbs1 (but more refined). This kind of need for feedback is so natural that something like that will be better somehow done on default by D. Bye, bearophile
Nov 15 2010
parent reply Sean Kelly <sean invisibleduck.org> writes:
bearophile Wrote:
 
 He also gives a quite useful unittest that the student implementation must
pass, this is a good usage of unittests. The unit test ends like this:
 
 ...
     writeln("unit test passed");
 }
 
 Indeed, a person needs feedback that the unittests have run (and have
succeed), I have used similar things in my dlbs1 (but more refined). This kind
of need for feedback is so natural that something like that will be better
somehow done on default by D.
I'd like unit tests to be optionally named: unittest("name"). The rest could then be done in library code.
Nov 16 2010
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, November 16, 2010 07:53:01 Sean Kelly wrote:
 bearophile Wrote:
 He also gives a quite useful unittest that the student implementation
 must pass, this is a good usage of unittests. The unit test ends like
 this:
 
 ...
 
     writeln("unit test passed");
 
 }
 
 Indeed, a person needs feedback that the unittests have run (and have
 succeed), I have used similar things in my dlbs1 (but more refined).
 This kind of need for feedback is so natural that something like that
 will be better somehow done on default by D.
I'd like unit tests to be optionally named: unittest("name"). The rest could then be done in library code.
That would indeed be great. With that done, it could become possible to run unit tests by name (though that would likely mean more changes for the compiler) in an IDE or whatnot. There's at least one bug report suggesting it, IIRC, though I think that it was suggested that they be named without the quotes. unittest(name) should probably translate to something like unittest_name in whatever scope it's in. In any case, it's a good enhancement request that hasn't come to fruition yet. Most of the rest (if not all of it) could indeed be done in a library. Right now unit tests follow the unix convention of saying nothing on success, which I think is best for the current set up - particularly when it's not all that hard to add code yourself which prints out success if you really want it to. - Jonathan M Davis
Nov 16 2010
next sibling parent reply Gide Nwawudu <gide btinternet.com> writes:
On Tue, 16 Nov 2010 10:54:50 -0800, Jonathan M Davis
<jmdavisProg gmx.com> wrote:

On Tuesday, November 16, 2010 07:53:01 Sean Kelly wrote:
 bearophile Wrote:
 He also gives a quite useful unittest that the student implementation
 must pass, this is a good usage of unittests. The unit test ends like
 this:
 
 ...
 
     writeln("unit test passed");
 
 }
 
 Indeed, a person needs feedback that the unittests have run (and have
 succeed), I have used similar things in my dlbs1 (but more refined).
 This kind of need for feedback is so natural that something like that
 will be better somehow done on default by D.
I'd like unit tests to be optionally named: unittest("name"). The rest could then be done in library code.
That would indeed be great. With that done, it could become possible to run unit tests by name (though that would likely mean more changes for the compiler) in an IDE or whatnot. There's at least one bug report suggesting it, IIRC, though I think that it was suggested that they be named without the quotes. unittest(name) should probably translate to something like unittest_name in whatever scope it's in. In any case, it's a good enhancement request that hasn't come to fruition yet. Most of the rest (if not all of it) could indeed be done in a library. Right now unit tests follow the unix convention of saying nothing on success, which I think is best for the current set up - particularly when it's not all that hard to add code yourself which prints out success if you really want it to. - Jonathan M Davis
Already requested, see http://d.puremagic.com/issues/show_bug.cgi?id=2749 Gide
Nov 16 2010
parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 16/11/2010 21:11, Gide Nwawudu wrote:
 On Tue, 16 Nov 2010 10:54:50 -0800, Jonathan M Davis
 <jmdavisProg gmx.com>  wrote:

 On Tuesday, November 16, 2010 07:53:01 Sean Kelly wrote:
 bearophile Wrote:
 He also gives a quite useful unittest that the student implementation
 must pass, this is a good usage of unittests. The unit test ends like
 this:

 ...

      writeln("unit test passed");

 }

 Indeed, a person needs feedback that the unittests have run (and have
 succeed), I have used similar things in my dlbs1 (but more refined).
 This kind of need for feedback is so natural that something like that
 will be better somehow done on default by D.
I'd like unit tests to be optionally named: unittest("name"). The rest could then be done in library code.
That would indeed be great. With that done, it could become possible to run unit tests by name (though that would likely mean more changes for the compiler) in an IDE or whatnot. There's at least one bug report suggesting it, IIRC, though I think that it was suggested that they be named without the quotes. unittest(name) should probably translate to something like unittest_name in whatever scope it's in. In any case, it's a good enhancement request that hasn't come to fruition yet. Most of the rest (if not all of it) could indeed be done in a library. Right now unit tests follow the unix convention of saying nothing on success, which I think is best for the current set up - particularly when it's not all that hard to add code yourself which prints out success if you really want it to. - Jonathan M Davis
Already requested, see http://d.puremagic.com/issues/show_bug.cgi?id=2749 Gide
I also agree having named unittests might be quite useful. I'm not sure about the nesting though, its seems to me using the D module itself as nesting is perfectly fine. -- Bruno Medeiros - Software Engineer
Nov 18 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 18 November 2010 04:47:43 Bruno Medeiros wrote:
 On 16/11/2010 21:11, Gide Nwawudu wrote:
 On Tue, 16 Nov 2010 10:54:50 -0800, Jonathan M Davis
 
 <jmdavisProg gmx.com>  wrote:
 On Tuesday, November 16, 2010 07:53:01 Sean Kelly wrote:
 bearophile Wrote:
 He also gives a quite useful unittest that the student implementation
 must pass, this is a good usage of unittests. The unit test ends like
 this:
 
 ...
 
      writeln("unit test passed");
 
 }
 
 Indeed, a person needs feedback that the unittests have run (and have
 succeed), I have used similar things in my dlbs1 (but more refined).
 This kind of need for feedback is so natural that something like that
 will be better somehow done on default by D.
I'd like unit tests to be optionally named: unittest("name"). The rest could then be done in library code.
That would indeed be great. With that done, it could become possible to run unit tests by name (though that would likely mean more changes for the compiler) in an IDE or whatnot. There's at least one bug report suggesting it, IIRC, though I think that it was suggested that they be named without the quotes. unittest(name) should probably translate to something like unittest_name in whatever scope it's in. In any case, it's a good enhancement request that hasn't come to fruition yet. Most of the rest (if not all of it) could indeed be done in a library. Right now unit tests follow the unix convention of saying nothing on success, which I think is best for the current set up - particularly when it's not all that hard to add code yourself which prints out success if you really want it to. - Jonathan M Davis
Already requested, see http://d.puremagic.com/issues/show_bug.cgi?id=2749 Gide
I also agree having named unittests might be quite useful. I'm not sure about the nesting though, its seems to me using the D module itself as nesting is perfectly fine.
I see no point in nesting. Name unit tests, however, would make stack traces from unit tests actually useable (since you'd know which test they were from when they weren't actually assertion failures in the tests themselves which give you a line number in the tests), and it helps open the doors for allowing external tools to access them directly. - Jonathan M Davis
Nov 18 2010
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 Most of the rest (if not all of it) could indeed be done in a library.
I am not sure it could be done nicely too :-)
 Right now 
 unit tests follow the unix convention of saying nothing on success,
That's an usability failure. Humans expect feedback, because you can't tell apart "unittests run and succeed" from "unittests not even run". That Unix convention is bad here. And Unix commands sometimes have a -v (verbose) command that gives feedback, while D unittests don't have this option.
 particularly when it's not all that hard 
 to add code yourself which prints out success if you really want it to.
It's also not hard to define global functions, wrapped in a version(unittest){}, to replace the need of the unittest keyword (unittest becomes a version ID). Bye, bearophile
Nov 16 2010
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, November 16, 2010 13:33:54 bearophile wrote:
 Jonathan M Davis:
 Most of the rest (if not all of it) could indeed be done in a library.
I am not sure it could be done nicely too :-)
That would depend on what you're trying to do. Printing test success or failure is as simple as adding the approprate scope statement to the beginning of each unittest block. A bit tedious perhaps, but not hard.
 Right now
 unit tests follow the unix convention of saying nothing on success,
That's an usability failure. Humans expect feedback, because you can't tell apart "unittests run and succeed" from "unittests not even run". That Unix convention is bad here. And Unix commands sometimes have a -v (verbose) command that gives feedback, while D unittests don't have this option.
I'm afraid that I have to disagree there. Having all of the successes print out would, in many cases, just be useless output flooding the console. I have no problem with making it possible for unit tests to report success, but I wouldn't want that to be the default. It's quite clear when a test fails, and that's what is necessary in order to fix test failures. I can see why a beginner might want the positive feedback that a test has succeeded, but personally, I would just find it annoying. The only real advantage would be that it would indicate where in the unit tests the program was, and that's only particularly important if you have a _lot_ of them and they take a long time to run. Adding named unit tests and making it possible to call locate and call unit tests functions externally would make it possible to have an IDE or some other external tool deal with unit test successes and failures in a manner closer to what you're looking for, and I think that that sort of thing would be a definite step forward, but what we have works quite well. I think that extensions to it (like adding names to unit tests) would be great, but the only major change that I can think of which really needs to be made (rather than an extension) would be to make it so that all unittest blocks in a module run independently so that they all run regardless of whether any others fail (and I think that that change is supposed to be being done at some point). Making changes such as making unittest blocks print on success is not something that I would consider a good change (though making it possible wouldn't necessarily be bad).
 particularly when it's not all that hard
 to add code yourself which prints out success if you really want it to.
It's also not hard to define global functions, wrapped in a version(unittest){}, to replace the need of the unittest keyword (unittest becomes a version ID).
Almost, but not quite. -unittest also enables assertions if they would otherwise be disabled, which a simple version couldn't do. - Jonathan M Davis
Nov 16 2010
parent reply Don <nospam nospam.com> writes:
Jonathan M Davis wrote:
 On Tuesday, November 16, 2010 13:33:54 bearophile wrote:
 Jonathan M Davis:
 Most of the rest (if not all of it) could indeed be done in a library.
I am not sure it could be done nicely too :-)
That would depend on what you're trying to do. Printing test success or failure is as simple as adding the approprate scope statement to the beginning of each unittest block. A bit tedious perhaps, but not hard.
 Right now
 unit tests follow the unix convention of saying nothing on success,
That's an usability failure. Humans expect feedback, because you can't tell apart "unittests run and succeed" from "unittests not even run". That Unix convention is bad here. And Unix commands sometimes have a -v (verbose) command that gives feedback, while D unittests don't have this option.
I'm afraid that I have to disagree there. Having all of the successes print out would, in many cases, just be useless output flooding the console. I have no problem with making it possible for unit tests to report success, but I wouldn't want that to be the default. It's quite clear when a test fails, and that's what is necessary in order to fix test failures. I can see why a beginner might want the positive feedback that a test has succeeded, but personally, I would just find it annoying. The only real advantage would be that it would indicate where in the unit tests the program was, and that's only particularly important if you have a _lot_ of them and they take a long time to run.
I think: "%d unit tests passed in %d modules" would be enough.
Nov 18 2010
parent reply Fawzi Mohamed <fawzi gmx.ch> writes:
On 18-nov-10, at 09:11, Don wrote:

 Jonathan M Davis wrote:
 On Tuesday, November 16, 2010 13:33:54 bearophile wrote:
 Jonathan M Davis:
 Most of the rest (if not all of it) could indeed be done in a  
 library.
I am not sure it could be done nicely too :-)
That would depend on what you're trying to do. Printing test success or failure is as simple as adding the approprate scope statement to the beginning of each unittest block. A bit tedious perhaps, but not hard.
 Right now
 unit tests follow the unix convention of saying nothing on success,
That's an usability failure. Humans expect feedback, because you can't tell apart "unittests run and succeed" from "unittests not even run". That Unix convention is bad here. And Unix commands sometimes have a -v (verbose) command that gives feedback, while D unittests don't have this option.
I'm afraid that I have to disagree there. Having all of the successes print out would, in many cases, just be useless output flooding the console. I have no problem with making it possible for unit tests to report success, but I wouldn't want that to be the default. It's quite clear when a test fails, and that's what is necessary in order to fix test failures. I can see why a beginner might want the positive feedback that a test has succeeded, but personally, I would just find it annoying. The only real advantage would be that it would indicate where in the unit tests the program was, and that's only particularly important if you have a _lot_ of them and they take a long time to run.
I think: "%d unit tests passed in %d modules" would be enough.
This was already discussed, I think that optimal solution would be to have a testing function a bit like tangos, the testing functions knows how the module is called. Tango one always prints the module, but that is easy to change. What I use is my own testing framework, in it i have defined as default main function that checks commandline arguments, so that one can for example pass --print-level=error and see only the errors... See http://dsource.org/projects/blip/wiki/BlipOverview for an example of using it. This means having a special file to compile, that generates an executable dedicated to testing, but this maps well to how I do tests. In fact I often keep the tests separated from the code, I even hide them behind templates to avoid excessive template instantiation in some cases because they are large and would slow down the compilation... The current default unittest function runs very early (before main), so it is not possible to use that and use commandline arguments (which is "correct" because in the current model unittests can be activated for *any* executable, and should not disturb its run). It should be possible to write a test function that just sets up things for a later real unittest run that starts from main and can parse the commandline arguments, thus solving all these discussions... Fawzi
Nov 18 2010
parent Sean Kelly <sean invisibleduck.org> writes:
Fawzi Mohamed <fawzi gmx.ch> wrote:
 On 18-nov-10, at 09:11, Don wrote:
 
 Jonathan M Davis wrote:
 On Tuesday, November 16, 2010 13:33:54 bearophile wrote:
 Jonathan M Davis:
 Most of the rest (if not all of it) could indeed be done in a 
 library.
I am not sure it could be done nicely too :-)
That would depend on what you're trying to do. Printing test >> success or failure is as simple as adding the approprate scope >> statement to the beginning of each unittest block. A bit tedious
 perhaps, but not hard.
 Right now
 unit tests follow the unix convention of saying nothing on
 success,
That's an usability failure. Humans expect feedback, because you
 can't tell
apart "unittests run and succeed" from "unittests not even run".
 That Unix
convention is bad here. And Unix commands sometimes have a -v >>> (verbose) command that gives feedback, while D unittests don't have this >>> option.
I'm afraid that I have to disagree there. Having all of the >> successes print out would, in many cases, just be useless output
 flooding the console. I have no problem with making it possible
 for  >> unit tests to report success, but I wouldn't want that
 to be the  >> default. It's quite clear when a test fails, and
 that's what is  >> necessary in order to fix test failures.
I can see why a beginner might want the positive feedback that a >> test has succeeded, but personally, I would just find it annoying. >> The only real advantage would be that it would indicate where in >> the unit tests the program was, and that's only particularly >> important if you have a _lot_ of them and they take a long time to >> run.
I think: "%d unit tests passed in %d modules" would be enough.
This was already discussed, I think that optimal solution would be to have a testing function a bit like tangos, the testing functions knows how the module is called. Tango one always prints the module, but that is easy to change. What I use is my own testing framework, in it i have defined as default main function that checks commandline arguments, so that one can for example pass --print-level=error and see only the errors... See http://dsource.org/projects/blip/wiki/BlipOverview for an example of using it. This means having a special file to compile, that generates an executable dedicated to testing, but this maps well to how I do tests. In fact I often keep the tests separated from the code, I even hide them behind templates to avoid excessive template instantiation in some cases because they are large and would slow down the compilation... The current default unittest function runs very early (before main), so it is not possible to use that and use commandline arguments (which is "correct" because in the current model unittests can be activated for *any* executable, and should not disturb its run). It should be possible to write a test function that just sets up things for a later real unittest run that starts from main and can parse the commandline arguments, thus solving all these discussions...
You can access the commandline args via Runtime.args. This works within unittests.
Nov 21 2010
prev sibling parent reply Lutger Blijdestijn <lutger.blijdestijn gmail.com> writes:
bearophile wrote:

 Jonathan M Davis:
 
 Most of the rest (if not all of it) could indeed be done in a library.
I am not sure it could be done nicely too :-)
 Right now
 unit tests follow the unix convention of saying nothing on success,
That's an usability failure. Humans expect feedback, because you can't tell apart "unittests run and succeed" from "unittests not even run". That Unix convention is bad here. And Unix commands sometimes have a -v (verbose) command that gives feedback, while D unittests don't have this option.
Actually the unix convention is to give exit code 0 as an indicator of success, so there is feedback. It is very usable for scripting. But with the change Sean suggested - and I assume an extension point in druntime - there would be enough for a more human friendly tool to be built on top of the current D unittesting system.
 particularly when it's not all that hard
 to add code yourself which prints out success if you really want it to.
It's also not hard to define global functions, wrapped in a version(unittest){}, to replace the need of the unittest keyword (unittest becomes a version ID). Bye, bearophile
Nov 17 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Lutger Blijdestijn:

 Actually the unix convention is to give exit code 0 as an indicator of 
 success, so there is feedback. It is very usable for scripting.
But currently something like that is not present in the D unittest system.
 But with the 
 change Sean suggested - and I assume an extension point in druntime - there 
 would be enough for a more human friendly tool to be built on top of the 
 current D unittesting system.
We'll see. Bye, bearophile
Nov 17 2010
next sibling parent Lutger Blijdestijn <lutger.blijdestijn gmail.com> writes:
bearophile wrote:

 Lutger Blijdestijn:
 
 Actually the unix convention is to give exit code 0 as an indicator of
 success, so there is feedback. It is very usable for scripting.
But currently something like that is not present in the D unittest system.
rdmd --main -unittest somemodule.d
Nov 17 2010
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
bearophile wrote:
 Lutger Blijdestijn:
 
 Actually the unix convention is to give exit code 0 as an indicator of 
 success, so there is feedback. It is very usable for scripting.
But currently something like that is not present in the D unittest system.
Yes, it is. Unit test failures return a non-zero exit code.
Nov 26 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter:

 Yes, it is. Unit test failures return a non-zero exit code.
I see, good. But real unit test systems don't just return that value, they give a more visible feedback, like the number of failed/passed tests. One line of text that shows those numbers is a good start. Bye, bearophile
Nov 26 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
 But real unit test systems don't just return that value, they give a more
visible feedback, like the number of failed/passed tests. One line of text that
shows those numbers is a good start.
Or maybe that's not the job of a compiler... Bye, bearophile
Nov 26 2010
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 26 November 2010 17:17:56 bearophile wrote:
 Walter:
 Yes, it is. Unit test failures return a non-zero exit code.
I see, good. But real unit test systems don't just return that value, they give a more visible feedback, like the number of failed/passed tests. One line of text that shows those numbers is a good start.
I'm a firm believer that D unit tests should not change how they fundamentally work at this point. I don't _want_ it to report the number of tests that passed. That information is not at all useful. And if I want to do something like set up something to run dmd periodically and report only when the tests start failing, then the current situation is perfect. I _do_ think that the unit testing stuff should be expanded to have named unit tests and do whatever is necessary to make it possible for external tools to run the unit tests. Then you could have an external tool that did things like only run specific unit tests and report which tests succeeded and which failed. So, I do think that it should be possible to build external tools on D's unit testing framework, but I think that it's quite good as it is now, and I wouldn't want to see it drastically changed. The two changes that I want to see to the current framework are 1. Make it so that every unittest block runs in a module instead of them stopping once one failed. The current situation is better than stopping _all_ unittest blocks once a single test fails, but it's still not granular enough. I believe that this change is planned, but work has to be done to make it possible, and that work hasn't been done yet. 2. Make it possible to name unittest blocks. This would make exceptions that escape unittest blocks _far_ more useful. Names like unittest45 really aren't useful at all. I can't even figure out how it does the numbering. Also, having named unittest blocks would be a necessity for properly allowing external tools to run the unit tests. I do _not_ want to see D programs printing out anything more than they do when running unit tests. I'm totally open to external tools which do more (it would particularly good for IDEs to be able to run unittest blocks individually), but I do not want to see the basic framework change how it prints feedback on test successes and failures. It works great as it is now. - Jonathan M Davis
Nov 26 2010
parent reply Walter Bright <newshound2 digitalmars.com> writes:
Jonathan M Davis wrote:
 I'm a firm believer that D unit tests should not change how they fundamentally 
 work at this point. I don't _want_ it to report the number of tests that
passed. 
That's right. The number that fail is completely useless window dressing.
 That information is not at all useful. And if I want to do something like set
up 
 something to run dmd periodically and report only when the tests start
failing, 
 then the current situation is perfect.
 
 I _do_ think that the unit testing stuff should be expanded to have named unit 
 tests and do whatever is necessary to make it possible for external tools to
run 
 the unit tests. Then you could have an external tool that did things like only 
 run specific unit tests and report which tests succeeded and which failed.
 
 So, I do think that it should be possible to build external tools on D's unit 
 testing framework, but I think that it's quite good as it is now, and I
wouldn't 
 want to see it drastically changed.
 
 The two changes that I want to see to the current framework are
 
 1. Make it so that every unittest block runs in a module instead of them 
 stopping once one failed. The current situation is better than stopping _all_ 
 unittest blocks once a single test fails, but it's still not granular enough.
I 
 believe that this change is planned, but work has to be done to make it 
 possible, and that work hasn't been done yet.
I believe that is the current behavior. For a time, it kept getting broken by changes to druntime, so it may be broken yet again, but that is the way it is supposed to work.
 2. Make it possible to name unittest blocks. This would make exceptions that 
 escape unittest blocks _far_ more useful. Names like unittest45 really aren't 
 useful at all. I can't even figure out how it does the numbering.
If the line numbers given out are incorrect, those are compiler bugs and I'd like to get them fixed.
 Also, having named unittest blocks would be a necessity for properly allowing 
external tools to run the unit tests. I don't really know how that would work.
 I do _not_ want to see D programs printing out anything more than they do when 
 running unit tests. I'm totally open to external tools which do more (it would 
 particularly good for IDEs to be able to run unittest blocks individually),
but 
 I do not want to see the basic framework change how it prints feedback on test 
 successes and failures. It works great as it is now.
Yes, and if anyone wants more, a writefln("your message here") works just fine.
Nov 26 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 26 November 2010 18:52:59 Walter Bright wrote:
 Jonathan M Davis wrote:
 I'm a firm believer that D unit tests should not change how they
 fundamentally work at this point. I don't _want_ it to report the number
 of tests that passed.
That's right. The number that fail is completely useless window dressing.
 That information is not at all useful. And if I want to do something like
 set up something to run dmd periodically and report only when the tests
 start failing, then the current situation is perfect.
 
 I _do_ think that the unit testing stuff should be expanded to have named
 unit tests and do whatever is necessary to make it possible for external
 tools to run the unit tests. Then you could have an external tool that
 did things like only run specific unit tests and report which tests
 succeeded and which failed.
 
 So, I do think that it should be possible to build external tools on D's
 unit testing framework, but I think that it's quite good as it is now,
 and I wouldn't want to see it drastically changed.
 
 The two changes that I want to see to the current framework are
 
 1. Make it so that every unittest block runs in a module instead of them
 stopping once one failed. The current situation is better than stopping
 _all_ unittest blocks once a single test fails, but it's still not
 granular enough. I believe that this change is planned, but work has to
 be done to make it possible, and that work hasn't been done yet.
I believe that is the current behavior. For a time, it kept getting broken by changes to druntime, so it may be broken yet again, but that is the way it is supposed to work.
It's not. This program import std.stdio; bool func() { return false; } void main() { } unittest { writeln("test 1"); assert(func()); } unittest { writeln("test 2"); } prints test 1 core.exception.AssertError test(15): unittest failure ---------------- ./test(onAssertErrorMsg+0x34) [0x808c0f4] ./test(onUnittestErrorMsg+0x18) [0x807f3b8] ./test(_d_unittestm+0x22) [0x807d252] ./test(void test.__unittest_fail(int)) [0x807acfa] ./test(void test.__unittest1()) [0x807ac3b] ./test(void test.__modtest()) [0x807ace0] ./test(extern (C) bool core.runtime.runModuleUnitTests()) [0x807f56c] ./test(_D6object10ModuleInfo7opApplyFMDFKPS6object10ModuleInfoZiZi+0x41) [0x807cd7d] ./test(runModuleUnitTests+0x87) [0x807f487] ./test(extern (C) int rt.dmain2.main(int, char**)) [0x807d448] ./test(extern (C) int rt.dmain2.main(int, char**)) [0x807d370] ./test(main+0x96) [0x807d316] /usr/lib32/libc.so.6(__libc_start_main+0xe6) [0xf75b7c76] ./test() [0x807ab51] The second unittest block is never run. I believe that the last time that this got discussed on the Phobos list, Sean said that some fundamental changes had to be made to either dmd or druntime (I _think_ it was dmd, but I'm not sure) to make it possible to run subsequent unit tests in a module after one of them has failed. If a test in a module fails, then the tests in other modules run, but not the rest of the tests in the module that had the failure.
 2. Make it possible to name unittest blocks. This would make exceptions
 that escape unittest blocks _far_ more useful. Names like unittest45
 really aren't useful at all. I can't even figure out how it does the
 numbering.
If the line numbers given out are incorrect, those are compiler bugs and I'd like to get them fixed.
Not the line number. I'm talking about the function name that you get stack traces. Take this program for instance: void func() { throw new Exception("An exception threw."); } void main() { } unittest { func(); } If you run the unit tests, you get object.Exception: An exception threw. ---------------- ./test(void test.func()) [0x80599fe] ./test(void test.__unittest1()) [0x8059a10] ./test(void test.__modtest()) [0x8059a1c] ./test(extern (C) bool core.runtime.runModuleUnitTests()) [0x805dcdc] ./test(_D6object10ModuleInfo7opApplyFMDFKPS6object10ModuleInfoZiZi+0x41) [0x805ba9d] ./test(runModuleUnitTests+0x87) [0x805dbf7] ./test(extern (C) int rt.dmain2.main(int, char**)) [0x805c168] ./test(extern (C) int rt.dmain2.main(int, char**)) [0x805c090] ./test(main+0x96) [0x805c036] /usr/lib32/libc.so.6(__libc_start_main+0xe6) [0xf7595c76] ./test() [0x8059921] Notic __unittest1(). Here, there's only one unit test, so it's not a big deal, but once you have a lot of them, it's not really feasible to associate that function name with a unittest block. If the unittest blocks were named, something like this unitest(mytest) { } then you could get a stack trace like this object.Exception: An exception threw. ---------------- ./test(void test.func()) [0x80599fe] ./test(void test.__unittest_mytest()) [0x8059a10] ./test(void test.__modtest()) [0x8059a1c] ./test(extern (C) bool core.runtime.runModuleUnitTests()) [0x805dcdc] ./test(_D6object10ModuleInfo7opApplyFMDFKPS6object10ModuleInfoZiZi+0x41) [0x805ba9d] ./test(runModuleUnitTests+0x87) [0x805dbf7] ./test(extern (C) int rt.dmain2.main(int, char**)) [0x805c168] ./test(extern (C) int rt.dmain2.main(int, char**)) [0x805c090] ./test(main+0x96) [0x805c036] /usr/lib32/libc.so.6(__libc_start_main+0xe6) [0xf7595c76] ./test() [0x8059921] With that stack trace, I can easily determine which test threw the exception. It's not a problem with assertions within the test - since they'll give the file and line number of the assertion in the test - but if any function called by the test throws an exception for whatever reason (including assertions in contracts), then you get a stack trace that borders on useless, because you can't easily determine which unittest block threw the exception. With named unittest blocks, that problem can be fixed. As it stands, I don't even know how the number for the unittest is picked. It does not appear that __unittestX() necessarily corresponds to the Xth unit test in a module lexographically. Named unit tests are really the way that the problem should be fixed. I'm not saying that naming unittest blocks should be mandatory, but I think that it should be possible. Unnamed unittest blocks result in functions with names like __unittest1() like they do now, whereas named unittest blocks would result in names like __unittest_testname() where testname is the name of the unittest block. It would make stack traces far easier to deal with, and if external tools are ever going to have any hope of calling unit test functions, then I think that it's a necessity
  > Also, having named unittest blocks would be a necessity for properly
  > allowing
 
 external tools to run the unit tests.
 
 I don't really know how that would work.
I'm not sure either. But ideally, it would be possible to have an external tool run a program which runs all of the static constructors and whatever else has to be run before the unittest blocks can run, and then specifically run each unittest block that it wants to, in whatever order it wants to, without necessarily running all of them. For instance, if you use JUnit with Eclipse, you can tell it to specifically run all of the unit tests in a file. Or you can tell it to run only a single unit test. Or you can tell it to run them all. Right now, with D, you can only ever run them all, and you can't really integrate them into an IDE. I think that that should become possible at some point. Unfortunately, however, I don't know enough to say exactly how that would work. I don't even know how it works with JUnit and Eclipse. It is potentially a very important feature though.
 I do _not_ want to see D programs printing out anything more than they do
 when running unit tests. I'm totally open to external tools which do
 more (it would particularly good for IDEs to be able to run unittest
 blocks individually), but I do not want to see the basic framework
 change how it prints feedback on test successes and failures. It works
 great as it is now.
Yes, and if anyone wants more, a writefln("your message here") works just fine.
Yes. It is a bit of work to make all of your unit tests print success or failure, but it's not hard, just tedious. I see no reason to make everyone have to put up with extraneous output just because some people want it to print a list of successes and failures. If you really want that, you can do it yourself. The one part I can think of that you can't do yourself very well is print the total number of successes and failures (unless you print a running total with each test). But it's possible to build printing functionality on top of a framework that only prints out on failure, whereas it's not possible to get rid of printing with a framework that always prints. - Jonathan M Davis
Nov 26 2010
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
bearophile wrote:
 Walter:
 
 Yes, it is. Unit test failures return a non-zero exit code.
I see, good.
I wish you'd check these things before confidently posting incorrect assertions about how D behaves.
Nov 26 2010