PHPUnit + Xdebug单元测试技术<br />——提升编码质量的工具和方法<br />
讨论的主题<br />PHPUnit单元测试技术<br />Xdebug调试<br />
声明<br />这仅是一个宣传、引导<br />会写测试并提升了 工作质量、减少返工次数 的程序员,牧师 老大说了,会更容易得到管理层的奖励和青睐<br />
如何测试…<br />测试基础<br />
一个例子: Stack.php<br /><?php<br />classStack<br />{<br />private $store;<br />publicfunction__construct() {<br />           ...
如何保证正确性?<br />手眼测试…<br />在程序底部添加一些测试语句<br />$stack = new Stack;<br />if ($stack) {<br />echo $stack->count();<br />    $st...
测试成功后…<br />剔除/注释 掉这些语句…<br />
下一次再修改时…<br />重新加上这些测试语句, 并再次测试<br />回归测试<br />
问题是…<br />每次修改都要重新加上这些测试, 以验证没有(未预期地) 破坏原有功能…<br />好吧, 为何不把测试独立出来呢?<br />
好主意!!<br />把测试独立成一个文件, 每次执行一下即可<br />无需再做 剔除/注释 – 加上/反注释 工作了<br />StackTest.php<br />-------------------------------------...
新问题是…<br />每次都要 手眼测试, 太累了!!!<br />呣, 有没有办法让 机器 去做?<br />然后自己就有时间去 把妹子…<br />
PHPUnit来帮忙<br /><?php<br />require_once'./Stack.php';<br />class StackTestextends PHPUnit_Framework_TestCase<br />{<br />p...
执行测试<br />$ phpunitStackTest<br />
执行测试<br />成功时:<br />
执行测试<br />失败时:<br />
- 互动演示 -<br />
Stack 增加新功能时…<br /><?php<br />classStack<br />{<br />private $store;<br />publicfunction__construct() {<br />             ...
<?php<br />require_once'./Stack.php';<br />class StackTestextends PHPUnit_Framework_TestCase<br />{<br />public function t...
- 互动演示 -<br />
xUnit方法的优势<br />减少验证 ‘代码正确性’ 的工作量<br />自动化回归测试<br />避免系统退步<br />写测试用例可以促使程序员发现边界条件<br />测试用例本身就是很好的示范代码和文档<br />写测试用例可以促使程...
什么是测试?<br />测试是一组输入、执行条件以及预期结果的集合<br />一组断言<br />测试是一个产品的详细接口规格<br />如何调用,结果值会是如何,etc.<br />测试定义产品的每一个面<br />测试是…<br />这一页...
鸭子<br />“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.”<...
人<br />“人就是以为自己不是机器的机器”<br />Wang Wenlin (1981 – ∞)<br />以为自己不是机器的机器, 是人…<br />
框架中的测试<br />Zend Framework & Symfony 1<br />
良好的测试支持<br />Zend Framework 集成 PHPUnit支持<br />Symfony 1 使用自己的 Lime 测试框架<br />Symfony 2 已改用 PHPUnit …<br />它们都能自动生成 功能测试 骨架...
Zend Framework 示例<br />$ zf create project demo<br />$ zf create controller foo<br />$ phpunit<br />
Zend Framework 示例<br /><?php<br />classIndexControllerTestextendsZend_Test_PHPUnit_ControllerTestCase<br />{<br />    …<br...
- 互动演示 -<br />
Symfony示例<br />$ symfonygenerate:project demo<br />$ symfonygenerate:appfoo<br />$ symfonygenerate:modulefoo bar<br />$ sy...
Symfony示例<br /><?php<br />include(dirname(__FILE__).'/../../bootstrap/functional.php');<br />$browser = newsfTestFunctiona...
- 互动演示 -<br />
好消息…<br />功能测试脚本, 测试组会帮忙制作…<br />程序员只需做单元测试<br />
PHPUnit还能做什么…<br />
代码覆盖报告<br />$ phpunit --coverage-html covStackTest<br />代码覆盖报告,一种调试工具。<br />
- 互动演示 -<br />
生成规格文档<br />$ phpunit --testdoxStackTest<br />测试 即是 定义。<br />
生成规格文档<br />
- 互动演示 -<br />
测试失败时…<br />Xdebug来帮忙<br />
Xdebug出场…<br />简便的 PHP 调试、跟踪 和 剖析 工具<br />我们主要用它的 远程调试功能<br />
如何调试一个测试?<br />$ export XDEBUG_CONFIG="remote_host=192.168.8.91idekey=netbeans-xdebug"<br />## plain old php<br />$ phpuni...
断点<br />单步<br />上下文<br />
- 互动演示 -<br />
Xdebug的其它能力…<br />跟踪 (Trace)<br />性能剖析 (Profile)<br />
一点疑惑<br />
断言… 可以吗?<br />这种定义事物的方式可能并不充分<br />但至少是必要的<br />可是仍然是不够充分…<br />世界上从来没有 ‘完全充分’,就像合同不够充分,法律不会完美一样<br />我们的目标是测试案例能覆盖到所有的代码路...
测试不是测试组的事吗?<br />单元测试 习惯上、实践上 是 程序员写的<br />只有程序员自己知道怎么测…<br />而且,它也是一种调试工具<br />功能测试 习惯上 是 测试组 来做<br />但仍然需要程序员的紧密配合<br />
最后…<br />
…谢谢!!<br />
Upcoming SlideShare
Loading in...5
×

PHPUnit + Xdebug 单元测试技术

3,881

Published on

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

Published in: Education, Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
3,881
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
41
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

PHPUnit + Xdebug 单元测试技术

  1. 1. PHPUnit + Xdebug单元测试技术<br />——提升编码质量的工具和方法<br />
  2. 2. 讨论的主题<br />PHPUnit单元测试技术<br />Xdebug调试<br />
  3. 3. 声明<br />这仅是一个宣传、引导<br />会写测试并提升了 工作质量、减少返工次数 的程序员,牧师 老大说了,会更容易得到管理层的奖励和青睐<br />
  4. 4. 如何测试…<br />测试基础<br />
  5. 5. 一个例子: Stack.php<br /><?php<br />classStack<br />{<br />private $store;<br />publicfunction__construct() {<br /> $this->store = array();<br /> }<br />publicfunctionpush($o) {<br />array_push($this->store, $o);<br /> }<br />publicfunctionpop() {<br />returnarray_pop($this->store);<br /> }<br />publicfunctioncount() {<br />returncount($this->store);<br /> }<br />}<br />
  6. 6. 如何保证正确性?<br />手眼测试…<br />在程序底部添加一些测试语句<br />$stack = new Stack;<br />if ($stack) {<br />echo $stack->count();<br /> $stack->push(1111);<br />echo $stack->count();<br />echo $stack->pop();<br />echo $stack->count();<br />}<br />
  7. 7. 测试成功后…<br />剔除/注释 掉这些语句…<br />
  8. 8. 下一次再修改时…<br />重新加上这些测试语句, 并再次测试<br />回归测试<br />
  9. 9. 问题是…<br />每次修改都要重新加上这些测试, 以验证没有(未预期地) 破坏原有功能…<br />好吧, 为何不把测试独立出来呢?<br />
  10. 10. 好主意!!<br />把测试独立成一个文件, 每次执行一下即可<br />无需再做 剔除/注释 – 加上/反注释 工作了<br />StackTest.php<br />-------------------------------------------------------------------------------------------<br /><?php<br />require_once ‘./Stack.php’;<br />$stack = new Stack;<br />if ($stack) {<br />echo $stack->count();<br /> $stack->push(1111);<br />echo $stack->count();<br />echo $stack->pop();<br />echo $stack->count();<br />}<br />
  11. 11. 新问题是…<br />每次都要 手眼测试, 太累了!!!<br />呣, 有没有办法让 机器 去做?<br />然后自己就有时间去 把妹子…<br />
  12. 12. PHPUnit来帮忙<br /><?php<br />require_once'./Stack.php';<br />class StackTestextends PHPUnit_Framework_TestCase<br />{<br />public function testCanPushAndPop() {<br /> $stack = new Stack();<br /> $this->assertEquals(0, $stack->count());<br /> $stack->push('foo');<br /> $this->assertEquals(1, $stack->count());<br /> $this->assertEquals('foo', $stack->pop());<br /> $this->assertEquals(0, $stack->count());<br /> }<br />}<br />
  13. 13. 执行测试<br />$ phpunitStackTest<br />
  14. 14. 执行测试<br />成功时:<br />
  15. 15. 执行测试<br />失败时:<br />
  16. 16. - 互动演示 -<br />
  17. 17. Stack 增加新功能时…<br /><?php<br />classStack<br />{<br />private $store;<br />publicfunction__construct() {<br /> $this->store = array();<br /> }<br />publicfunctionpush($o) {<br />array_push($this->store, $o);<br /> }<br />publicfunctionpop() {<br />returnarray_pop($this->store);<br /> }<br />publicfunctioncount() {<br />returncount($this->store);<br /> }<br />public function clean() {<br /> $this->store = array();<br /> }<br />}<br />
  18. 18. <?php<br />require_once'./Stack.php';<br />class StackTestextends PHPUnit_Framework_TestCase<br />{<br />public function testCanPushAndPop() {<br /> $stack = new Stack();<br /> $this->assertEquals(0, $stack->count());<br /> $stack->push('foo');<br /> $this->assertEquals(1, $stack->count());<br /> $this->assertEquals('foo', $stack->pop());<br /> $this->assertEquals(0, $stack->count());<br /> }<br /> public function testCanClean() {<br /> $stack = new Stack();<br /> $stack->push('foo');<br /> $this->assertEquals(1, $stack->count());<br /> $stack->clean();<br /> $this->assertEquals(0, $stack->count());<br /> }<br />}<br />也要增加新测试…<br />
  19. 19. - 互动演示 -<br />
  20. 20. xUnit方法的优势<br />减少验证 ‘代码正确性’ 的工作量<br />自动化回归测试<br />避免系统退步<br />写测试用例可以促使程序员发现边界条件<br />测试用例本身就是很好的示范代码和文档<br />写测试用例可以促使程序员真正了解需求<br />完备的测试可以给程序员以信心<br />More…<br />
  21. 21. 什么是测试?<br />测试是一组输入、执行条件以及预期结果的集合<br />一组断言<br />测试是一个产品的详细接口规格<br />如何调用,结果值会是如何,etc.<br />测试定义产品的每一个面<br />测试是…<br />这一页 PPT 本身就是个测试…<br />
  22. 22. 鸭子<br />“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.”<br />James Whitcomb Riley (1849 – 1916)<br />(Duck typing)<br />
  23. 23. 人<br />“人就是以为自己不是机器的机器”<br />Wang Wenlin (1981 – ∞)<br />以为自己不是机器的机器, 是人…<br />
  24. 24. 框架中的测试<br />Zend Framework & Symfony 1<br />
  25. 25. 良好的测试支持<br />Zend Framework 集成 PHPUnit支持<br />Symfony 1 使用自己的 Lime 测试框架<br />Symfony 2 已改用 PHPUnit …<br />它们都能自动生成 功能测试 骨架…<br />
  26. 26. Zend Framework 示例<br />$ zf create project demo<br />$ zf create controller foo<br />$ phpunit<br />
  27. 27. Zend Framework 示例<br /><?php<br />classIndexControllerTestextendsZend_Test_PHPUnit_ControllerTestCase<br />{<br /> …<br />publicfunctiontestIndexAction()<br /> {<br /> $params = array('action' => 'index', 'controller' => 'Index', 'module' => 'default');<br /> $urlParams = $this->urlizeOptions($params);<br /> $url = $this->url($urlParams);<br /> $this->dispatch($url);<br /> // assertions<br /> $this->assertModule($urlParams['module']);<br /> $this->assertController($urlParams['controller']);<br /> $this->assertAction($urlParams['action']);<br /> $this->assertQueryContentContains("div#welcome h3", "This is your project's main page");<br /> }<br />}<br />
  28. 28. - 互动演示 -<br />
  29. 29. Symfony示例<br />$ symfonygenerate:project demo<br />$ symfonygenerate:appfoo<br />$ symfonygenerate:modulefoo bar<br />$ symfonytest:all<br />$ symfonytest:functionalfoo<br />
  30. 30. Symfony示例<br /><?php<br />include(dirname(__FILE__).'/../../bootstrap/functional.php');<br />$browser = newsfTestFunctional(new sfBrowser());<br />$browser-><br />get('/content/index')-><br />with('request')->begin()-><br />isParameter('module', 'content')-><br />isParameter('action', 'index')-><br />end()-><br />with('response')->begin()-><br />isStatusCode(200)-><br />checkElement('body', '!/This is a temporary page/')-><br />end()<br />;<br />
  31. 31. - 互动演示 -<br />
  32. 32. 好消息…<br />功能测试脚本, 测试组会帮忙制作…<br />程序员只需做单元测试<br />
  33. 33. PHPUnit还能做什么…<br />
  34. 34. 代码覆盖报告<br />$ phpunit --coverage-html covStackTest<br />代码覆盖报告,一种调试工具。<br />
  35. 35.
  36. 36. - 互动演示 -<br />
  37. 37. 生成规格文档<br />$ phpunit --testdoxStackTest<br />测试 即是 定义。<br />
  38. 38. 生成规格文档<br />
  39. 39. - 互动演示 -<br />
  40. 40. 测试失败时…<br />Xdebug来帮忙<br />
  41. 41. Xdebug出场…<br />简便的 PHP 调试、跟踪 和 剖析 工具<br />我们主要用它的 远程调试功能<br />
  42. 42. 如何调试一个测试?<br />$ export XDEBUG_CONFIG="remote_host=192.168.8.91idekey=netbeans-xdebug"<br />## plain old php<br />$ phpunitStackTest<br />## zend framework<br />$ phpunit application/controllers/FooControllerTest<br />## symfony 1<br />$ symfonytest:functionalfoo<br />
  43. 43. 断点<br />单步<br />上下文<br />
  44. 44. - 互动演示 -<br />
  45. 45. Xdebug的其它能力…<br />跟踪 (Trace)<br />性能剖析 (Profile)<br />
  46. 46.
  47. 47. 一点疑惑<br />
  48. 48. 断言… 可以吗?<br />这种定义事物的方式可能并不充分<br />但至少是必要的<br />可是仍然是不够充分…<br />世界上从来没有 ‘完全充分’,就像合同不够充分,法律不会完美一样<br />我们的目标是测试案例能覆盖到所有的代码路径即可<br />
  49. 49. 测试不是测试组的事吗?<br />单元测试 习惯上、实践上 是 程序员写的<br />只有程序员自己知道怎么测…<br />而且,它也是一种调试工具<br />功能测试 习惯上 是 测试组 来做<br />但仍然需要程序员的紧密配合<br />
  50. 50. 最后…<br />
  51. 51. …谢谢!!<br />
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×