Re: C/C++ White-Box Unit Testing and Test::More

2004-06-28 Thread Adrian Howard
On 26 Jun 2004, at 12:51, Fergal Daly wrote:
On Fri, Jun 25, 2004 at 10:13:52PM +0100, Adrian Howard wrote:
[snip]
What xUnit gives you is a little bit more infrastructure to make these
sorts of task easier.
That's fair enough but that infrastructure is just extra baggage in 
some
cases.
True. The nice thing about Perl's framework is that we can avoid it 
when we don't need it.

Although the extra baggage that people are complaining about is often 
because of the verboseness of a language's OO code rather than xUnit 
itself.

Actually, just after I wrote the email, I realised I had used xUnit 
before, in Delphi. With DUnit, testing a single class takes a 
phenomenal amount of boilerplate code and I guess that's why I'd 
blocked it from my memory :).
I think DUnit would be an example of exactly what I'm talking about. 
For example the following DUnit

unit Project1TestCases;
interface
uses
TestFrameWork;

type
TTestCaseFirst = class(TTestCase)
published
procedure TestFirst;
end;

implementation

procedure TTestCaseFirst.TestFirst;
begin
Check(1 + 1 = 2, 'Catastrophic arithmetic failure!');
end;

initialization
TestFramework.RegisterTest(TTestCaseFirst.Suite);
end.
would be written in Test::Class as:
package Project1TestCases;
use base qw( Test::Class );
use Test::More;

sub catastrophic_arithmetic_failure : Test { is 1+1, 2 };
or, since we don't need any xUnit magic here, as plain old:
use Test::More tests = 1;
is 1+1, 2, 'catastrophic arithmetic failure';
This is why I like Perl!
As you say, we already have a good chunk of xUnit style with 
Test::Harness, with each .t file corresponding somewhat to a suite 
but without the nestability.
You could also compare each .t file to a test method, since the tests 
in different .t files tend to be isolated from each other.

I think the baggage only pays for itself when you end up doing a lot of
inheriting between test classes,
For me the baggage pays off as soon as test isolation becomes a factor. 
Having setup/teardown to help create test fixtures saves me typing. 
YMMV.

Adrian


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-26 Thread Tony Bowden
On Fri, Jun 25, 2004 at 01:07:36PM -0400, Andrew Pimlott wrote:
 You are also circumventing the isolation part of the xUnit model,
 because you don't get setup/teardown for each test data.  Possibly you
 don't care about that in this case, but if you did, you wouldn't be able
 to do the above, so I consider this another limitation.

I can happily call the setup/teardown methods inside the loop if I need
to. They're just normal methods.

 So to me, the above code is basically Test::More style, just using
 methods for organization.  

*That* code yes. But it was your example ...

 On that note, it seems that for some people the appeal of xUnit-style
 testing is less the model above (failure == exception, isolation),
 and more the modularity and reuse you can get by writing your tests
 with objects.

failure = exception, per se, no. However, I can throw exceptions if I
want and Test::Class will DTRT, so that's another advantage.

isolation, yes. But I don't think you mean the same thing by this as I
do. That said, I tend much more towards startup/shutdown that
setup/teardown.

Moduluarity and reuse: who doesn't love that? :)

Tony


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-26 Thread Fergal Daly
On Fri, Jun 25, 2004 at 10:13:52PM +0100, Adrian Howard wrote:
 On 25 Jun 2004, at 16:51, Fergal Daly wrote:
 [snip]
 NB: I haven't used xUnit style testing so I could be completely off 
 the mark
 but some (not all) of these benefits seem to be available in T::M land.
 
 Just so I'm clear - I'm /not/ saying any of this is impossible with 
 T::M and friends. That's obviously silly since you can build an xUnit 
 framework with Test::Builder and friends.
 
 What xUnit gives you is a little bit more infrastructure to make these 
 sorts of task easier.

That's fair enough but that infrastructure is just extra baggage in some
cases.

Actually, just after I wrote the email, I realised I had used xUnit before,
in Delphi. With DUnit, testing a single class takes a phenomenal amount of
boilerplate code and I guess that's why I'd blocked it from my memory :).

As you say, we already have a good chunk of xUnit style with Test::Harness,
with each .t file corresponding somewhat to a suite but without the
nestability.

I think the baggage only pays for itself when you end up doing a lot of
inheriting between test classes,

F




Re: C/C++ White-Box Unit Testing and Test::More

