Re: Unit testing framework suggestions?
Re: Unit testing framework suggestions?
- Subject: Re: Unit testing framework suggestions?
- From: Marco Scheurer <email@hidden>
- Date: Sun, 26 Sep 2004 13:01:20 +0200
On Sep 26, 2004, at 01:33, Georg Tuparev wrote:
It happens that I disagree with Marco once each decade (so do not
expect me to start discussing with him next 10 years) ... but I feel
this is one of these occasions...
Oh! I'l have to show some disagreement too then!
One reason is that tests can have their own state and ivars, and it
wouldn't be a good idea to mix this with the class you want to test.
You might be right is theory, but at least I and all the people I
enjoyed working with almost never kept state between two tests.
Actually, if I think very hard, I cannot find a single case where my
need of using state was not because of stinky code - or bad design, or
bad refactoring.
I admit that it is not frequent, and one could certainly go away
without that possibility.
In our testing framework, we create an instance of the tested class
for every single test method.
If I understand this correctly, this is exactly what is done in OCUnit
and SmalltalkUnit.
In cases where we need singleton we need to override the setUp and
tearDown methods. For class like App Delegate (instantiated in a nib
file) we write:
+ (id)setUp { return [NSApp delegate]; }
+ (void)tearDown:(id)testInstance { }
This feels strange at the beginning - normally one needs to implement
setUp and tearDown for each TestCase class,
No. You can but don't have to implement setUp and tearDown. You do it
only when you want to initialize all your TestCase tests to a common
state.
but with our framework we need from time to time to knock them off -
most often though one never touches them. Also note the "+" in front
of these methods. This is not a typo :-)
OCUnit also has +setUp...
Here a typical test method:
- (void)testVisibleWindow {
SEConfirmIsTrue(tableWindow != nil, @"Window should not be nil");
SEConfirmIsTrue([tableWindow isVisible],
@"Window should be visible after the application
is launched");
}
UI testing made easy...
I fail to see any differences with how this would be done using OCUnit,
except the name of the macros. Until I see more of this kit, I'm still
unconvinced: it looks to me like one of the many "I can make it
simpler" attempt, which evolves in mostly the same thing as OCUnit, a
good example of the NIH syndrome.
With an installer package, target and file templates and a README, I
doubt that it would take anyone more than 5 minutes to write a first
test using OCUnit, unless of course one is new to the whole idea.
Another is that tests are written from the perspective of a user of
the class rather than as "internal" tests. A good practice is to
write the tests before you write the tested code. If you do so, your
tests can be seen as a formal specification of the code to be
written.
Developer writes tests first - to help him or her to write the real
code. So you write a test not as a user, but as an author. Tests are
also the best known to me way of documenting - and you want to keep
the doc close to the code - otherwise they will get out of sync -
therefore test are so good - they must be in sync if they have to
pass!
If you test all the time (say after each change), it doesn'y matter
where your tests are, they will not get out of sync. If you don't, it
doesn't matter where they are either, they will get out of sync. So
this to "keep your tests in sync" is not a reason for having them in
one class or another.
[I am sure this might sound like Knuth's Literate Programming - in
retrospect I have to acknowledge that after Drew and I wrote the first
version of our testing framework, I though that this is the closest
practical way of doing literate programming for Cocoa]
I said that much when talking about a "formal specification".
In truth my point about writing tests first also has little to do with
where they are implemented. You can of course start writing your class
by writing the test methods. But it seems more natural to me to do so
as an "outsider", the customer who specifies what the methods are
supposed to do.
Another is that a lot of stuff is usually done in the TestCase class,
so that writing a test is as simple as writing a single method in a
subclass of TestCase.
Luckily we have categories in ObjC. And no one stops you putting this
"lot of stuff" to a category of NSObject :-) But more importantly,
there is no need to have a lot of stuff in TestCase class.
Yes, as I said that's a possibility. And then in order to keep your
files shorter you may want to put the testing categories in separate
files, and if you do so you gain nothing by having the tests in a
category instead of a subclass of TestCase. However you have lost some
flexibility, like the ability to store a state when you need it.
marco
Marco Scheurer
Sen:te, Lausanne, Switzerland http://www.sente.ch
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden