PHPUnit学习笔记

PHPUnit学习笔记

PHPUnit是一个轻量级的PHP测试框架。它是在PHP5下面对JUnit3系列版本的完整移植,是xUnit测试框架家族的一员(它们都基于模式先锋Kent Beck的设计)

PHPUnit 编写测试的基本惯例与步骤

  1. 针对类 Class 的测试写在类 ClassTest中。

  2. ClassTest(通常)继承自 PHPUnit_Framework_TestCase。

  3. 测试都是命名为 test* 的公用方法。

  4. 也可以在方法的文档注释块(docblock)中使用 @test 标注将其标记为测试方法。

  5. 在测试方法内,类似于 assertEquals()这样的断言方法用来对实际值与预期值的匹配做出断言。

例:用 PHPUnit 测试数组操作
<pre>
<?php class StackTest extends PHPUnit_Framework_TestCase { public function testPushAndPop() { $stack = array(); $this->assertEquals(0, count($stack)); array_push($stack, 'foo'); $this->assertEquals('foo', $stack[count($stack)-1]); $this->assertEquals(1, count($stack)); $this->assertEquals('foo', array_pop($stack)); $this->assertEquals(0, count($stack)); } /** * 定义test标签声明改方法是测试方法 * @test */ public function indexEquals() { $stack = array(1,2,3,4); $this->assertEquals(2,$stack[0]); //失败 } } ?>
</pre>

  • 通俗的讲,单元测试就是在测试用例类中,定义一系列的测试方法,在方法中使用断言(assert)来测试你程序中的相关函数、类、接口、过程的执行结果是否和你预期的是一样的,
  • 如果某个部分的执行结果没有与你期待的结果相同,PHPUnit就会向你报告问题,你也可以方便的根据报告确认和修复程序中的Bug。针对你的程序写好详细的完整单元测试,你就不用每次完成一个新功能后逐个的测试你软件的所有功能,而且在程序发布之前,你至少可以通过测试消灭大部分的内部逻辑Bug和缺陷。
  • 同样,你在之后的维护开发中,如果在某个功能的修改中不小心改坏了与其相关连的其他模块,那么先前完善的单元测试也会向你报告出相关的问题让你及时发现和修复问题。

测试方法间的依赖关系

  • 测试方法并不一定非要是一个封装良好的独立实体。测试方法之间经常有隐含的依赖关系暗藏在测试的实现方案中。
  • 依赖关系通过注释@depends来定义.这个特性一般用于检查代码的逻辑过程,一个逻辑的执行前提是另外一个逻辑的执行结果

例:用 @depends 标注来表达依赖关系

<?php
class StackTest extends PHPUnit_Framework_TestCase
{
   public function testEmpty()
   {
       $stack = array();
       $this->assertEmpty($stack);
       return $stack;
   }
   /**
    * @depends testEmpty
    */
   public function testPush(array $stack)
   {
       array_push($stack, 'foo');
       $this->assertEquals('foo', $stack[count($stack)-1]);
       $this->assertNotEmpty($stack);
       return $stack;
   }
   /**
    * @depends testPush
    */
   public function testPop(array $stack)
   {
       $this->assertEquals('foo', array_pop($stack));
       $this->assertEmpty($stack);
   }
}
?>
  • 只要断言检查没有出现异常,那么PHPUnit就会根据依赖关系依次执行依赖的测试方法,直到依赖关系结束为止.
  • 为了方便快速的确定问题的所在,如果某个测试方法依赖的方法测试没有功过,那么PHPUnit会自动跳过后面所有的依赖测试.

*** 拥有多个 @depends 标注的测试,其第一个参数是第一个生产者提供的基境,第二个参数是第二个生产者提供的基境,以此类推 ***
<pre>
<?php class MultipleDependenciesTest extends PHPUnit_Framework_TestCase { public function testProducerFirst() { $this->assertTrue(true); return 'first'; } public function testProducerSecond() { $this->assertTrue(true); return 'second'; } /** 多重依赖 * @depends testProducerFirst * @depends testProducerSecond */ public function testConsumer() { $this->assertEquals( array('first', 'second'), func_get_args() ); } } ?>
</pre>

数据供给器

  • 某个测试方法没有依赖的方法,我们怎么给它传入参数做测试呢?PHPUnit给我们提供了数据提供者方法来为测试方法传入数据.测试方法可以接受任意参数。这些参数由数据供给器方法提供。用 @dataProvider 标注来指定使用哪个数据供给器方法。
  • 数据提供者方法返回数据的格式: 需要返回的是2维数组,第二维数组值的位置,对应测试方法参数的位置,参数个数和数组长度要相等,否则PHPUnit会报错

例:使用返回数组的数组的数据供给器
<pre>
<?php class DataTest extends PHPUnit_Framework_TestCase { /** *@dataProvider additionProvider */ public function testAdd($a, $b, $expected) { $this->assertEquals($expected, $a + $b); } public function additionProvider() { return array( array(0, 0, 0), array(0, 1, 1), array(1, 0, 1), array(1, 1, 3) ); } } ?>
</pre>

  • 如果测试同时从 @dataProvider 方法和一个或多个 @depends 测试接收数据,那么来自于数据供给器的参数将先于来自所依赖的测试的。来自于所依赖的测试的参数对于每个数据集都是一样的。

例:
<pre>
<?php class DependencyAndDataProviderComboTest extends PHPUnit_Framework_TestCase { public function provider() { return array( array('provider1'), array('provider2')); } public function testProducerFirst() { $this->assertTrue(true); return 'first'; } public function testProducerSecond() { $this->assertTrue(true); return 'second'; } /** * @depends testProducerFirst * @depends testProducerSecond * @dataProvider provider */ public function testConsumer() { $this->assertEquals( array('provider1', 'first', 'second'), func_get_args() ); } } ?>
</pre>
** 结果:Tests: 4, Assertions: 4, Failures: 1. **

@depends @dataProvider
@dataProvider 是一个二维数组, 有多少个第二纬的数组就测试多少次,第二纬的数组和参数一致
@depends 生产者(producer)返回一个测试基境(fixture)的实例,并将此实例传递给依赖于它的消费者(consumer)们。二者同时存在的话先进行@dataProvider

对异常进行测试

例:
<pre>
<?php class ExceptionTest extends PHPUnit_Framework_TestCase { public function testException() { $this->expectException(InvalidArgumentException::class); } } ?>
</pre>

  • 使用 @expectedException 标注
    <pre>
    `
    <?php
    class ExceptionTest extends PHPUnit_Framework_TestCase
    {
    /**
    • @expectedException InvalidArgumentException
      */
      public function testException()
      {
      }
      }
      ?>
      `
      </pre>

对输出进行测试

错误相关信息的输出

边缘情况

基境(fixture)

PHPUnit 支持共享建立基境的代码。在运行某个测试方法前,会调用一个名叫 setUp() 的模板方法。setUp() 是创建测试所用对象的地方。当测试方法运行结束后,不管是成功还是失败,都会调用另外一个名叫 tearDown() 的模板方法。tearDown() 是清理测试所用对象的地方。

在编写测试用例的时候可能最费时间的就是编写那些将程序设置到使用状态和测试完毕之后将其再设置回初始状态的代码了。PHPUnit给我们提供了setUp和tearDown这两个方法来解决这个问题。

测试类的每个测试方法都会运行一次 setUp() 和 tearDown() 模板方法(同时,每个测试方法都是在一个全新的测试类实例上运行的)。

setUpBeforeClass() 与 tearDownAfterClass() 模板方法将分别在测试用例类的第一个测试运行之前和测试用例类的最后一个测试运行之后调用。

组织测试

  1. 用文件系统来编排测试套件
  2. 用 XML 配置来编排测试套件
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容