2004-06-26 Thread Fergal Daly
On Fri, Jun 25, 2004 at 02:18:49PM -0500, Andy Lester wrote:
 On Fri, Jun 25, 2004 at 04:51:29PM +0100, Fergal Daly ([EMAIL PROTECTED]) wrote:
   * I never have to type repetitive tests like
   
 isa_ok Foo-new(), 'Foo'
   
   again because it's handled by a base class that all my test classes 
   inherit from.
 
 Repetition is good.  I feel very strongly that you should be checking
 your constructor results in every single test, and checked against
 literals, not variables.
 
 my $foo = My::Foo-new();
 isa_ok( $foo, 'My::Foo' );
 # and then use it.
 #
 # Later on...
 my $foo = My::Foo-new( bar = 14, bat = \$wango );
 isa_ok( $foo, 'My::Foo' );
 
 The more checks you have, the better.  Sure, the first isa_ok
 technically covers the constructor, but why not check after EVERY
 constructor?  The 2nd example is really an entirely different test.

@_ solves that.

sub constructor_ok
{
my $class = shift;
isa_ok($class-new(@_), $class);
}

I don't think xUnit style makes it any easier to run the same test with many
different inputs,

F



Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Tony Bowden
On Thu, Jun 24, 2004 at 07:13:08PM -0400, Andrew Pimlott wrote:
 But (I thought) the idea was that every test needs the same setup.  If
 they're all in one method, they won't get that.  

How's that?

 Also, if you add lots of tests in a single method, (again as I understand) 
 they will stop after the first failure, which is not ideal if the rest of 
 the tests can still run.

That's a feature. If they can still run, move them to a different
method.

  You can group dependant tests into one method and have the method return
  or die at any point...
 As above, they won't all get the setup/teardown.

I really don't understand what you're getting at here.

Tony


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Adrian Howard
On 24 Jun 2004, at 20:19, Andrew Pimlott wrote:
On Thu, Jun 24, 2004 at 05:08:44PM +0100, Adrian Howard wrote:
Where xUnit wins for me are in the normal places where OO is useful
(abstraction, reuse, revealing intention, etc.).
Since you've thought about this, and obviously don't believe it's OO 
so
it's better, I'd be interested in seeing an example if you have one in
mind.
Off the top of my head.
* I never have to type repetitive tests like
isa_ok Foo-new(), 'Foo'
again because it's handled by a base class that all my test classes 
inherit from.

* I can create units of testing that can be reused multiple times. If I 
have an Iterator interface I can write a test suite for it once and 
reuse it any class that implements the Iterator interface.

* I have conception level available higher than individual tests (in 
T::M land) or asserts (in xUnit land). I can say something like:

sub addition_is_commutative : Test {
is 10 + 5, 15;
is 5 + 10, 15;
};
and talk about addition_is_commutative test as a concept separate from 
the tests/assertions that implement it. I can easily move test methods 
around as I refactor without having to worry about it breaking some 
other part of the test suite.

* The setup/teardown methods provide an infrastructure for creating 
test fixtures and isolating tests, which can often save typing and 
speed everything up considerably.

* Need to check that a class invariant still holds after each test? 
Chuck it in a teardown method.

Cheers,
Adrian


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Andrew Pimlott
On Fri, Jun 25, 2004 at 07:35:26AM +0100, Tony Bowden wrote:
 On Thu, Jun 24, 2004 at 07:13:08PM -0400, Andrew Pimlott wrote:
  But (I thought) the idea was that every test needs the same setup.  If
  they're all in one method, they won't get that.  
 
 How's that?

I thought the isolation principle that people were talking about is
that before every test, a setup method is called, and after every test
a teardown is called, automatically by the test harness.  This
seems to require one method == one test.

  Also, if you add lots of tests in a single method, (again as I understand) 
  they will stop after the first failure, which is not ideal if the rest of 
  the tests can still run.
 
 That's a feature. If they can still run, move them to a different
 method.

I was responding to your suggestion to put all the tests in one method
if they are just parametrized by data.  How do you suggest writing the
equivalent of

foreach (@test_data) {
is(my_func($_-{input}), $_-{output}, $_-{test_name});
}

in xUnit style, such that the first failure does not cause the rest not
to run?

Andrew


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Adrian Howard
On 24 Jun 2004, at 21:41, Ovid wrote:
[snip]
I also like the thought of inheriting tests, but I know not everyone 
is fond of this idea.  There
was a moderately interesting discussion about this on Perlmonks:
http://www.perlmonks.org/index.pl?node_id=294571
[snip]
Yeah, I meant to contribute to that but never got the spare tuits.
I tend to use them when I have an abstract interface that several 
different classes are implementing. Seems a bad idea to either ignore 
testing functionality that's being changed or waste time reimplementing 
the basically the same code.

Adrian


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Tony Bowden
On Fri, Jun 25, 2004 at 11:10:19AM -0400, Andrew Pimlott wrote:
 I thought the isolation principle that people were talking about is
 that before every test, a setup method is called, and after every test
 a teardown is called, automatically by the test harness.  This
 seems to require one method == one test.

That depends on what you class as a test for this principle. A test
(as in a test method) can contain lots of tests (as in Test::More
function calls). There's no problem with having lots of 'asserts' in one
test method.

 I was responding to your suggestion to put all the tests in one method
 if they are just parametrized by data.  How do you suggest writing the
 equivalent of
 foreach (@test_data) {
 is(my_func($_-{input}), $_-{output}, $_-{test_name});
 }
 in xUnit style, such that the first failure does not cause the rest not
 to run?

erm,

sub test_my_func : Test(no_plan) {
  my $self = shift;
  my @test_data = get_test_data_from_somewhere();
  $self-num_tests(scalar @test_data);
  foreach (@test_data) {
is(my_func($_-{input}), $_-{output}, $_-{test_name});
  }
}

What am I missing?

Tony




Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Fergal Daly
On Fri, Jun 25, 2004 at 04:05:09PM +0100, Adrian Howard wrote:
 
 On 24 Jun 2004, at 20:19, Andrew Pimlott wrote:
 
 On Thu, Jun 24, 2004 at 05:08:44PM +0100, Adrian Howard wrote:
 Where xUnit wins for me are in the normal places where OO is useful
 (abstraction, reuse, revealing intention, etc.).
 
 Since you've thought about this, and obviously don't believe it's OO 
 so
 it's better, I'd be interested in seeing an example if you have one in
 mind.

NB: I haven't used xUnit style testing so I could be completely off the mark
but some (not all) of these benefits seem to be available in T::M land.

 Off the top of my  head.
 
 * I never have to type repetitive tests like
 
   isa_ok Foo-new(), 'Foo'
 
 again because it's handled by a base class that all my test classes 
 inherit from.

sub constructor_ok
{
my $class = shift;

isa_ok $class-new, $class;
}

 * I can create units of testing that can be reused multiple times. If I 
 have an Iterator interface I can write a test suite for it once and 
 reuse it any class that implements the Iterator interface.

What's stopping you doing this in T::M,

sub test_iterator
{
my $iterator = shift;
# test various things about $iterator.
}

 * I have conception level available higher than individual tests (in 
 T::M land) or asserts (in xUnit land). I can say something like:
 
   sub addition_is_commutative : Test {
   is 10 + 5, 15;
   is 5 + 10, 15;
   };
 
 and talk about addition_is_commutative test as a concept separate from 
 the tests/assertions that implement it. I can easily move test methods 
 around as I refactor without having to worry about it breaking some 
 other part of the test suite.

I don't get this. What is the difference between having this as a method vs
as a sub?

 * The setup/teardown methods provide an infrastructure for creating 
 test fixtures and isolating tests, which can often save typing and 
 speed everything up considerably.
 
 
 * Need to check that a class invariant still holds after each test? 
 Chuck it in a teardown method.

The T::M land you could put your setup and teardown in modules and call them
before and after. Then if they're named consistently you could automate that
at which point, you'd almost have xUnit. So xUnit seems to win here for sure,

F


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Adrian Howard
On 25 Jun 2004, at 16:10, Andrew Pimlott wrote:
[snip]
I thought the isolation principle that people were talking about is
that before every test, a setup method is called, and after every  
test
a teardown is called, automatically by the test harness.  This
seems to require one method == one test.
It doesn't. I think there's a confusion of vocabulary.
In the Perl world 'test' refers to something like 'is' and 'ok' from  
Test::More and friends. We're interested in the number of successful  
tests.

In the xUnit world these are called assertions, not a tests, and in  
general we're /not/ concerned with the number of assertions that  
succeed.

In the xUnit world a /test/ is a method with one or more assertions  
that checks one particular bit of behaviour in the code. A failed test  
is a method where one assertion failed. A passed test is a method where  
all assertions succeed.

