I recently worked on an application wide cache component. One implementation persists data by communicating with a Redis server, the other one uses PDO and is accessing a SQLite DB file.
There is an abstract test class, which covers all the methods in the application cache interface, and two concrete tests for both implementations, inheriting the abstract class and thus are forced to provide a method to return an instance if the actual cache object. If the entire test suite is running, both tests succeed. However, if I only run the SQLite test, it fails - the Redis test is all right. I stumbled upon this case as I saw, there was 0% code coverage for the SQLite Cache. Adding debug output revealed ridiculous behaviour.
First of all, these are roughly the classes:
Abstract base class:
abstract class ApplicationCacheTestCase extends BasicTestCase {
/**
* @return ApplicationCache
*/
protected abstract function getCache();
private function cacheImpl() {
static $impl;
if(null == $impl) {
$impl = $this->getCache();
}
return $impl;
}
/**
* @test
*/
public function itemsCanBeCached() {
$item1 = $this->createItem('test-1', 42);
$duration = 2; //secs
$this->assertItemIsSettable($item1->key, $item1->val, $duration);
$cache = $this->cacheImpl();
$this->assertTrue($cache->has('test-1'));
$this->assertItemHasValue('test-1', 42);
}
}
SQLite Implementation:
class CacheTest extends ApplicationCacheTestCase {
public function __construct() {
echo "SQLite test has started.\n";
}
protected final function getCache() {
echo "Allocated cache instance.\n";
return new Cache(':memory:');
}
}
Running the entire suite leads to following output:
SQLite test has started.
SQLite test has started.
SQLite test has started.
[... several times ...]
OK (112 tests, 462 assertions)
The test class gets instantiated a few times, but getCache()
is never called. How does this test even succeed? Telling PHPUnit to only run the SQLite Cache tests produces that:
SQLite test has started.
[...]
Failed asserting that false is true.
./test/unit/BlackTie/Cache/Application/ApplicationCacheTestCase.php:77
Allocated cache instance.
This test depends on "BlackTie\Cache\Application\SQLite\CacheTest::itemsCanBeCached" to pass.
[... several times ...]
FAILURES!
Tests: 1, Assertions: 5, Failures: 1, Skipped: 6.
Line 77 is the $this->assertTrue($cache->has('test-1'));
in the first test. Am I doing something wrong?
Thanks in advance for your help!
Aucun commentaire:
Enregistrer un commentaire