PHPUnit + Xdebug 单元测试技术
Upcoming SlideShare
Loading in...5
×
 

PHPUnit + Xdebug 单元测试技术

on

  • 3,863 views

PHPUnit + Xdebug 单元测试技术推广 Keynote。

PHPUnit + Xdebug 单元测试技术推广 Keynote。

Statistics

Views

Total Views
3,863
Slideshare-icon Views on SlideShare
3,169
Embed Views
694

Actions

Likes
0
Downloads
39
Comments
0

4 Embeds 694

http://rdc.hoopchina.com 514
http://soplwang.com 167
http://rdc.hupu.com 8
http://cache.baidu.com 5

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    PHPUnit + Xdebug 单元测试技术 PHPUnit + Xdebug 单元测试技术 Presentation Transcript

    • PHPUnit + Xdebug单元测试技术
      ——提升编码质量的工具和方法
    • 讨论的主题
      PHPUnit单元测试技术
      Xdebug调试
    • 声明
      这仅是一个宣传、引导
      会写测试并提升了 工作质量、减少返工次数 的程序员,牧师 老大说了,会更容易得到管理层的奖励和青睐
    • 如何测试…
      测试基础
    • 一个例子: Stack.php
      <?php
      classStack
      {
      private $store;
      publicfunction__construct() {
      $this->store = array();
      }
      publicfunctionpush($o) {
      array_push($this->store, $o);
      }
      publicfunctionpop() {
      returnarray_pop($this->store);
      }
      publicfunctioncount() {
      returncount($this->store);
      }
      }
    • 如何保证正确性?
      手眼测试…
      在程序底部添加一些测试语句
      $stack = new Stack;
      if ($stack) {
      echo $stack->count();
      $stack->push(1111);
      echo $stack->count();
      echo $stack->pop();
      echo $stack->count();
      }
    • 测试成功后…
      剔除/注释 掉这些语句…
    • 下一次再修改时…
      重新加上这些测试语句, 并再次测试
      回归测试
    • 问题是…
      每次修改都要重新加上这些测试, 以验证没有(未预期地) 破坏原有功能…
      好吧, 为何不把测试独立出来呢?
    • 好主意!!
      把测试独立成一个文件, 每次执行一下即可
      无需再做 剔除/注释 – 加上/反注释 工作了
      StackTest.php
      -------------------------------------------------------------------------------------------
      <?php
      require_once ‘./Stack.php’;
      $stack = new Stack;
      if ($stack) {
      echo $stack->count();
      $stack->push(1111);
      echo $stack->count();
      echo $stack->pop();
      echo $stack->count();
      }
    • 新问题是…
      每次都要 手眼测试, 太累了!!!
      呣, 有没有办法让 机器 去做?
      然后自己就有时间去 把妹子…
    • PHPUnit来帮忙
      <?php
      require_once'./Stack.php';
      class StackTestextends PHPUnit_Framework_TestCase
      {
      public function testCanPushAndPop() {
      $stack = new Stack();
      $this->assertEquals(0, $stack->count());
      $stack->push('foo');
      $this->assertEquals(1, $stack->count());
      $this->assertEquals('foo', $stack->pop());
      $this->assertEquals(0, $stack->count());
      }
      }
    • 执行测试
      $ phpunitStackTest
    • 执行测试
      成功时:
    • 执行测试
      失败时:
    • - 互动演示 -
    • Stack 增加新功能时…
      <?php
      classStack
      {
      private $store;
      publicfunction__construct() {
      $this->store = array();
      }
      publicfunctionpush($o) {
      array_push($this->store, $o);
      }
      publicfunctionpop() {
      returnarray_pop($this->store);
      }
      publicfunctioncount() {
      returncount($this->store);
      }
      public function clean() {
      $this->store = array();
      }
      }
    • <?php
      require_once'./Stack.php';
      class StackTestextends PHPUnit_Framework_TestCase
      {
      public function testCanPushAndPop() {
      $stack = new Stack();
      $this->assertEquals(0, $stack->count());
      $stack->push('foo');
      $this->assertEquals(1, $stack->count());
      $this->assertEquals('foo', $stack->pop());
      $this->assertEquals(0, $stack->count());
      }
      public function testCanClean() {
      $stack = new Stack();
      $stack->push('foo');
      $this->assertEquals(1, $stack->count());
      $stack->clean();
      $this->assertEquals(0, $stack->count());
      }
      }
      也要增加新测试…
    • - 互动演示 -
    • xUnit方法的优势
      减少验证 ‘代码正确性’ 的工作量
      自动化回归测试
      避免系统退步
      写测试用例可以促使程序员发现边界条件
      测试用例本身就是很好的示范代码和文档
      写测试用例可以促使程序员真正了解需求
      完备的测试可以给程序员以信心
      More…
    • 什么是测试?
      测试是一组输入、执行条件以及预期结果的集合
      一组断言
      测试是一个产品的详细接口规格
      如何调用,结果值会是如何,etc.
      测试定义产品的每一个面
      测试是…
      这一页 PPT 本身就是个测试…
    • 鸭子
      “When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.”
      James Whitcomb Riley (1849 – 1916)
      (Duck typing)

    • “人就是以为自己不是机器的机器”
      Wang Wenlin (1981 – ∞)
      以为自己不是机器的机器, 是人…
    • 框架中的测试
      Zend Framework & Symfony 1
    • 良好的测试支持
      Zend Framework 集成 PHPUnit支持
      Symfony 1 使用自己的 Lime 测试框架
      Symfony 2 已改用 PHPUnit …
      它们都能自动生成 功能测试 骨架…
    • Zend Framework 示例
      $ zf create project demo
      $ zf create controller foo
      $ phpunit
    • Zend Framework 示例
      <?php
      classIndexControllerTestextendsZend_Test_PHPUnit_ControllerTestCase
      {

      publicfunctiontestIndexAction()
      {
      $params = array('action' => 'index', 'controller' => 'Index', 'module' => 'default');
      $urlParams = $this->urlizeOptions($params);
      $url = $this->url($urlParams);
      $this->dispatch($url);
      // assertions
      $this->assertModule($urlParams['module']);
      $this->assertController($urlParams['controller']);
      $this->assertAction($urlParams['action']);
      $this->assertQueryContentContains("div#welcome h3", "This is your project's main page");
      }
      }
    • - 互动演示 -
    • Symfony示例
      $ symfonygenerate:project demo
      $ symfonygenerate:appfoo
      $ symfonygenerate:modulefoo bar
      $ symfonytest:all
      $ symfonytest:functionalfoo
    • Symfony示例
      <?php
      include(dirname(__FILE__).'/../../bootstrap/functional.php');
      $browser = newsfTestFunctional(new sfBrowser());
      $browser->
      get('/content/index')->
      with('request')->begin()->
      isParameter('module', 'content')->
      isParameter('action', 'index')->
      end()->
      with('response')->begin()->
      isStatusCode(200)->
      checkElement('body', '!/This is a temporary page/')->
      end()
      ;
    • - 互动演示 -
    • 好消息…
      功能测试脚本, 测试组会帮忙制作…
      程序员只需做单元测试
    • PHPUnit还能做什么…
    • 代码覆盖报告
      $ phpunit --coverage-html covStackTest
      代码覆盖报告,一种调试工具。
    • - 互动演示 -
    • 生成规格文档
      $ phpunit --testdoxStackTest
      测试 即是 定义。
    • 生成规格文档
    • - 互动演示 -
    • 测试失败时…
      Xdebug来帮忙
    • Xdebug出场…
      简便的 PHP 调试、跟踪 和 剖析 工具
      我们主要用它的 远程调试功能
    • 如何调试一个测试?
      $ export XDEBUG_CONFIG="remote_host=192.168.8.91idekey=netbeans-xdebug"
      ## plain old php
      $ phpunitStackTest
      ## zend framework
      $ phpunit application/controllers/FooControllerTest
      ## symfony 1
      $ symfonytest:functionalfoo
    • 断点
      单步
      上下文
    • - 互动演示 -
    • Xdebug的其它能力…
      跟踪 (Trace)
      性能剖析 (Profile)
    • 一点疑惑
    • 断言… 可以吗?
      这种定义事物的方式可能并不充分
      但至少是必要的
      可是仍然是不够充分…
      世界上从来没有 ‘完全充分’,就像合同不够充分,法律不会完美一样
      我们的目标是测试案例能覆盖到所有的代码路径即可
    • 测试不是测试组的事吗?
      单元测试 习惯上、实践上 是 程序员写的
      只有程序员自己知道怎么测…
      而且,它也是一种调试工具
      功能测试 习惯上 是 测试组 来做
      但仍然需要程序员的紧密配合
    • 最后…
    • …谢谢!!