From this perspective it makes sense to abort after the first assertion  
has failed - since the 'test' has failed. Think of it like logical ''  
short circuiting, or maybe like SKIP blocks (there's no point doing the  
other assertions because the thing we're testing has already failed).

Test isolation is the idea each test (not assertion) can run  
independently from every other. This means when we have a failure we  
can quickly focus in on exactly what caused the problem. We can be  
confidant that four test failures indicates four separate problems, not  
a cascade of failure within the test suite itself.

There is a school of thought that one-assertion-per-test is a good goal  
to aim for, but not everybody agrees. For some discussion see:

-  
http://www.testdriven.com/modules/newbb/viewtopic.php? 
viewmode=flattopic_id=363forum=6
- http://www.artima.com/weblogs/viewpost.jsp?thread=35578

Hopefully this makes some vague sort of sense.
Cheers,
Adrian


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Andrew Pimlott
On Fri, Jun 25, 2004 at 04:41:15PM +0100, Tony Bowden wrote:
 On Fri, Jun 25, 2004 at 11:10:19AM -0400, Andrew Pimlott wrote:
  I was responding to your suggestion to put all the tests in one method
  if they are just parametrized by data.  How do you suggest writing the
  equivalent of
  foreach (@test_data) {
  is(my_func($_-{input}), $_-{output}, $_-{test_name});
  }
  in xUnit style, such that the first failure does not cause the rest not
  to run?
 
 erm,
 
 sub test_my_func : Test(no_plan) {
   my $self = shift;
   my @test_data = get_test_data_from_somewhere();
   $self-num_tests(scalar @test_data);
   foreach (@test_data) {
 is(my_func($_-{input}), $_-{output}, $_-{test_name});
   }
 }

Now I'm confused too.  None of the Test::Unit examples I've seen use
is, they use some form of assert.  Is this the Test::More is, or
something else?  Doesn't an xUnit-style test need to throw an exception
to signal failure?  Does your is do that?  If so, no test data after
the first failure will be tried.  If not, how does this work?

If this style is described somewhere and I just missed it, point me the
way.  My Test::Unit doesn't use the : Test attribute, so maybe I have
old or wrong code.

Andrew


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Ovid
--- Andrew Pimlott [EMAIL PROTECTED] wrote:
 Now I'm confused too.  None of the Test::Unit examples I've seen use
 is, they use some form of assert.

You were looking at Test::Class code, not Test::Unit code.

Cheers,
Ovid

=
Silence is Evilhttp://users.easystreet.com/ovid/philosophy/indexdecency.htm
Ovid   http://www.perlmonks.org/index.pl?node_id=17000
Web Programming with Perl  http://users.easystreet.com/ovid/cgi_course/


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Andrew Pimlott
Ok, now that I understand what library you're using ...

On Fri, Jun 25, 2004 at 04:41:15PM +0100, Tony Bowden wrote:
 On Fri, Jun 25, 2004 at 11:10:19AM -0400, Andrew Pimlott wrote:
  I was responding to your suggestion to put all the tests in one method
  if they are just parametrized by data.  How do you suggest writing the
  equivalent of
  foreach (@test_data) {
  is(my_func($_-{input}), $_-{output}, $_-{test_name});
  }
  in xUnit style, such that the first failure does not cause the rest not
  to run?
 
 erm,
 
 sub test_my_func : Test(no_plan) {
   my $self = shift;
   my @test_data = get_test_data_from_somewhere();
   $self-num_tests(scalar @test_data);
   foreach (@test_data) {
 is(my_func($_-{input}), $_-{output}, $_-{test_name});
   }
 }

By not using the failure == exception part of the xUnit model, you avoid
the issue I was getting at.  Obviously, the above would stop after the
first test data that provokes a failure if you were using that model,
which is why I consider it limiting.

You are also circumventing the isolation part of the xUnit model,
because you don't get setup/teardown for each test data.  Possibly you
don't care about that in this case, but if you did, you wouldn't be able
to do the above, so I consider this another limitation.

So to me, the above code is basically Test::More style, just using
methods for organization.  On that note, it seems that for some people
the appeal of xUnit-style testing is less the model above (failure ==
exception, isolation), and more the modularity and reuse you can get by
writing your tests with objects.  On this point there's not much to
argue about--if that helps you write better tests, great!

Which leaves me wondering if anyone defends Test::Unit per se.  :-)

Andrew


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Adrian Howard
On 24 Jun 2004, at 21:10, Tony Bowden wrote:
On Thu, Jun 24, 2004 at 02:59:30PM -0400, Andrew Pimlott wrote:
I see this more as a limitation than a feature.  It seems to mean that
- You need to use the same setup/teardown for all your tests.
Those that need different things aren't testing the same thing and
should move to a different class.
Yup.
This misunderstanding seems to be a common one. Novice xUnit users 
often think that there should be a single test class for every class 
being tested.

Sometimes this can work; when you don't need text fixtures or where a 
single set of test fixtures can cover all of a classes functionality.

However many situations require multiple classes each with their own 
set of fixtures and test behaviour.

