我一直在使用PhpUnit,效果很好,仅使用断言测试我的代码。最近我决定尝试PhpUnit进行覆盖率报告分析,但我注意到使用dataProvider方法的测试往往会降低我的代码覆盖率。我想知道我可能做错了什么或者这是否是dataProvider测试技术的结果?我正在使用PhpUnit 6和Php 7。
我已经包含了一个源类Foo,下面有三个测试类来测试它。 FooTest使用常规测试方法,没有dataProviders。 BarTest使用带有@codeCoverageIgnore注释的dataProvider方法,而BazTest使用没有注释的dataProvider方法。
您可以通过BazTest查看代码覆盖率得分如何降低。
Foo.php
namespace phpunittestproject\src;
/**
* Foo
*
* This is a simple class to be used as a source file
* in unit test experiments. It gets and sets a name
* string and date object.
*
*/
class Foo
{
/**
* Name
*
* String characters other than numeric.
*
* @var string
*/
private $name = null;
/**
* Date
*
* Date no older than 2000.
*
* @var \DateTime
*/
private $date = null;
/**
* Constructor
*
* Sets instance vars.
*
*/
public function __construct()
{
$this->name = '';
$this->date = new \DateTime('now');
}
/**
* Get Date
*
* @return DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Get Name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set Date
*
* This method accepts a DateTime object that corresponds
* to a date no earlier than 2000.
*
* @param \DateTime $value Date after 2000.
* @return boolean Result of operation.
*/
public function setDate(\DateTime $value)
{
if($value < new \DateTime('2000-01-01 00:00:00')){
return false;
} else {
$this->date = $value;
return true;
}
}
/**
* Set Name
*
* This method accepts a string that does not contain numeric
* characters.
*
* @param string $value String without numeric characters.
* @return boolean Result of operation.
*/
public function setName(string $value)
{
if(preg_match('/\\d/', $value)){
return false;
} else {
$this->name = $value;
return true;
}
}
}
FooTest.php:
declare(strict_types = 1);
namespace phpunittestproject\test;
use \phpunittestproject\src\Foo;
/**
*
* Foo Test
*
* This test class does not use dataProvider methods. All
* test assertions are being done in test metods.
*
*/
class FooTest extends \PHPUnit\Framework\TestCase
{
/**
*
*
*/
public function testGetDate()
{
$foo = new Foo();
// Good date:
$date = new \DateTime('2011-01-01 11:11:11');
$foo->setDate($date);
$this->assertEquals($date, $foo->getDate());
// Bad date:
$date = new \DateTime('1990-01-01 11:11:11');
$foo->setDate($date);
$this->assertNotEquals($date, $foo->getDate());
}
/**
*
*
*/
public function testGetName()
{
$foo = new Foo();
// Good name:
$foo->setName('A Good Name');
$this->assertEquals('A Good Name', $foo->getName());
// Bad name:
$foo->setName('Bad Name 666');
$this->assertNotEquals('Bad Name 666', $foo->getName());
}
/**
* Test setDate()
*
* This test method tests the date property when it is
* set with good and bad data using method setDate().
*
*/
public function testSetDate()
{
$foo = new Foo();
// Good date:
$date = new \DateTime('2011-01-01 11:11:11');
$foo->setDate($date);
$this->assertAttributeEquals($date, 'date', $foo);
// Bad date:
$date = new \DateTime('1990-01-01 11:11:11');
$foo->setDate($date);
$this->assertAttributeNotEquals($date, 'date', $foo);
}
/**
*
* Test setName()
*
* This test method tests the name property when it is
* set with good and bad data using method setName().
*
*
*/
public function testSetName()
{
$foo = new Foo();
// Good name:
$foo->setName('Good Name');
$this->assertAttributeEquals('Good Name', 'name', $foo);
// Bad name:
$foo->setName('Bad Name 666');
$this->assertAttributeNotEquals('', 'name', $foo);
}
}
BarTest.php:
declare(strict_types = 1);
namespace phpunittestproject\test;
use \phpunittestproject\src\Foo;
/**
*
* Bar Test
*
* This test class utilizes dataProvider methods to feed
* test methods. The dataProvider methods are annotated
* with codeCoverageIgnore.
*
*/
class BarTest extends \PHPUnit\Framework\TestCase
{
/**
*
* @codeCoverageIgnore
*/
public function providerTestSetDateWithInvalidData()
{
return array(
array(new \DateTime('1990-01-01 11:11:11')),
);
}
/**
*
* @codeCoverageIgnore
*/
public function providerTestSetDateWithValidData()
{
return array(
array(new \DateTime('2011-01-01 11:11:11')),
);
}
/**
*
* @codeCoverageIgnore
*/
public function providerTestSetNameWithInvalidData()
{
return array(
array('Bad Name 666'),
);
}
/**
*
* @codeCoverageIgnore
*/
public function providerTestSetNameWithValidData()
{
return array(
array('Good Name'),
);
}
/**
*
*
*/
public function testGetDate()
{
$foo = new Foo();
$date = new \DateTime('2001-01-01 11:11:11');
$foo->setDate($date);
$this->assertEquals($date, $foo->getDate());
}
/**
*
*
*/
public function testGetName()
{
$foo = new Foo();
$foo->setName('A Good Name');
$this->assertEquals('A Good Name', $foo->getName());
}
/**
*
* @dataProvider providerTestSetDateWithInvalidData
*
*
*/
public function testSetDateWithInvalidData($value)
{
$foo = new Foo();
$foo->setDate($value);
$this->assertAttributeNotEquals($value, 'date', $foo);
}
/**
*
* @dataProvider providerTestSetDateWithValidData
*
*
*/
public function testSetDateWithValidData($value)
{
$foo = new Foo();
$foo->setDate($value);
$this->assertAttributeEquals($value, 'date', $foo);
}
/**
*
* @dataProvider providerTestSetNameWithInvalidData
*
*
*/
public function testSetNameWithInvalidData($value)
{
$foo = new Foo();
$foo->setName($value);
$this->assertAttributeNotEquals($value, 'name', $foo);
}
/**
*
* @dataProvider providerTestSetNameWithValidData
*
*
*/
public function testSetNameWithValidData($value)
{
$foo = new Foo();
$foo->setName($value);
$this->assertAttributeEquals($value, 'name', $foo);
}
}
BazTest.php:
declare(strict_types = 1);
namespace phpunittestproject\test;
use \phpunittestproject\src\Foo;
/**
*
* Baz Test
*
* This test class utilizes dataProvider methods to feed
* test methods. The dataProvider methods are not annotated
* with codeCoverageIgnore.
*
*/
class BazTest extends \PHPUnit\Framework\TestCase
{
/**
*
*
*/
public function providerTestSetDateWithInvalidData()
{
return array(
array(new \DateTime('1990-01-01 11:11:11')),
);
}
/**
*
*
*/
public function providerTestSetDateWithValidData()
{
return array(
array(new \DateTime('2011-01-01 11:11:11')),
);
}
/**
*
*
*/
public function providerTestSetNameWithInvalidData()
{
return array(
array('Bad Name 666'),
);
}
/**
*
*
*/
public function providerTestSetNameWithValidData()
{
return array(
array('Good Name'),
);
}
/**
*
*
*/
public function testGetDate()
{
$foo = new Foo();
$date = new \DateTime('2001-01-01 11:11:11');
$foo->setDate($date);
$this->assertEquals($date, $foo->getDate());
}
/**
*
*
*/
public function testGetName()
{
$foo = new Foo();
$foo->setName('A Good Name');
$this->assertEquals('A Good Name', $foo->getName());
}
/**
*
* @dataProvider providerTestSetDateWithInvalidData
*
*
*/
public function testSetDateWithInvalidData($value)
{
$foo = new Foo();
$foo->setDate($value);
$this->assertAttributeNotEquals($value, 'date', $foo);
}
/**
*
* @dataProvider providerTestSetDateWithValidData
*
*
*/
public function testSetDateWithValidData($value)
{
$foo = new Foo();
$foo->setDate($value);
$this->assertAttributeEquals($value, 'date', $foo);
}
/**
*
* @dataProvider providerTestSetNameWithInvalidData
*
*
*/
public function testSetNameWithInvalidData($value)
{
$foo = new Foo();
$foo->setName($value);
$this->assertAttributeNotEquals($value, 'name', $foo);
}
/**
*
* @dataProvider providerTestSetNameWithValidData
*
*
*/
public function testSetNameWithValidData($value)
{
$foo = new Foo();
$foo->setName($value);
$this->assertAttributeEquals($value, 'name', $foo);
}
}
phpunit.xml:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" bootstrap="./vendor/autoload.php">
<testsuites>
<testsuite name="DataProviderTestSuite">
<file>phpunittestproject/test/FooTest.php</file>
<file>phpunittestproject/test/BarTest.php</file>
<file>phpunittestproject/test/BazTest.php</file>
</testsuite>
</testsuites>
<filter>
<whitelist>
<file>phpunittestproject/test/FooTest.php</file>
<file>phpunittestproject/test/BarTest.php</file>
<file>phpunittestproject/test/BazTest.php</file>
</whitelist>
</filter>
</phpunit>
答案 0 :(得分:0)
感谢@Christopher的解决方案!错误配置的phpunit.xml文件导致PhpUnit测试测试。编辑白名单元素修复了低代码覆盖率分数。 dataProvider方法不需要使用@codeCoverageIgnore注释!
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" bootstrap="./vendor/autoload.php">
<testsuites>
<testsuite name="DataProviderTestSuite">
<!-- Test files go here: -->
<file>phpunittestproject/test/FooTest.php</file>
<file>phpunittestproject/test/BarTest.php</file>
<file>phpunittestproject/test/BazTest.php</file>
</testsuite>
</testsuites>
<filter>
<whitelist>
<!-- Source files to be tested go here: -->
<file>phpunittestproject/src/Foo.php</file>
</whitelist>
</filter>
</phpunit>