Question

At the risk of being flamed... what advantage does enforcing calls to methods rather than functions have in a context where the context is implicit.

Considering that PHP's syntax is so ugly for calling methods why would PHPUnit's creators have enforced its usage?

If the framework had set a global "currentTestCase" object and then transparently associated failed asserts with that object we could be writing:

assertEquals("blah", $text);

as opposed to the equivalent, but verbose:

$this->assertEquals("blah", $text);

What exactly do we get by using OO in this context.

Please enlighten me.

Was it helpful?

Solution

Because PHPUnit is derived from xUnit and that's how xUnit does it.

Why does xUnit do it that way? I'm glad you asked. The original reason, as Robert points out, is that xUnit comes from Smalltalk and was popularized by JUnit in Java. Both are OO-or-nothing languages so they had no choice.

This is not to say there are not other advantages. OO tests can be inherited. This means if you want to test a subclass you can run all the parent's tests and just override the handful of test methods for the behaviors you've changed. This gives you excellent coverage of subclasses without having to duplicate test code.

Its easy to add and override assert methods in PHPUnit. Just subclass PHPUnit_Framework_TestCase, write your own assert methods and have your test classes inherit from your new subclass. You can also write default setup and teardown methods.

Finally, it guarantees that the test framework's methods aren't going to clash with the thing that they're testing. If the test framework just dumped its functions into the test and you wanted to test something that had a setup method... well you're in trouble.

That said, I hear your pain. A big test framework can be annoying and cumbersome and brittle. Perl doesn't use an xUnit style, it uses a procedural style with short test function names. See Test::More for an example. Behind the scenes it does just what you suggested, there's a singleton test instance object which all the functions use. There's also a hybrid procedural assert functions with OO test methods module called Test::Class which does the best of both worlds.

Considering that PHP's syntax is so ugly for calling methods

I guess you don't like the ->. I suggest you learn to live with it. OO PHP is so much nicer than the alternative.

OTHER TIPS

One good reason is that assertXXX as a method name has a high risk for naming clash.

Another one is that it is derived from the xUnit family, which typically deals with object-oriented languages - Smalltalk initially. This makes it easier to related yourself to your "siblings" from e.g. Java and Ruby.

Not a direct answer, but as of PHPUnit 3.5, you do not have to write $this-> anymore. PHPUnit 3.5 added a function library for Assertions, which you have to include

require_once 'PHPUnit/Framework/Assert/Functions.php';

Then you can do

assertEquals('foo', $bar);

See Sebastian Bergmann's Blog post about it

Having the test cases in class-methods saves work for PHPUnit. Due to lack of built-in intelligence PHPUnit couldn't find or handle pure test functions. Only having to recognize the ->assert*() messages -in a simple boolean chain- again saves processing logic (for PHPUnit, not the test case author). It's all syntactic salt that saves overhead from the PHPUnit/SimpleTest point of view.

It wouldn't be a technical problem to capture error/warning messages, exceptions or recognize PHPs native assert() statement. It's not done because a difficult API looks more enterprisey.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top