PHPUnit 单元测试简介

来源:互联网 发布:伏羲距今多少年 知乎 编辑:程序博客网 时间:2024/04/27 16:27

安装

可以通过pear安装:

$pear channel-discover pear.phpunit.de$pear channel-discover pear.symfony-project.com$pear install phpunit
可以下载包:

wget https://phar.phpunit.de/phpunit.phar chmod +x phpunit.pharmv phpunit.phar /usr/local/bin/phpunit

先看一个例子:

require_once('UserStore.php');require_once('PHPUnit/Framework/TestCase.php');class UserStoreTest extends PHPUnit_Framework_TestCase {    private $store;    public function setUp() {        $this->store = new UserStore();    }    public function testAddUser_ShortPass() {        $this->setExpectedException('Exception');         $this->store->addUser(  "bob williams", "a@b.com", "ff" );        $this->fail("Short password exception expected");    }    public function  testGetUser() {        $this->store->addUser(  "bob williams", "a@b.com", "12345" );        $user = $this->store->getUser(  "a@b.com" );        $this->assertEquals( $user['mail'], "a@b.com" );        $this->assertEquals( $user['name'], "bob williams" );        $this->assertEquals( $user['pass'], "12345" );    }    public function tearDown() {}}
setUp()方法会在每一个测试方法前自动调用.可以设立一个测试环境.

tearDown()方法会在每个测试方法运行后被调用. 

测试方法名必须是"test"开头的,或者 加了@test修饰符

断言方法

断言是判断系统中某个假设是否成立的语句或者方法,上例中assertEquals()就是一个断言方法. 除此之外还有:

assertArrayHasKey()
assertClassHasAttribute()
assertClassHasStaticAttribute()
assertContains()
assertContainsOnly()
assertContainsOnlyInstancesOf()
assertCount()
assertEmpty()
assertEqualXMLStructure()
assertEquals()
assertFalse()
assertFileEquals()
assertFileExists()

....

具体可以参考手册.


测试异常

上例中的$this->setExpectedException('Exception');  指定了期望抛出的异常类型. 这个方法是PHPUnit_Extensions_ExceptionTestCase的方法, 他是phpunit的扩展类.


运行测试套件

把写好的测试类放到一个目录下然后

$phpunit test/

约束

public function  testAddUser_duplicate() {            try {                $ret = $this->store->addUser(  "bob williams", "a@b.com", "123456" );                $ret = $this->store->addUser(  "bob stevens", "a@b.com", "123456" );                self::fail( "Exception should have been thrown" );            } catch ( Exception $e ) {                $const = $this->logicalAnd(                            //$this->logicalNot( $this->contains("bob stevens")),                             $this->isType('object')                         );                self::AssertThat( $this->store->getUser( "a@b.com"), $const );            }    }
约束的实现用断言也可以实现,  约束的有点是逻辑清晰, 而且可以复用.

常用的约束方法:

PHPUnit_Framework_Constraint_Attribute attribute(PHPUnit_Framework_Constraint $constraint, $attributeName)
PHPUnit_Framework_Constraint_IsAnything anything()
PHPUnit_Framework_Constraint_ArrayHasKey arrayHasKey(mixed $key)
PHPUnit_Framework_Constraint_TraversableContains contains(mixed $value)

......


模拟与桩

所谓桩就是stub, 可以理解为占位的伪造的假对象, 它可以使你关注要测试的类本身,而不是整个系统, 免受外部环境影响.

stub对象只是占位, 而mock对象还关注于对行为的预期.

public function testValidate_FalsePass() {        $store = $this->getMock("UserStore");        $this->validator = new Validator( $store );        $store->expects($this->once() )              ->method('notifyPasswordFailure')              ->with( $this->equalTo('bob@example.com') );        $store->expects( $this->any() )              ->method("getUser")              ->will( $this->returnValue(new User( "bob williams", "bob@example.com", "right")));        $this->validator->validateUser("bob@example.com", "wrong"); /*        $store = $this->getMock("UserStore");        $store->expects( $this->once() )              ->method('notifyPasswordFailure');        //$store->expects( $this->at( 1 ) ) // raise bug        $store->expects( $this->once( ) )              ->method("getUser")              ->with( $this->equalTo('henry') );*/        //$store->getUser("bob@bob.com");    } 


0 0
原创粉丝点击