2012-03-10 143 views
0

我很好奇人们如何处理测试之间的耦合以及“级联失败”。我不知道还有什么叫它,所以我会解释一些代码。单元测试,测试之间的耦合和级联失败

我有一个简单的缓存类,我想测试。

class Cache 
{ 
    private $data = array(); 
    public function set($key, $data) 
    { 
     $this->data[$key] = $data; 
     return true; 
    } 
    public function get($key) 
    { 
     if (!isset($this->data[$key])) { 
      return false; 
     } 
     return $this->data[$key]; 
    } 
} 

现在我想测试这个类以及这个类中的两个方法。这是问题所在; get()方法依赖于set()方法。所以我可以用两种方式之一编写测试用例。

class TestCache extends Test 
{ 
    private $cache = null; 
    public function setup() 
    { 
     $this->cache = new Cache(); 
    } 
    public function testSet() 
    { 
     $result = $this->cache->set('foo', 'bar'); 
     $this->asserTrue($result); 
    } 
    public function testGet() 
    { 
     $result = $this->cache->get('foo'); 
     $this->assertEquals($result, 'bar'); 
    } 
} 

这里的问题是第二个测试testGet()对第一个测试testSet()的回复。如果testSet()失败,那么testGet()也会失败。两种测试之间有一种耦合。此外,如果我更改测试方法的顺序,testGet()测试将失败。因此,我写这样的测试案例:

class TestCache extends Test 
{ 
    private $cache = null; 
    public function setup() 
    { 
     $this->cache = new Cache(); 
    } 
    public function testSet() 
    { 
     $result = $this->cache->set('foo', 'bar'); 
     $this->asserTrue($result); 
    } 
    public function testGet() 
    { 
     $this->cache->set('foo', 'bar'); 
     $result = $this->cache->get('foo'); 
     $this->assertEquals($result, 'bar'); 
    } 
} 

现在两个测试之间没有耦合,但仍然存在问题。如果Cache :: set()方法失败,那么第二个测试也将失败,因为第二个测试对Cache :: get()的调用对Cache :: set()的响应不失败。

所以我想知道你通常如何处理这样的情况。由于一次错误测试,您是否仅仅接受测试输出中的数十个失败?如果重要的测试失败,您是否会放弃进一步的测试?

回答

2

这是@depends指令在phpunit中的用途:请参阅“测试依赖关系”部分。如果依赖失败,那么依赖于初始测试的后续测试将被跳过。

+0

非常有趣,我可以看到这个创建*次要*维护。问题,但看起来像一个小的价格付出。 – mellowsoon 2012-03-10 18:54:49

0

你如何运行你的测试?你打电话TestCache::testSet()其次TestCache::testGet()assertTrue()assertEquals()做什么?他们是否使用异常来打破当前的执行路径?如果不是,那将是例如组相互依赖测试的好方法,如果Test::assertTrue()实现像这样:

public function assertTrue($value, $method = "") 
{ 
    if ($value !== true) 
    { 
     throw new Exception("assertTrue() failed on $method, Value $value does not evaluate to true"); 
    } 
} 

然后,夫妻的测试,像这样(内部测试集()& testGet()通过方法名“缓存::集”或“缓存::得到”的断言功能:现在

try 
{ 
    TestCache::testSet(); 
    TestCache::testGet(); 
} 
catch ($e) 
{ 
    echo("Failed - " . $e->getMessage()); 
} 

,如果testSet()失败,则执行跳过testGet()