Phpunit入门 r2

1,716 views

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,716
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
17
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Phpunit入门 r2

  1. 1. PHPUnit 入门 PHP User Group Shanghai 2008-04-26 Zhou Xianhua BaohuaCaiPHP User Group Shanghai 12008
  2. 2. 测试 ? • 测试方法 – 黑盒测试 – 白盒测试 • 测试过程 – 单元测试 – 集成测试 – 压力测试 – 并发测试 – 环境测试PHP User Group Shanghai 22008
  3. 3. 为 什么 要进 行单 元测试 ? • 保证代码按照特定的行为运行 • 减少 Bug • 提高整体项目开发效率 • 便于项目后续的维护PHP User Group Shanghai 32008
  4. 4. 常见 的测试 工具 • PHP – PHPUnit 、 SimpleTest • ActionScript – AsUnit • Javascript – JsUnit 、 scriptaculous(unittest) 、 crosscheck • Java – Junit 、 TestNG • Python – PyUnitPHP User Group Shanghai 42008
  5. 5. PHPUnit 的特性 • 安装、使用方便,是 xUnit 家族中的一员 • 完全支持 PHP5 • 开源、免费、有详细的文档供参考及官方支持 • 提供多种格式的测试输出 ( XML 、 JSON 、 TAP... ) • 可以自动生成测试类( --skeleton )及从测试类 生成应用类 • 提供 Selenium RC 接口,便于在真实的浏览器中 测试,实现基于 WEB 的功能测试。 • 参考: http://www.phpunit.de/wiki/FeaturesPHP User Group Shanghai 52008
  6. 6. 安装 PHPUnit • 使用 PEAR 安装 – pear channel-discover pear.phpunit.de – pear install phpunit/PHPUnit • 直接下载压缩包(或从 svn 库导出) – http://pear.phpunit.de/get/PHPUnit-3.2.18.tgz – 在 php.ini 中设置 include_path ,包含 PHPUnit 路 径 – 把 pear-phpunit 改名为 phpunit ,并加上可执行属 性,把文件中的 @php_bin@ 改成 php 可执行命 令所在的路径(注: Win 下是 pear-phpunit.bat ) – 修改 PHPUnit/Util/Fileloader.php ,把文件中的 @php_bin@ 改成 php 可执行命令所在的路径PHP User Group Shanghai 62008
  7. 7. 安装成功 运行 phpunit – PHPUnit 3.2.18 by Sebastian Bergmann. – Usage: phpunit [switches] UnitTest [UnitTest.php] – --log-json Log test execution in JSON format. – --log-tapLog test execution in TAP format to file. – --log-xml Logtest execution in XMLPHP User Group Shanghai 72008
  8. 8. 传统 的测试// 测试输入的用户名是否合法function checkName($name){ return (bool)preg_match(/^[w_d]{3,30}$/, $name);}// 传统的测试方法echo checkName(”testUserName”) ? ”Y” : ”N”;var_dump(checkName(” ”));if(checkName(”......”)) echo ”...”;
  9. 9. 第一个 PHPUnit 测试// CheckNameTest.phprequire_once PHPUnit/Framework.php;require_once checkName.php;class CheckNameTest extends PHPUnit_Framework_TestCase{ public function testValidateUser() { $this->assertTrue(checkName(”testUser001”)); $this->assertFalse(checkName(”User 001”)); }}
  10. 10. 运 行第一个 PHPUnit 测试$phpunit CheckNameTest.phpPHPUnit 3.2.18 by Sebastian Bergmann.Time: 0 secondsOK (1 test)
  11. 11. 测试步骤1. 将类 Class 的测试写入 ClassTest2. ClassTest 继承(通常)自 PHPUnit_Framework_TestCase3. 测试都是公用方法,命名为 test*4. 在测试方法中,类似 assertEquals() 的断 言方法用来断言一个实际值(应该)匹配 一个期望值
  12. 12. 数据提供者class DataTest extends PHPUnit_Framework_TestCase{     public static function provider()    {         return array( array(1, 0, 1), array(1, 1, 3) );     }      /* @dataProvider provider     */     public function testAdd($a, $b, $c)  {         $this->assertEquals($c, $a + $b);     }}
  13. 13. 含有通过 和失败 的测试require_once PHPUnit/Framework.php;class MyTest extends PHPUnit_Framework_TestCase { public function testSuccess() { $this->assertEquals(3, 1 + 2); } public function testFailure() { $this->assertTrue(2 > 3); }}
  14. 14. 含有通过 和失败 的测试结 果.FTime: 0 secondsThere was 1 failure:1) testFailure(MyTest)Failed asserting that <boolean:false> is true./home/zhouxh/php/phpunit/MyTest.php:11FAILURES!Tests: 2, Failures: 1
  15. 15. 不同的测试结 果. 测试成功输出F 测试当中断言失败时输出E 测试有错误发生时输出S 测试被跳过时输出I 测试未完成时输出
  16. 16. 有错误发 生的测试 ( E )public function testError() { $this->assertLessThan(3); $this->assertEquals(”E?”);}---------E1) testFailure(MyTest)Missing argument 2 for PHPUnit_Framework_Assert::assertLessThan(), called in ... ...
  17. 17. 被跳过 的测试 ( S )public function testSkip() { $this->markTestSkipped("Skipped test!"); // stop!!! $this->assertTrue(true);}---$phpunit –verbose MyTest.phpS...1) testSkip(MyTest)Skipped test!...
  18. 18. 未完成的测试 ( I )public function testIncomplete() { $this->markTestIncomplete("Incomplete test!"); // stop!!! $this->assertTrue(true);}---$phpunit –verbose MyTest.phpI...1) testIncomplete(MyTest)Incomplete test!...
  19. 19. 夹 具 (Fixtures)class MyTest extends PHPUnit_Framework_TestCase { public function setUp() { $this->mysqlConnection = mysql_connection(”localhost”, ”root”, ”password”); $this->data = array(1, 2, 3, 4); } public function testOne() {} public function testTwo() {} public function tearDown() { mysql_close($this->mysqlConnection); unset($this->data); }}
  20. 20. 夹 具 (Fixtures) setUp() testOne() tearDown() setUp() testTwo() tearDown()
  21. 21. 同时测试 多个文件// AllTests.phprequire_once PHPUnit/Framework.php;require_once PHPUnit/TextUI/TestRunner.php;$suite = new PHPUnit_Framework_TestSuite();$suite->addTestFile(tests/CheckNameTest.php);$suite->addTestFile(tests/CheckPasswordTest.php);PHPUnit_TextUI_TestRunner::run($suite);---$php AllTests.php...
  22. 22. 同时测试 多个文件// AllTests.phprequire_once PHPUnit/Framework.php;require_once PHPUnit/TextUI/TestRunner.php;require_once tests/CheckNameTest.php;require_once tests/CheckPasswordTest.php;$suite = new PHPUnit_Framework_TestSuite();$suite->addTestSuite(CheckNameTest);$suite->addTestSuite(CheckPasswordTest);PHPUnit_TextUI_TestRunner::run($suite);
  23. 23. 输 出测试require "PHPUnit/Extensions/OutputTestCase.php";class OutputTest extends PHPUnit_Extensions_OutputTestCase { public function testOne() { $this->expectOutputString("php"); echo "php"; } public function testTwo() { $this->expectOutputString("phd"); echo "php"; }}
  24. 24. 输 出测试 结 果.FTime: 0 secondsThere was 1 failure:1) testTwo(OutputTest)Failed asserting that two strings are equal.expected string <phd>difference < x>got string <php>Tests: 2, Failures: 1.
  25. 25. 性能测试require_once PHPUnit/Extensions/PerformanceTestCase.php;class PerformanceTestextends PHPUnit_Extensions_PerformanceTestCase{ public function testPerformance() { $this->setMaxRunningTime(2); sleep(1); }}
  26. 26. 其它扩 展测试• 数据库测试 – PHPUnit_Extensions_Database_TestCase• PHP 格式测试 – PHPUnit_Extensions_PhptTestCase – http://qa.php.net/write-test.php• Selenium Rc 测试 – PHPUnit_Extensions_SeleniumTestCase – http://selenium.openqa.org/
  27. 27. 测试驱动开发 (TDD)• 主要开发步骤 – 1. 编写测试用例 – 2. 运行测试用例(此时测试结果必然是失败的) – 3. 为测试用例编写代码 – 4. 再次运行测试用例(测试结果是成功或失败的) 若失败则返回第 3 步继续。 – 5. 根据需要清除 / 优化相关代码(重构),收工 ! Test Code Test Code
  28. 28. 测试驱动开发 (TDD) :例子require_once PHPUnit/Framework.php;require_once Cal.php;class MyTest extends PHPUnit_Framework_TestCase { protected $cal; protected function setUp() { $this->cal = new Cal(); } public function testAdd() { $this->assertEquals(3, $this->cal->add(1, 2)); } public function tearDown() { $this->cal = null; }}
  29. 29. 测试驱动开发 (TDD) :例子$phpunit MyTest.phpFatal error: require_once(): Failed opening required Cal.php (include_path=.:... ...
  30. 30. 测试驱动开发 (TDD) :例子class Cal { public function add() { }}
  31. 31. 测试驱动开发 (TDD) :例子phpunit MyTest.phpFTime: 0 secondsThere was 1 failure:1) testAdd(MyTest)Failed asserting that <null> matches expected value <integer:3>.
  32. 32. 测试驱动开发 (TDD) :例子class Cal { public function add($a, $b) { return $a + $b; }}
  33. 33. 测试驱动开发 (TDD) :例子$phpunit MyTest.phpPHPUnit 3.2.18 by Sebastian Bergmann..Time: 0 secondsOK (1 test)
  34. 34. 测试 范围 分析• 查看代码有哪些被测试了,有哪些没有被测试, 用不同的颜色区分开• 需要 xdebug 扩展支持• 输出结果: html 、 xml – phpunit --coverage-html ./reports MyTest.php – phpunit --coverage-xml report.xml MyTest.php• 覆盖级别:类、方法、行• 支持元标签: @covers 、 @codeCoverageIgnoreStart 和 @codeCoverageIgnoreEnd
  35. 35. 测试 范围 分析$phpunit –coverage-html ./reports MyTest.php
  36. 36. 更多 ... ...• 官方网站:• http://www.phpunit.de/• http://planet.phpunit.de/• 例子(谁在使用 PHPUnit ):• http://www.phpunit.de/wiki/WhoUsesPHPUnit• (ZendFramework 、 PHP-Gtk2 、 Phing... ... )• 相关工具:• http://www.phpundercontrol.org• http://cruisecontrol.sourceforge.net/• http://www.xdebug.org

×