Cheers,
Adrian


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Andy Lester
On Fri, Jun 25, 2004 at 04:51:29PM +0100, Fergal Daly ([EMAIL PROTECTED]) wrote:
  * I never have to type repetitive tests like
  
  isa_ok Foo-new(), 'Foo'
  
  again because it's handled by a base class that all my test classes 
  inherit from.

Repetition is good.  I feel very strongly that you should be checking
your constructor results in every single test, and checked against
literals, not variables.

my $foo = My::Foo-new();
isa_ok( $foo, 'My::Foo' );
# and then use it.
#
# Later on...
my $foo = My::Foo-new( bar = 14, bat = \$wango );
isa_ok( $foo, 'My::Foo' );

The more checks you have, the better.  Sure, the first isa_ok
technically covers the constructor, but why not check after EVERY
constructor?  The 2nd example is really an entirely different test.

Tests are all about quantity.


xoa

-- 
Andy Lester = [EMAIL PROTECTED] = www.petdance.com = AIM:petdance


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Nicholas Clark
On Fri, Jun 25, 2004 at 02:18:49PM -0500, Andy Lester wrote:
 Tests are all about quantity.

I always thought that tests were about malice:

I bet the programmer didn't think of this...
What happens if I just do this...
Mmm, I wonder if it covers this corner case?
Eat pathological data and die!
Surrender feeble routine. You are no match for the weaponry of my tests!

Then again, I do like having lots of tests. And parameterising tests so that
I can feed the same basic test lots of different permutations of the data.
[To attempt to send the most variations of malice, in the hope that one of
them knocks out the routine and finds a bug]

Nicholas Clark


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Adrian Howard
On 25 Jun 2004, at 20:18, Andy Lester wrote:
Repetition is good.  I feel very strongly that you should be checking
your constructor results in every single test, and checked against
literals, not variables.
I'm not complaining about repetitive tests, and I agree with what you 
said about testing constructor results if it's something that can 
reasonably fail.

I'm complaining about /typing/ repetitive tests. Why the heck should I 
have to type the same code in twice if I can get the computer to do it 
for me.

Adrian


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Adrian Howard
On 24 Jun 2004, at 19:59, Andrew Pimlott wrote:
[snip]
- You don't have much control (correct me if I'm wrong) about the order
  of tests, or the relationship between tests, eg you can't say if 
this
  test fails, skip these others.  This is straightforward in
  Test::More's simple procedural style.
[snip]
This is probably due to the same test/assertion confusion - but the 
whole /point/ of xUnit is that the test order shouldn't matter :-)

Test isolation == good!
If I need isolation, why can't I just ask for it directly?
with_test_setup {
run_tests();
}
You can.
But then the test writer/reader has to code/understand the 
with_test_setup() code for each test script, and the structure of each 
of those routines is pretty much the same.

So you might decide to generalise it and have a standard mechanism for 
you to plug in your start up code.

Then you discover that some of your tests need to clean up after 
themselves so you add another slot to run after the tests.

Then you might find that you often have common sets of tests that are 
run in different situations, so it would be nice if you could package 
them up and use them as a unit. So you add some infrastructure to 
support it.

Well done - you've implemented an xUnit framework!
(or rather provided the few elements of an xUnit framework not already 
supplied by Test::Harness, Test::Builder and friends).

These sorts of requirements are exactly what made me build Test::Class 
- adding the bits of xUnit not already in the Perl testing framework.

I didn't start out to write an xUnit framework. What I did was refactor 
several large and slow test suites and the very xUnit-ish Test::Class 
just fell out.

I don't really think of xUnit as a competitor to Perl's normal testing 
infrastructure - it's more of a superset. The fact that it's so easy to 
layer the missing bits of xUnit on top of Perl's standard mechanisms 
shows that.

[snip]
Even better would be to put Test::Builder in skip mode, where it 
skips
automatically whenever a test fails:

skip_mode {
ok(something);
is(this, that);
}
sub skip_mode () {
my $test_sub = shift;
my $old_ok = \Test::Builder::ok;
my $test_passed=1;
local $Test::Builder::Level = $Test::Builder::Level + 1;
no warnings;
local *Test::Builder::ok = sub {
die unless $test_passed = $old_ok-(@_);
};
eval { $test_sub-() };
die $@ if $@  $test_passed;
};
:-)
[snip]
Every time I hear about xUnit, I figure there must be something other
than setup and teardown in its favor.  If that's all there is, I'm 
not
sold.
You have to remember that xUnit isn't just setup/teardown routines. 
It's all the rest too - assertions, a test runner, test suites, OO 
reuse framework, etc. Most of which we already have with Test::Harness, 
Test:Builder and friends.

When people speak about the advantages of xUnit, they're mostly talking 
about the advantages of having a standard testing infrastructure.

