在PHPUnit测试失败时,将显示实际值和期望值.
但是当测试通过时,不会显示此信息.
如何强制PHPUnit始终显示预期和实际的断言结果?
我正在尝试使用PHPunit关注单元测试.
我在这里找到了一个非常好的教程http://blog.nickbelhomme.com/php/phpunit-training-course-for-free_282
但是有些东西我想念并且还不知道该怎么做.
我有一个用户模块,它维护有关用户的所有信息.还有一个功能保存功能可以将用户保存在数据库中.所以我有一个testFunction
public function testCanCreateUser()
{
$userData = array(
'userName' => 'User1',
'firstName' => 'Joey',
'lastName' => 'Hendricks',
'email' => 'Joey@hendricks.com',
'password' => 'f$tfe8F'
);
$user = new Model_User($userData);
$user->save();
}
Run Code Online (Sandbox Code Playgroud)
我将第一次参加我的测试.由于数据库是空的.但是当我第二次运行我的测试时它将无法工作,因为我的系统不允许同一个用户在数据库中两次.所以为了做到这一点,我必须在每次运行测试之前重新创建我的testdatabase.做这个的最好方式是什么?或者这个问题是以不同的方式解决的吗?
TNX.
我一直试图解决这个问题很长一段时间.
我有一个简单的PHPUnit测试用例,包含2个测试.当我运行它时,我得到这个输出:
PHPUnit 3.5.14 by Sebastian Bergmann.
.
Run Code Online (Sandbox Code Playgroud)
所以第一个断言运行,传递.然而,第二个断言导致一些PHP错误(异常或其他),并且PHPUnit只是在没有任何关于可能出错的信息的情况下死掉.
这是我的phpunit.xml:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="true"
syntaxCheck="false"
bootstrap="bootstrap.php.cache"
>
<testsuites>
<testsuite name="Portal Test Suite">
<directory>../src/OneSolution/Portal/*Bundle/Tests</directory>
</testsuite>
</testsuites>
</phpunit>
Run Code Online (Sandbox Code Playgroud)
设置syntaxCheck为true不提供有关错误的任何其他信息.但是,它确实打印了两次(在运行任何测试之前)The filename, directory name, or volume label syntax is incorrect.
???
那么,有没有人有任何想法我可以做些什么来使PHPUnit报告这些错误消息(该--verbose选项也没有帮助)?
编辑:我发现了导致测试失败的原因.有一个错误的方法名称(我猜太依赖于代码辅助).但是,这并不能解决主要问题.任何警告,错误或异常都不会被PHPUnit报告.
我正在使用php undercontrol和代码浏览器报告每个setter/getter上的一些CRAP索引错误,即这样的代码
public function getFoo()
{
return $this->_foo;
}
Run Code Online (Sandbox Code Playgroud)
getter/setter由单元测试覆盖,复杂性为none,因为没有if/for/switch/foreach.那么为什么我得到该代码的CRAP索引为1?
PS:自我回答可能是因为复杂性没有,但我的主要问题是每个getter/setter因为CRAP索引而生成警告所以无论如何都要告诉phpunit/php代码覆盖率使CRAP等于0表示功能具有0复杂度指数.
在phpunit中我们可以指定特别调用的方法
->with($this->equalTo('foobar'))
Run Code Online (Sandbox Code Playgroud)
或任何
->with($this->anything())
Run Code Online (Sandbox Code Playgroud)
参数.
但是有没有办法指定该方法在没有参数的情况下被调用?
这是我期望失败的测试:
public function testZ()
{
$a = $this->getMock('q');
$a->expects($this->once())
->method('z')
->with(); // <--- what constraint to specify here?
$a->z(1);
}
Run Code Online (Sandbox Code Playgroud)
UPD:
这个问题具有理论性质,所以我没有任何现实生活的例子.在某些情况下,我现在可以想到的是:
public function testMe($object)
{
$object->foo();
}
Run Code Online (Sandbox Code Playgroud)
我们假设testMe应该(通过设计和需求)总是调用没有参数的方法(假设foo()有默认值).因为在这种情况下任何非默认参数(更精确:任何参数!=默认参数,我们还不知道,哪些可能可以独立改变)会导致致命的后果.
使用PHPUnit,我想知道我们是否可以模拟一个对象来测试是否使用期望参数和返回值调用方法?
在doc中,有一些传递参数或返回值的示例,但不是两者都有 ...
我试过用这个:
// My object to test
$hoard = new Hoard();
// Mock objects used as parameters
$item = $this->getMock('Item');
$user = $this->getMock('User', array('removeItem'));
...
$user->expects($this->once())
->method('removeItem')
->with($this->equalTo($item));
$this->assertTrue($hoard->removeItemFromUser($item, $user));
我的断言失败,因为Hoard :: removeItemFromUser()应该返回User :: removeItem()的返回值,这是真的.
$user->expects($this->once())
->method('removeItem')
->with($this->equalTo($item), $this->returnValue(true));
$this->assertTrue($hoard->removeItemFromUser($item, $user));
也失败并显示以下消息:" 调用User :: removeItem(Mock_Item_767aa2db Object(...))的参数计数太低. "
$user->expects($this->once())
->method('removeItem')
->with($this->equalTo($item)) … 我试图在PHPUnit中运行测试并得到此错误.
致命错误:/opt/lampp/lib/php/PHPUnit/Util/PHP.php:237中带有消息'Class __PHP_Incomplete_Class没有unserializer'的未捕获异常'ErrorException'
PHP - 5.4.7
PHPUnit - 3.7.21
Run Code Online (Sandbox Code Playgroud)
PHPUnit设置:
processIsolation = "true"
Run Code Online (Sandbox Code Playgroud)
提前致谢.
我正在为Symfony2项目进行测试,现在我正在寻找一种方法来创建涉及实体对象的测试而不会持久化它们.问题是:id是一个私有字段,没有setter.我可以创建新对象并设置一些属性,但我无法测试涉及getId()调用的任何内容.
$entity = new TheEntity();
// Can't set ID!
$entity->setProperty('propertyValue');
$name = $entity->getProperty(); // OK
$id = $entity->getId(); // not OK - null
Run Code Online (Sandbox Code Playgroud)
我所知道的决议:
建议的处理方法是什么,如何使用set ID以干净,快速的方式获取实体进行测试?
编辑
原来我可以用嘲笑来解决这个问题......对不起,我还在学习.我一直在寻找一种干净,标准,快速的方法来完成任务.但是我忘记了第二个参数getMock()- 也就是说我不必模拟我将要使用的实体的每个方法.我想避免多个->expects()->method()->will()等等.这是通过添加:array('getId').这个辅助方法解决了这个问题:
protected function getEntityMock($entityClass, $id)
{
$entityMock = $this->getMock($entityClass, array('getId'));
$entityMock
->expects($this->any())
->method('getId')
->will($this->returnValue($id));
return $entityMock;
}
Run Code Online (Sandbox Code Playgroud)
当创建同一个类的许多实体时,事情当然可以通过更多辅助方法来简化,例如:
protected function getTheEntityMock($id)
{
return $this->getEntityMock('\The\NameSpace\TheEntity', $id);
}
Run Code Online (Sandbox Code Playgroud)
唯一的限制是实体本身不能使用 …
我正在使用Codeception进行Laravel 4 PHP应用程序的单元,功能和验收测试.
我的单元测试看起来如下:
use Codeception\Util\Stub;
class ExampleTest extends \Codeception\TestCase\Test
{
public function testExample()
{
$example = true;
$this->assertSame($example, true);
}
}
Run Code Online (Sandbox Code Playgroud)
我的功能测试看起来像这样:
use \TestGuy;
class ExampleCest
{
public function example(TestGuy $I)
{
$I->amOnPage('/auth/login');
$I->see('Sign in');
}
}
Run Code Online (Sandbox Code Playgroud)
但我也想在我的功能测试中使用PHPUnit断言方法.但是当我尝试时,我得到了这个错误:
调用未定义的方法ExampleCest :: assertSame()
如何在Codeception功能测试中使用PHP断言方法?
所以我想从我的Testsuite中排除一个directoy就像这样:
<testsuite name="PHPUnitWillKillMe">
<directory>src/*/Bundle/*/*Bundle/Tests</directory>
<exclude>src/*/Bundle/*/*Bundle/Tests/Controller/</exclude>
</testsuite>
Run Code Online (Sandbox Code Playgroud)
应该测试除控制器之外的所有东西.
问题是,它不起作用.当我运行时,PHPUnit仍然在src// Bundle //*Bundle/Tests/Controller /中运行所有测试
phpunit --testsuite PHPUnitWillKillMe
Run Code Online (Sandbox Code Playgroud)
任何的想法?
最好的祝福!
我测试的PHPUnit版本是3.7.21和3.7.28.
phpunit ×10
php ×8
unit-testing ×5
symfony ×3
testing ×2
codeception ×1
doctrine-orm ×1
lamp ×1
metrics ×1
mocking ×1