Re: selectively running unittest functions
26-Oct-2013 02:36, Daniel Davidson пишет: On Friday, 25 October 2013 at 16:43:23 UTC, Daniel Davidson wrote: On Friday, 25 October 2013 at 14:14:39 UTC, Dicebot wrote: This will work starting with 2.064: Ok. I'll keep pressing. Here is an updated version: http://pastebin.com/g6FWsTkr The idea is to be able to just import ut, annotate as you have described and get unit tests run. I want to mixin the equivalent of your main in each module that just pulls in a module constructors to evaluate what tests are there. The code in the paste crashes on the call to getUnitests. If I comment out `alias tests = TypeTuple!(__traits(getUnitTests, mod));` then I see similar call to `alias members = TypeTuple!(__traits(allMembers, mod));` work just fine. Is this the right way to use this? Any pointers on the segmentation fault? Thanks Dan Ok, binary reduction has shown the seg fault was due to a debug import. It's a bug so please file it in bugzilla. Don't let them go unnoticed ;) http://d.puremagic.com/issues/ This code causes a crash for me - just because of the getUnittests. If I remove the debug import it works. Since I use debug imports in general, I'm not so sure it is worthwhile to pursue the named unit test approach at this time. import std.typetuple; import std.stdio; debug import std.datetime; unittest { writeln(In Test!!); } mixin(alias mod = ~ __MODULE__ ~ ;); alias tests = TypeTuple!(__traits(getUnitTests, mod)); static this() { writeln(Done); } Thanks Dan -- Dmitry Olshansky
Re: selectively running unittest functions
On Saturday, 26 October 2013 at 08:09:26 UTC, Dmitry Olshansky wrote: 26-Oct-2013 02:36, Daniel Davidson пишет: On Friday, 25 October 2013 at 16:43:23 UTC, Daniel Davidson wrote: On Friday, 25 October 2013 at 14:14:39 UTC, Dicebot wrote: This will work starting with 2.064: Ok. I'll keep pressing. Here is an updated version: http://pastebin.com/g6FWsTkr The idea is to be able to just import ut, annotate as you have described and get unit tests run. I want to mixin the equivalent of your main in each module that just pulls in a module constructors to evaluate what tests are there. The code in the paste crashes on the call to getUnitests. If I comment out `alias tests = TypeTuple!(__traits(getUnitTests, mod));` then I see similar call to `alias members = TypeTuple!(__traits(allMembers, mod));` work just fine. Is this the right way to use this? Any pointers on the segmentation fault? Thanks Dan Ok, binary reduction has shown the seg fault was due to a debug import. It's a bug so please file it in bugzilla. Don't let them go unnoticed ;) http://d.puremagic.com/issues/ Yes - I have.
Re: selectively running unittest functions
Here is a working solution: https://github.com/patefacio/d-help/blob/master/d-help/opmix/ut.d Currently it only pulls in unittests at the module level. I'm sure it will work on unittests scoped to structs/classes, I just need to figure out how to determine if a compile time named object is an aggregate, as __traits(getUnitTests, foo) will complain if foo is not a module or aggregate. With a source a.d and b.d like in: https://github.com/patefacio/d-help/blob/master/d-help/opmix/examples/ut/ it can pull out by module name and uda test name. It has a -s summary option as well. Here is sample output: http://pastebin.com/fYd7k1Kz Thanks Dan
Re: selectively running unittest functions
I strictly believe any unittest enhancing library must be built on top of existing unittest blocks using __traits(getUnittest) and be 100% compatible with normal `-unittest` mode
Re: selectively running unittest functions
On Friday, 25 October 2013 at 13:04:03 UTC, Dicebot wrote: I strictly believe any unittest enhancing library must be built on top of existing unittest blocks using __traits(getUnittest) and be 100% compatible with normal `-unittest` mode I don't disagree. What exactly does that mean and what would it look like? I'm not familiar with __traits(getUnittest). Is that something that could/should be used in what I'm doing? What I'm missing, and apparently others in the original thread, is a way to run tests selectively. It is difficult to do with unittest because they are not named. If there were a way to annotate the test and pull them out that way it would be great. Can it be done?
Re: selectively running unittest functions
On Friday, 25 October 2013 at 13:23:46 UTC, Daniel Davidson wrote: What I'm missing, and apparently others in the original thread, is a way to run tests selectively. It is difficult to do with unittest because they are not named. If there were a way to annotate the test and pull them out that way it would be great. Can it be done? You can completely re-implement default test by using runtime hook http://wiki.dlang.org/Runtime_Hooks (_d_unittest should do AFAIK) In that runner you can manually get all unittest blocks in the program as functions using __traits(getUnittest). One can make any custom decisions for running specific unittest blocks based on User-Defined Attributes attached to it. Benefit of this approach is that the very same tests remain runnable in traditional out-of-the-box way if you don't use that library runner. I remember Jacob Carlborg doing some experiments in that direction but did not track any further progress.
Re: selectively running unittest functions
On Friday, 25 October 2013 at 13:30:54 UTC, Dicebot wrote: You can completely re-implement default test by using runtime hook http://wiki.dlang.org/Runtime_Hooks (_d_unittest should do AFAIK) *default test runner
Re: selectively running unittest functions
On Friday, 25 October 2013 at 14:14:39 UTC, Dicebot wrote: This will work starting with 2.064: module a; import std.stdio; struct ID { string data; } @ID(one) unittest { writeln(1); } @ID(two) unittest { writeln(2); } void main() { import std.typetuple; alias tests = TypeTuple!( __traits(getUnitTests, a) ); foreach (test; tests) { foreach (uda; __traits(getAttributes, test)) { static if (is(typeof(uda) == ID)) { if (uda == ID(two)) test(); } } } } It will print stuff twice though because I didn't suppress native unittest runner. Didn't actually dwell deep into runtime hooks so don't know what is best way to do it (maybe we need one more enhancement for it) This is great. I love the unittest blocks and UDAs. This way I can still have very easy-entry (as in just write unittest {}) unittests while gaining the power of unittest frameworks. It's a hell of a lot better than having some class with attributes containing methods with attributes, containing parameters with attributes :) I'm developing RSI when writing tests in other languages. (In Java I develop RSI just declaring variables...)
Re: selectively running unittest functions
On Friday, 25 October 2013 at 13:04:03 UTC, Dicebot wrote: I strictly believe any unittest enhancing library must be built on top of existing unittest blocks using __traits(getUnittest) and be 100% compatible with normal `-unittest` mode I agree, this should be easy to implement. In my unit testing framework i could add support to run only unit tests of one particular module but in the future when the above is released it would be easy to add it on a per test basis.
Re: selectively running unittest functions
On Friday, 25 October 2013 at 15:55:11 UTC, Gary Willoughby wrote: For information how to implement your own unit test handler see the bottom of the report module here: https://github.com/nomad-software/dunit From there you can selectively run tests based on some outside criteria. I think the new trait will open up further possibilities too. After 2.064 is out and good support of attributed test blocks is added I really recommend to consider separating core modules that support it into Phobos proposal. Will need to convince some conservative guys this is actually needed, but I think it is doable :P
Re: selectively running unittest functions
For information how to implement your own unit test handler see the bottom of the report module here: https://github.com/nomad-software/dunit From there you can selectively run tests based on some outside criteria. I think the new trait will open up further possibilities too.
Re: selectively running unittest functions
On Friday, 25 October 2013 at 14:14:39 UTC, Dicebot wrote: This will work starting with 2.064: Ok. I'll keep pressing. Here is an updated version: http://pastebin.com/g6FWsTkr The idea is to be able to just import ut, annotate as you have described and get unit tests run. I want to mixin the equivalent of your main in each module that just pulls in a module constructors to evaluate what tests are there. The code in the paste crashes on the call to getUnitests. If I comment out `alias tests = TypeTuple!(__traits(getUnitTests, mod));` then I see similar call to `alias members = TypeTuple!(__traits(allMembers, mod));` work just fine. Is this the right way to use this? Any pointers on the segmentation fault? Thanks Dan
Re: selectively running unittest functions
On Friday, 25 October 2013 at 16:43:23 UTC, Daniel Davidson wrote: On Friday, 25 October 2013 at 14:14:39 UTC, Dicebot wrote: This will work starting with 2.064: Ok. I'll keep pressing. Here is an updated version: http://pastebin.com/g6FWsTkr The idea is to be able to just import ut, annotate as you have described and get unit tests run. I want to mixin the equivalent of your main in each module that just pulls in a module constructors to evaluate what tests are there. The code in the paste crashes on the call to getUnitests. If I comment out `alias tests = TypeTuple!(__traits(getUnitTests, mod));` then I see similar call to `alias members = TypeTuple!(__traits(allMembers, mod));` work just fine. Is this the right way to use this? Any pointers on the segmentation fault? Thanks Dan Ok, binary reduction has shown the seg fault was due to a debug import. This code causes a crash for me - just because of the getUnittests. If I remove the debug import it works. Since I use debug imports in general, I'm not so sure it is worthwhile to pursue the named unit test approach at this time. import std.typetuple; import std.stdio; debug import std.datetime; unittest { writeln(In Test!!); } mixin(alias mod = ~ __MODULE__ ~ ;); alias tests = TypeTuple!(__traits(getUnitTests, mod)); static this() { writeln(Done); } Thanks Dan