Cheers,
Adrian


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-25 Thread Adrian Howard
On 25 Jun 2004, at 16:51, Fergal Daly wrote:
[snip]
NB: I haven't used xUnit style testing so I could be completely off 
the mark
but some (not all) of these benefits seem to be available in T::M land.
Just so I'm clear - I'm /not/ saying any of this is impossible with 
T::M and friends. That's obviously silly since you can build an xUnit 
framework with Test::Builder and friends.

What xUnit gives you is a little bit more infrastructure to make these 
sorts of task easier.

Off the top of my  head.
* I never have to type repetitive tests like
isa_ok Foo-new(), 'Foo'
again because it's handled by a base class that all my test classes
inherit from.
sub constructor_ok
{
my $class = shift;
isa_ok $class-new, $class;
}
But you still have to call constructor_ok().
I can still all my common tests in a base test class and just by 
inheriting from it get them all run automagically.

* I can create units of testing that can be reused multiple times. If 
I
have an Iterator interface I can write a test suite for it once and
reuse it any class that implements the Iterator interface.
What's stopping you doing this in T::M,
sub test_iterator
{
my $iterator = shift;
# test various things about $iterator.
}
Nothing. But xUnit supplies a little extra bit of magic to mark 'test' 
subroutines so they can be automatically found and run with no effort 
on your part.

* I have conception level available higher than individual tests (in
T::M land) or asserts (in xUnit land). I can say something like:
sub addition_is_commutative : Test {
is 10 + 5, 15;
is 5 + 10, 15;
};
and talk about addition_is_commutative test as a concept separate from
the tests/assertions that implement it. I can easily move test methods
around as I refactor without having to worry about it breaking some
other part of the test suite.
I don't get this. What is the difference between having this as a 
method vs as a sub?
By having it as a test method it gets automatically picked up and run 
by the test environment. I can move the test method to another class 
and, without altering another line, it will be automatically picked up 
and run by the new class.

* The setup/teardown methods provide an infrastructure for creating
test fixtures and isolating tests, which can often save typing and
speed everything up considerably.
* Need to check that a class invariant still holds after each test?
Chuck it in a teardown method.
The T::M land you could put your setup and teardown in modules and 
call them before and after. Then if they're named consistently you 
could automate that at which point, you'd almost have xUnit. So xUnit 
seems to win here for sure,
Exactly! This is all stuff that Test::Builder based modules can do - 
xUnit just sprinkles some convenience fairy dust over everything to 
make doing it easier :-)

The /nice/ thing about Perl's infrastructure is that we can abandon the 
extra infrastructure when we don't need it - making simpler test 
scripts more compact and easier to understand.

Cheers,
Adrian


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-24 Thread Piers Cawley
Andrew Pimlott [EMAIL PROTECTED] writes:

 On Wed, Jun 09, 2004 at 08:18:30AM -0700, Ovid wrote:
 As for porting a Test::More style framework, I tried doing that with
 Python and was actually doing well with it, but I was shot down pretty
 quickly.

 Any specific reasons why (is the discussion archived)?  Is there any
 site that compares the styles?

The xUnit style framework does a much better job of enforcing test
isolation than Test::More does (but you have to remember that what
Test::More thinks of as a test, xUnit thinks of as an assertion to be
used *in* a test). 


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-24 Thread Adrian Howard
On 24 Jun 2004, at 07:09, Piers Cawley wrote:
[snip]
The xUnit style framework does a much better job of enforcing test
isolation than Test::More does (but you have to remember that what
Test::More thinks of as a test, xUnit thinks of as an assertion to be
used *in* a test).
To be fair to Test::More and friends xUnit doesn't /enforce/ test 
isolation any more than Test::More prevents it. Writing isolated tests 
with Test::More is trivial, just do something like:

sub make_fixture {
return ( Cash-new(10), Cash-new(20) );
};
isa_ok( $_, 'Cash' ) foreach make_fixture();
{
  my ($ten, $twenty) = make_fixture();
  is_deeply $ten + $twenty, Cash-new(30);
};
... etc ...
I had a mild rant about this on the TDD list a few months back. You can 
write isolated tests in a procedural style quite easily. You can also 
easily write tightly-coupled tests in an xUnit style. It's all reliant 
on developer discipline. xUnit provides some infrastructure that helps, 
but it doesn't enforce it. Developers do that.

(Apologies for rant. Consider it a symptom of the number of ghastly 
xUnit test classes that I've seen with 100 line test methods and no 
setup methods.)

Where xUnit wins for me are in the normal places where OO is useful 
(abstraction, reuse, revealing intention, etc.). Where xUnit loses are 
the times when you don't need it all the extra infrastructure and it 
just becomes overhead that gets in the way of understanding the test 
suite.

Where the Perl testing framework wins for me:
-	it gives me the flexibility to do both procedural and xUnit styles as 
I see fit
-	it also provides SKIP and TODO tests, which I've not come across 
elsewhere. TODO test in particular I find useful for tracking technical 
debt
-	Test::Harness has a nice ASCII protocol that I can use to feed 
non-Perl stuff into the testing framework

Anyway enough rambling ;-)
Adrian


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-24 Thread Andrew Pimlott
On Thu, Jun 24, 2004 at 07:09:40AM +0100, Piers Cawley wrote:
 The xUnit style framework does a much better job of enforcing test
 isolation than Test::More does

I see this more as a limitation than a feature.  It seems to mean that

- You need to use the same setup/teardown for all your tests.

- You're restricted to one test == one method, so you can't paramatrize
  your tests by data (eg, second example below).

- You don't have much control (correct me if I'm wrong) about the order
  of tests, or the relationship between tests, eg you can't say if this
  test fails, skip these others.  This is straightforward in
  Test::More's simple procedural style.

If I need isolation, why can't I just ask for it directly?

with_test_setup {
run_tests();
}

and even

foreach (@my_test_data) {
with_test_setup {
run_tests($_);
}
}

 (but you have to remember that what
 Test::More thinks of as a test, xUnit thinks of as an assertion to be
 used *in* a test). 

This is the one point of actual difference, but I think we can take care
of it.  For starters,

SKIP: {
ok(something) || skip
is(this, that) || skip;
}

Even better would be to put Test::Builder in skip mode, where it skips
automatically whenever a test fails:

skip_mode {
ok(something);
is(this, that);
}

This can't play nice with test counts, but that's a brain-dead idea
anyway.

Every time I hear about xUnit, I figure there must be something other
than setup and teardown in its favor.  If that's all there is, I'm not
sold.

Andrew


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-24 Thread Andrew Pimlott
On Thu, Jun 24, 2004 at 05:08:44PM +0100, Adrian Howard wrote:
 Where xUnit wins for me are in the normal places where OO is useful 
 (abstraction, reuse, revealing intention, etc.).

Since you've thought about this, and obviously don't believe it's OO so
it's better, I'd be interested in seeing an example if you have one in
mind.

Andrew


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-24 Thread chromatic
On Thu, 2004-06-24 at 11:59, Andrew Pimlott wrote:

 Every time I hear about xUnit, I figure there must be something other
 than setup and teardown in its favor.  If that's all there is, I'm not
 sold.

It's the best option for languages that enforce a nominally pure OO
style.

(During the tech review of the XP Pocket Guide, Dave Thomas pointed out
that many of the XP techniques come from the way Smalltalk forced Ward
and Kent to work.  xUnit qualifies there.)

-- c



Re: C/C++ White-Box Unit Testing and Test::More

2004-06-24 Thread Tony Bowden
On Thu, Jun 24, 2004 at 02:59:30PM -0400, Andrew Pimlott wrote:
 I see this more as a limitation than a feature.  It seems to mean that
 - You need to use the same setup/teardown for all your tests.

Those that need different things aren't testing the same thing and
should move to a different class.

 - You're restricted to one test == one method, so you can't paramatrize
   your tests by data (eg, second example below).

I'm not sure what you mean here. You can have lots of tests in a single
method. And subclasses can add their own extra tests to the parent's
tests.

 - You don't have much control (correct me if I'm wrong) about the order
   of tests, or the relationship between tests, eg you can't say if this
   test fails, skip these others.  This is straightforward in
   Test::More's simple procedural style.

You can group dependant tests into one method and have the method return
or die at any point...

 Every time I hear about xUnit, I figure there must be something other
 than setup and teardown in its favor.  If that's all there is, I'm not
 sold.

The big gain for me with Test::Class is inheritable tests. Subclasses
can ensure they still pass all their parent's tests, as well as all of
their own, without me having to copy all the tests, or set up a really
clumsy testing environment. And of course you get to refactor the test
suite quite nicely too so that it's really obvious what each test is
doing.

If I'm not testing something with a lot of inheritance, then Test::Class
loses about 90% of its attraction.

Tony



Re: C/C++ White-Box Unit Testing and Test::More

2004-06-24 Thread Ovid
--- Tony Bowden [EMAIL PROTECTED] wrote:
 The big gain for me with Test::Class is inheritable tests. Subclasses
 can ensure they still pass all their parent's tests, as well as all of
 their own, without me having to copy all the tests, or set up a really
 clumsy testing environment. And of course you get to refactor the test
 suite quite nicely too so that it's really obvious what each test is
 doing.

