Thread: [Perlunit-devel] Problem with namespace
Status: Beta
Brought to you by:
mca1001
From: jonasbn <jo...@wa...> - 2002-02-21 21:45:36
Attachments:
TestCase.pm.patch
|
As promised - my example: package Class::EmployeeTest; use strict; use vars qw(@ISA); use base qw(Test::Unit::TestCase); sub new { my $self = shift()->SUPER::new(@_); $self->{'_name'} = ''; $self->{'_department'} = ''; return $self; } sub set_up { my $self = shift; $self->{'_name'} = 'Arne Raket'; $self->{'_department'} = 'dA pErl lAb'; } sub test_name { my $self = shift; my $name = $self->{_name}; $self->assert($name eq 'Arne Raket'); } sub test_department { my $self = shift; my $department = $self->{'_department'}; $self->assert($department eq 'dA pErl lAb'); } 1; The name (_name) field clashes, I guess that name is probably the most used field in OOP. It should therefore not be used in Test::Unit::TestCase. I have made a brief workaround (see the attached patch). Changing the internal field to Test::Unit::TestCase::_name_of_test is not a valid solution though :-/ So a proper namespace protection scheme should be implemented. I have tried to fool around with this (using Tie::Securehash) without any luck, since the Assert.pm tries to access the _no_backtrace_on_fail at runtime. Either the component structure should be change or a different scheme should be chosen. jonasbn -- Eml: jo...@wa... || ICQ: 62401545 WWW: http://jonasbn.hjem.wanadoo.dk/ |
From: Adam S. <ad...@sp...> - 2002-03-04 14:38:40
|
jonasbn (jo...@wa...) wrote: > The name (_name) field clashes, I guess that name is probably the most used > field in OOP. It should therefore not be used in Test::Unit::TestCase. You're quite right. Thanks for pointing this out. > Changing the internal field to Test::Unit::TestCase::_name_of_test is not a > valid solution though :-/ > > So a proper namespace protection scheme should be implemented. I have tried to > fool around with this (using Tie::Securehash) without any luck, since the > Assert.pm tries to access the _no_backtrace_on_fail at runtime. > > Either the component structure should be change or a different scheme should be chosen. This is one of the nasty things about perl. However, I think the solution suggested by perlobj ($self->{__PACKAGE__ . '_foo'}) is good enough, so I've just committed a general fix which adopts this convention for TestCase objects. Actually, now I've committed it, it occurs to me that $self->{__PACKAGE__}{foo} is an even nicer convention, but I can't be bothered to change it again now :-) |
From: Matthias F. <mf...@hi...> - 2002-03-18 06:03:34
|
Er, question first, shall we? I wonder if you have a recommendation for how to approach the problem I'm trying to solve, given PerlUnit's current architecture. I want to be able to start a TestRunner running against a dynamically generated suite, where the suite itself is determined by the command line. So, for instance, I imagine the command line looking something like this: perl TestRunner.pl MyTestMaker arg1 arg2.... where MyTestMaker has a suite() method that uses the arguments to generate the appropriate test suite. The thing is, there's no way for MyTestMaker to get access to the arguments, because they're all eaten up by TestRunner and not passed along. Is there another way (a "right" way) to do this? My solution so far is to bypass TestRunner.pl, instead using a script that generates the test suite, creates a new TestRunner object and starts it running with the constructed suite. The two things I don't like about this are that it relies on the TestRunner::do_run() method, which I'm not sure is a public part of the API, and that I'd rather use TestRunner.pl if at all possible. Any suggestions? OK, now my own small suggestion. I was confused at first when a Boolean assertion failed with the message "Expected TRUE, got FALSE." Seems to me that a Boolean test doesn't have an expected value the way an equality assertion does; how about changing the message to "Assertion failed"? -- Matthias |
From: Adam S. <ad...@sp...> - 2002-03-18 14:28:08
|
Matthias Ferber (mf...@hi...) wrote: > Er, question first, shall we? I wonder if you have a recommendation for > how to approach the problem I'm trying to solve, given PerlUnit's current > architecture. I want to be able to start a TestRunner running against a > dynamically generated suite, where the suite itself is determined by the > command line. > > So, for instance, I imagine the command line looking something like this: > > perl TestRunner.pl MyTestMaker arg1 arg2.... > > where MyTestMaker has a suite() method that uses the arguments to generate > the appropriate test suite. The thing is, there's no way for MyTestMaker > to get access to the arguments, because they're all eaten up by TestRunner > and not passed along. Is there another way (a "right" way) to do this? > > My solution so far is to bypass TestRunner.pl, instead using a script that > generates the test suite, creates a new TestRunner object and starts it > running with the constructed suite. The two things I don't like about > this are that it relies on the TestRunner::do_run() method, which I'm not > sure is a public part of the API, and that I'd rather use TestRunner.pl if > at all possible. Any suggestions? I think you've done the right thing (in the context of the current PerlUnit tree, at least), and that do_run() should be part of the public API. If you wanted to extend the argument syntax of TestRunner.pl to allow parameters to be passed to tests, feel free to post a proposed syntax here. It looks like this part of PerlUnit needs a bit of a spring-clean; for instance, I can't see anything that uses TestRunner::run() or TestRunner::run_and_wait(). I'll add this to the TODO list. > OK, now my own small suggestion. I was confused at first when a Boolean > assertion failed with the message "Expected TRUE, got FALSE." Seems to me > that a Boolean test doesn't have an expected value the way an equality > assertion does; how about changing the message to "Assertion failed"? I've changed it to "Boolean assertion failed". -- Adam Spiers -=- musician & hacker -- ad...@sp... -=- http://tigerpig.org/ $_=q{*{$Just =bless{},'$another ';"\$Perl \::$hacker"}=sub{print$%[$.++];$,,$ ;$_[0]},eval join+v45.62,('$z')x6};s/(?<=\$)([a-z\n]+ ?)/push@%,$+;f/egi;eval |
From: Matthias F. <mf...@hi...> - 2002-03-18 18:26:56
|
Thanks for the help, Adam, that's reassuring. I'm not actually sure whether the syntax I showed as an example would be the best interpretation in practice, actually. Right now, if I'm reading the code right, TestRunner::start() ignores all but the last argument (not counting switches). I can see two reasonable ways to change that: one is to take the first non-switch argument as the name of the class to build a suite from and pass the remaining arguments to its constructor, which would handle the situation I'm working on and would look like my example; the other thing it could do is interpret all the arguments as separate test classes, and build a suite combining the suites from each of those classes. I like the first idea because it adds flexibility in situations like mine, but the second is perhaps more intuitive and maybe even more useful most of the time. So I think I'll just throw these both out as possibilities for thought and let 'em fall where they may. Re TestRunner.pm, if you're going to clean up that part of the code anyway, and if do_run() is going to be public, may I suggest naming it run_suite() instead for clarity? Thanks, Matthias On Mon, 18 Mar 2002, Adam Spiers wrote: > Matthias Ferber (mf...@hi...) wrote: > > Er, question first, shall we? I wonder if you have a recommendation for > > how to approach the problem I'm trying to solve, given PerlUnit's current > > architecture. I want to be able to start a TestRunner running against a > > dynamically generated suite, where the suite itself is determined by the > > command line. > > > > So, for instance, I imagine the command line looking something like this: > > > > perl TestRunner.pl MyTestMaker arg1 arg2.... > > > > where MyTestMaker has a suite() method that uses the arguments to generate > > the appropriate test suite. The thing is, there's no way for MyTestMaker > > to get access to the arguments, because they're all eaten up by TestRunner > > and not passed along. Is there another way (a "right" way) to do this? > > > > My solution so far is to bypass TestRunner.pl, instead using a script that > > generates the test suite, creates a new TestRunner object and starts it > > running with the constructed suite. The two things I don't like about > > this are that it relies on the TestRunner::do_run() method, which I'm not > > sure is a public part of the API, and that I'd rather use TestRunner.pl if > > at all possible. Any suggestions? > > I think you've done the right thing (in the context of the current > PerlUnit tree, at least), and that do_run() should be part of the > public API. If you wanted to extend the argument syntax of > TestRunner.pl to allow parameters to be passed to tests, feel free to > post a proposed syntax here. > > It looks like this part of PerlUnit needs a bit of a spring-clean; for > instance, I can't see anything that uses TestRunner::run() or > TestRunner::run_and_wait(). I'll add this to the TODO list. > > > OK, now my own small suggestion. I was confused at first when a Boolean > > assertion failed with the message "Expected TRUE, got FALSE." Seems to me > > that a Boolean test doesn't have an expected value the way an equality > > assertion does; how about changing the message to "Assertion failed"? > > I've changed it to "Boolean assertion failed". > > -- > Adam Spiers -=- musician & hacker -- ad...@sp... -=- http://tigerpig.org/ > $_=q{*{$Just =bless{},'$another ';"\$Perl \::$hacker"}=sub{print$%[$.++];$,,$ > ;$_[0]},eval join+v45.62,('$z')x6};s/(?<=\$)([a-z\n]+ ?)/push@%,$+;f/egi;eval > > _______________________________________________ > Perlunit-devel mailing list > Per...@li... > https://lists.sourceforge.net/lists/listinfo/perlunit-devel > |
From: Adam S. <ad...@sp...> - 2002-06-20 15:28:11
|
Matthias Ferber (mf...@hi...) wrote: > Thanks for the help, Adam, that's reassuring. I'm not actually sure > whether the syntax I showed as an example would be the best interpretation > in practice, actually. Right now, if I'm reading the code right, > TestRunner::start() ignores all but the last argument (not counting > switches). I can see two reasonable ways to change that: one is to take > the first non-switch argument as the name of the class to build a suite > from and pass the remaining arguments to its constructor, which would > handle the situation I'm working on and would look like my example; the > other thing it could do is interpret all the arguments as separate test > classes, and build a suite combining the suites from each of those > classes. > > I like the first idea because it adds flexibility in situations like mine, > but the second is perhaps more intuitive and maybe even more useful most > of the time. So I think I'll just throw these both out as possibilities > for thought and let 'em fall where they may. I've been wanting more control from the command-line recently too, which has been a good reason to get off my butt and reply to your mail. More specifically, I want to be able to control which test methods in a suite get run by passing them as arguments. The immediate problem for me is that I have an equivalent of TestRunner.pl which allows running of several suites at once, e.g. $ ./MyTestRunner.pl MySuite1 MySuite2 but allowing arguments to a suite would break that. One approach I thought of was using '--' to delimit the tests: $ ./TestRunner.pl --switch MyTest1 arg1a arg1b -- MyTest2 arg2a arg2b How does that sound? It occurs to me that I should probably merge all my runner's enhancements back into TestRunner.pl; the latter is a rather lame piece of code as it stands. > Re TestRunner.pm, if you're going to clean up that part of the code > anyway, and if do_run() is going to be public, may I suggest naming it > run_suite() instead for clarity? Good idea; added to doc/TODO. |
From: Matthias F. <mf...@hi...> - 2002-06-20 21:03:28
|
I built a script that did something like this for JUnit in Java -- the part about controlling which test methods get run, that is, not the part about passing arguments, which may be impossible in Java anyway. I used colons as a delimiter: java TestRunner class1:test1 class2:test2... The colon would be awkward in Perl because it's also used in the class delimiter, but another symbol could work: perl TestRunner.pl My::Class1.method1 My::Class2.method2 You could extend that to passing arguments, except then you have trouble if the argument contains a period (or whatever delimiter). This isn't a wholly thought out idea yet, but what I like about it versus passing the method names as arguments is that it can be combined with passing real arguments. I'm not sure that holds water yet, though, and the method-names-as-arguments idea has the great advantage of being intuitive (perhaps except for the --, but that doesn't seem so bad to me). I'm going to try to come up with more ideas and bat this around a little more. Here's one off the cuff: perl TestRunner.pl -switches My::ClassA -m method1 -m method2 My::ClassB to test two methods from ClassA and all of ClassB. still thinking... Matthias On Thu, 20 Jun 2002, Adam Spiers wrote: > Matthias Ferber (mf...@hi...) wrote: > > Thanks for the help, Adam, that's reassuring. I'm not actually sure > > whether the syntax I showed as an example would be the best interpretation > > in practice, actually. Right now, if I'm reading the code right, > > TestRunner::start() ignores all but the last argument (not counting > > switches). I can see two reasonable ways to change that: one is to take > > the first non-switch argument as the name of the class to build a suite > > from and pass the remaining arguments to its constructor, which would > > handle the situation I'm working on and would look like my example; the > > other thing it could do is interpret all the arguments as separate test > > classes, and build a suite combining the suites from each of those > > classes. > > > > I like the first idea because it adds flexibility in situations like mine, > > but the second is perhaps more intuitive and maybe even more useful most > > of the time. So I think I'll just throw these both out as possibilities > > for thought and let 'em fall where they may. > > I've been wanting more control from the command-line recently too, > which has been a good reason to get off my butt and reply to your mail. > More specifically, I want to be able to control which test methods in > a suite get run by passing them as arguments. The immediate problem > for me is that I have an equivalent of TestRunner.pl which allows > running of several suites at once, e.g. > > $ ./MyTestRunner.pl MySuite1 MySuite2 > > but allowing arguments to a suite would break that. One approach I > thought of was using '--' to delimit the tests: > > $ ./TestRunner.pl --switch MyTest1 arg1a arg1b -- MyTest2 arg2a arg2b > > How does that sound? > > It occurs to me that I should probably merge all my runner's > enhancements back into TestRunner.pl; the latter is a rather lame > piece of code as it stands. > > > Re TestRunner.pm, if you're going to clean up that part of the code > > anyway, and if do_run() is going to be public, may I suggest naming it > > run_suite() instead for clarity? > > Good idea; added to doc/TODO. > > > ------------------------------------------------------- > Bringing you mounds of caffeinated joy > >>> http://thinkgeek.com/sf <<< > > _______________________________________________ > Perlunit-devel mailing list > Per...@li... > https://lists.sourceforge.net/lists/listinfo/perlunit-devel > |
From: Adam S. <ad...@sp...> - 2002-06-21 11:26:34
|
Matthias Ferber (mf...@hi...) wrote: > I built a script that did something like this for JUnit in Java -- the > part about controlling which test methods get run, that is, not the part > about passing arguments, which may be impossible in Java anyway. I used > colons as a delimiter: > > java TestRunner class1:test1 class2:test2... > > The colon would be awkward in Perl because it's also used in the class > delimiter, but another symbol could work: > > perl TestRunner.pl My::Class1.method1 My::Class2.method2 That's quite nice. > You could extend that to passing arguments, except then you have trouble > if the argument contains a period (or whatever delimiter). > > This isn't a wholly thought out idea yet, but what I like about it versus > passing the method names as arguments is that it can be combined with > passing real arguments. I'm not sure that holds water yet, though, and > the method-names-as-arguments idea has the great advantage of being > intuitive (perhaps except for the --, but that doesn't seem so bad to > me). I'm going to try to come up with more ideas and bat this around a > little more. > > Here's one off the cuff: > > perl TestRunner.pl -switches My::ClassA -m method1 -m method2 My::ClassB > > to test two methods from ClassA and all of ClassB. or perl TestRunner.pl -switches My::ClassA ::method1 ::method2 My::ClassB It all depends on whether we want to allow arguments other than methods. I don't need them myself (yet) but I guess we do want to allow them. The other question is whether switches should apply globally or be allowed as sort of local modifiers for each class, although there's a danger we're thinking too far ahead here. |