3

I've been doing unit testing and I ran into this weird bad problem.

I'm doing user authentication tests with some of my services/mappers.

I run, all together about 307 tests right now. This only really happens when I run them all in one batch.

I try to instantiate only one Zend_Application object and use that for all my tests. I only instantiate it to take care of the db connection, the session, and the autoloading of my classes.

Here is the problem.

Somewhere along the line of tests the __destruct method of the Zend_Session_SaveHandler_DbTable gets called. I have NO IDEA WHY? But it does.

The __destruct method will render any writing to my session objects useless because they are marked as read-only.

I have NO clue why the destruct method is being called.

It gets called many tests before my authentication tests. If I run each folder of tests individually there is no problem. It's only when I try to run all 307 tests. I do have some tests that do database work but my code is not closing the db connections or destructing the save handler.

Does anyone have any ideas on why this would be happening and why my Zend_Session_SaveHandler_DbTable is being destructed? Does this have anything to do with the lifetime that it has by default?

Jerry Saravia
  • 3,737
  • 3
  • 24
  • 39

2 Answers2

1

It's an old question, but I have just had the same problem and found the solution here. I think it's the right way to solve it.

Zend_Session::$_unitTestEnabled = true;
Donatas Olsevičius
  • 1,350
  • 8
  • 13
1

I think that what was happening is that PHPUnit was doing garbage collection. Whenever I ran the 307 tests the garbage collector had to run and it probably destroyed the Zend_Session_SaveHandler_DbTable for some reason.

This would explain why it didn't get destroyed when fewer tests were being run.

Or maybe it was PHP doing the garbage collection, that makes more sense.

Either way, my current solution is to create a new Zend_Application object for each test class so that all the tests within that class have a fresh zend_application object to work with.

Here is some interesting information.

I put an echo statement in the __destruct method of the savehandler.

The method was being called ( X + 1 ) times, where X was the number of tests that I ran. If I ran 50 test I got 51 echos, 307 tests then 308 echos, etc.

Here is the interesting part. If I ran only a few tests, the echos would all come at the END of the test run. If I tried to run all 307 tests, 90 echos would show up after what I assumed were 90 test. The rest of the echos would then come up at the end of the remaining tests. The number of echos was X + 1 again, or in this case 308.

So, this is where I'm assuming that this has something to do with either the tearDown method that PHPUnit calls, or the PHP garbage collector. Maybe PHPUnit invokes the garbage collector at teardown. Who knows but I'm glad I got it working now as my tests were all passing beforehand.

If any of you have a better solution then let me know. Maybe I uncovered a flaw in my code, phpunit, or zend, that hadn't been known before and there is some way to fix it.

Jerry Saravia
  • 3,737
  • 3
  • 24
  • 39
  • I think in theory you would want a fresh application object for each test. In practice though, using the same object is often the way to go when we are sure it is pristine for every subsequent test. Are they all in the same test suite? Having your tests in different suites helps for troubleshooting issues like this. If you find where _destruct is being called twice you will probably find what is choking your tests. Good-luck, +oned for posting back your findings. – Stephane Gosselin Jun 08 '11 at 03:10
  • Hey, I was having my bootstrap file creating a global zend_application object and was putting it into the $GLOBALS variable. Each test class would then fetch the application object in it's setUpBeforeClass/SetUp methods. I wasn't dispatching any controllers or anything. The reason I was instantiating it was because the application could be called to setup autoloading of my models and the database connection for the database/authentication tests. – Jerry Saravia Jun 08 '11 at 12:28
  • All my tests were in an 'application' folder in other folders. In PHP unit if I specified the subfolders only then everything was fine. But once I tried to run every test things went bad. I think that I'm missing some sort of PHPUnit behavior that would explain all this. – Jerry Saravia Jun 08 '11 at 12:30