I also like the thought of inheriting tests, but I know not everyone is fond of this 
idea.  There
was a moderately interesting discussion about this on Perlmonks: 
http://www.perlmonks.org/index.pl?node_id=294571

Cheers,
Ovid



=
Silence is Evilhttp://users.easystreet.com/ovid/philosophy/indexdecency.htm
Ovid   http://www.perlmonks.org/index.pl?node_id=17000
Web Programming with Perl  http://users.easystreet.com/ovid/cgi_course/


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-24 Thread Andrew Pimlott
On Thu, Jun 24, 2004 at 09:10:09PM +0100, Tony Bowden wrote:
 On Thu, Jun 24, 2004 at 02:59:30PM -0400, Andrew Pimlott wrote:
  I see this more as a limitation than a feature.  It seems to mean that
  - You need to use the same setup/teardown for all your tests.
 
 Those that need different things aren't testing the same thing and
 should move to a different class.

What about running the same tests with different sample data (so
different setup/teardown)?  I suppose you could create a sub-class for
each data set, but that seems like busy-work.  (Unless you can create
all those sub-classes automatically from the data)

  - You're restricted to one test == one method, so you can't paramatrize
your tests by data (eg, second example below).
 
 I'm not sure what you mean here. You can have lots of tests in a single
 method. And subclasses can add their own extra tests to the parent's
 tests.

But (I thought) the idea was that every test needs the same setup.  If
they're all in one method, they won't get that.  Also, if you add lots
of tests in a single method, (again as I understand) they will stop
after the first failure, which is not ideal if the rest of the tests can
still run.

  - You don't have much control (correct me if I'm wrong) about the order
of tests, or the relationship between tests, eg you can't say if this
test fails, skip these others.  This is straightforward in
Test::More's simple procedural style.
 
 You can group dependant tests into one method and have the method return
 or die at any point...

As above, they won't all get the setup/teardown.

 The big gain for me with Test::Class is inheritable tests.

I see.

Andrew


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-10 Thread Andrew Savige
Ovid wrote:
 For white box testing C code, I just use assert().

assert() is ok, but ok() is better. :-)
I will prolly roll my own custom ok() macro, so instead of:
  assert(x==y);
I can write:
  ok(x==y, test that x equals y);
Writing a lot of tests, I want to be able to easily label each test.
(I think I will need an ok() macro rather than a function to get
__FILE__ and __LINE__ also for failing tests).

/-\


Find local movie times and trailers on Yahoo! Movies.
http://au.movies.yahoo.com


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-09 Thread Avram Aelony
Perhaps this will be useful... 
http://boost.org/libs/test/doc/index.html.
-Avram

On Jun 8, 2004, at 8:18 PM, Andrew Savige wrote:
I am currently using Test::More for my Perl white-box unit tests.
I also need to write some C/C++ white-box unit tests and would like
to use something similar in spirit to Test::More.
Smalltalk's SUnit-style framework has been ported to many languages
(JUnit, cppunit, Test::Unit, Test::Class, ...).
Has anyone ported a Test::More style framework to C/C++ or Java?
How do Perl5/Parrot white-box unit test their C code?
/-\
Find local movie times and trailers on Yahoo! Movies.
http://au.movies.yahoo.com



Re: C/C++ White-Box Unit Testing and Test::More

2004-06-09 Thread Ovid
--- Andrew Savige [EMAIL PROTECTED] wrote:
 Has anyone ported a Test::More style framework to C/C++ or Java?
 How do Perl5/Parrot white-box unit test their C code?

For white box testing C code, I just use assert().

As for porting a Test::More style framework, I tried doing that with Python and was 
actually doing
well with it, but I was shot down pretty quickly.  xunit style testing, though it has 
limitations,
is very powerful and people are quick to scoff at alternatives (at least from what I've
experienced.)

Cheers,
Ovid

=
Silence is Evilhttp://users.easystreet.com/ovid/philosophy/indexdecency.htm
Ovid   http://www.perlmonks.org/index.pl?node_id=17000
Web Programming with Perl  http://users.easystreet.com/ovid/cgi_course/


Re: C/C++ White-Box Unit Testing and Test::More

2004-06-09 Thread chromatic
On Tue, 2004-06-08 at 20:18, Andrew Savige wrote:

 I am currently using Test::More for my Perl white-box unit tests.
 I also need to write some C/C++ white-box unit tests and would like
 to use something similar in spirit to Test::More.

What if you used Inline::C *and* Test::More?  If they're white box tests
for well-factored code, would it work?

-- c