首页 php教程 php手册 利用单元测试对PHP代码进行检查

利用单元测试对PHP代码进行检查

Jun 13, 2016 am 10:35 AM
php 代码 修改 使用 单元 开发 测试 确保 调整 驱动

  测试驱动的开发和单元测试是确保代码在经过修改和重大调整之后依然能如我们期望的一样工作的最新方法。在本文中,您将学习到如何在模块、数据库和用户界面(UI)层对自己的 PHP 代码进行单元测试。

  现在是凌晨 3 点。我们怎样才能知道自己的代码依然在工作呢?

  Web 应用程序是 24x7 不间断运行的,因此我的程序是否还在运行这个问题会在晚上一直困扰我。单元测试已经帮我对自己的代码建立了足够的信心 —— 这样我就可以安稳地睡个好觉了。

  单元测试 是一个为代码编写测试用例并自动运行这些测试的框架。测试驱动的开发是一种单元测试方法,其思想是应该首先编写测试程序,并验证这些测试可以发现错误,然后才开始编写需要通过这些测试的代码。当所有测试都通过时,我们开发的特性也就完成了。这些单元测试的价值是我们可以随时运行它们 —— 在签入代码之前,重大修改之后,或者部署到正在运行的系统之后都可以。

  PHP 单元测试

  对于 PHP 来说,单元测试框架是 PHPUnit2。可以使用 PEAR 命令行作为一个 PEAR 模块来安装这个系统:% pear install PHPUnit2。

  在安装这个框架之后,可以通过创建派生于 PHPUnit2_Framework_TestCase 的测试类来编写单元测试。

  模块单元测试

  我发现开始单元测试最好的地方是在应用程序的业务逻辑模块中。我使用了一个简单的例子:这是一个对两个数字进行求和的函数。为了开始测试,我们首先编写测试用例,如下所示。

  清单 1. TestAdd.php

  assertTrue( add( 1, 2 ) == 3 ); }  function test2() { $this->assertTrue( add( 1, 1 ) == 2 ); }}?>

  这个 TestAdd 类有两个方法,都使用了 test 前缀。每个方法都定义了一个测试,这个测试可以与清单 1 一样简单,也可以十分复杂。在本例中,我们在第一个测试中只是简单地断定 1 加 2 等于 3,在第二个测试中是 1 加 1 等于 2。

  PHPUnit2 系统定义了 assertTrue() 方法,它用来测试参数中包含的条件值是否为真。然后,我们又编写了 Add.php 模块,最初让它产生错误的结果。

  清单 2. Add.php

  

  现在运行单元测试时,这两个测试都会失败。

  清单 3. 测试失败

  % phpunit TestAdd.phpPHPUnit 2.2.1 by Sebastian Bergmann.FFTime: 0.0031270980834961There were 2 failures:1) test1(TestAdd)2) test2(TestAdd)FAILURES!!!Tests run: 2, Failures: 2, Errors: 0, Incomplete Tests: 0.

  现在我知道这两个测试都可以正常工作了。因此,可以修改 add() 函数来真正地做实际的事情了。

  现在这两个测试都可以通过了。

  

  清单 4. 测试通过

  % phpunit TestAdd.phpPHPUnit 2.2.1 by Sebastian Bergmann...Time: 0.0023679733276367OK (2 tests)%

  尽管这个测试驱动开发的例子非常简单,但是我们可以从中体会到它的思想。我们首先创建了测试用例,并且有足够多的代码让这个测试运行起来,不过结果是错误的。然后我们验证测试的确是失败的,接着实现了实际的代码使这个测试能够通过。

  我发现在实现代码时我会一直不断地添加代码,直到拥有一个覆盖所有代码路径的完整测试为止。在本文的最后,您会看到有关编写什么测试和如何编写这些测试的一些建议。

  数据库测试

  在进行模块测试之后,就可以进行数据库访问测试了。数据库访问测试带来了两个有趣的问题。首先,我们必须在每次测试之前将数据库恢复到某个已知点。其次,要注意这种恢复可能会对现有数据库造成破坏,因此我们必须对非生产数据库进行测试,或者在编写测试用例时注意不能影响现有数据库的内容。

  数据库的单元测试是从数据库开始的。为了阐述这个问题,我们需要使用下面的简单模式。

  清单 5. Schema.sql

  DROP TABLE IF EXISTS authors;CREATE TABLE authors (  id MEDIUMINT NOT NULL AUTO_INCREMENT,  name TEXT NOT NULL,  PRIMARY KEY ( id ));

  清单 5 是一个 authors 表,每条记录都有一个相关的 ID。

  接下来,就可以编写测试用例了。

  清单 6. TestAuthors.php

  assertTrue( Authors::delete_all() );  }  function test_insert() {     $this->assertTrue( Authors::delete_all() );     $this->assertTrue( Authors::insert( Jack ) );  }  function test_insert_and_get() {     $this->assertTrue( Authors::delete_all() );     $this->assertTrue( Authors::insert( Jack ) );     $this->assertTrue( Authors::insert( Joe ) );     $found = Authors::get_all();     $this->assertTrue( $found != null );     $this->assertTrue( count( $found ) == 2 );  }}?>

  这组测试覆盖了从表中删除作者、向表中插入作者以及在验证作者是否存在的同时插入作者等功能。这是一个累加的测试,我发现对于寻找错误来说这非常有用。观察一下哪些测试可以正常工作,而哪些测试不能正常工作,就可以快速地找出哪些地方出错了,然后就可以进一步理解它们之间的区别。

  最初产生失败的 dblib.php PHP 数据库访问代码版本如下所示。

  清单 7. dblib.php

  getMessage()); }    return $db;  }  public static function delete_all()  {    return false;  }  public static function insert( $name )  {    return false;  }  public static function get_all()  {    return null;  }}?>

  对清单 8 中的代码执行单元测试会显示这 3 个测试全部失败了:

  清单 8. dblib.php

  % phpunit TestAuthors.phpPHPUnit 2.2.1 by Sebastian Bergmann.FFFTime: 0.007500171661377There were 3 failures:1) test_delete_all(TestAuthors)2) test_insert(TestAuthors)3) test_insert_and_get(TestAuthors)FAILURES!!!Tests run: 3, Failures: 3, Errors: 0, Incomplete Tests: 0.%

  现在我们可以开始添加正确访问数据库的代码 —— 一个方法一个方法地添加 —— 直到所有这 3 个测试都可以通过。最终版本的 dblib.php 代码如下所示。

  清单 9. 完整的 dblib.php

  getMessage()); }    return $db;  }  public static function delete_all()  {    $db = Authors::get_db();    $sth = $db->prepare( DELETE FROM authors );    $db->execute( $sth );    return true;  }  public static function insert( $name )  {    $db = Authors::get_db();    $sth = $db->prepare( INSERT INTO authors VALUES (null,?) );    $db->execute( $sth, array( $name ) );    return true;  }  public static function get_all()  {    $db = Authors::get_db();    $res = $db->query( "SELECT * FROM authors" );    $rows = array();    while( $res->fetchInto( $row ) ) { $rows []= $row; }    return $rows;  }}?>

  HTML 测试

  对整个 PHP 应用程序进行测试的下一个步骤是对前端的超文本标记语言(HTML)界面进行测试。要进行这种测试,我们需要一个如下所示的 Web 页面。


  清单 10. TestPage.php

  get( $url );    $resp = $clie

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1664
14
CakePHP 教程
1422
52
Laravel 教程
1316
25
PHP教程
1267
29
C# 教程
1239
24
在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

解释PHP中的晚期静态绑定(静态::)。 解释PHP中的晚期静态绑定(静态::)。 Apr 03, 2025 am 12:04 AM

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? 什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些?PHP的魔法方法包括:1.\_\_construct,用于初始化对象;2.\_\_destruct,用于清理资源;3.\_\_call,处理不存在的方法调用;4.\_\_get,实现动态属性访问;5.\_\_set,实现动态属性设置。这些方法在特定情况下自动调用,提升代码的灵活性和效率。

PHP和Python:比较两种流行的编程语言 PHP和Python:比较两种流行的编程语言 Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

PHP行动:现实世界中的示例和应用程序 PHP行动:现实世界中的示例和应用程序 Apr 14, 2025 am 12:19 AM

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

PHP:网络开发的关键语言 PHP:网络开发的关键语言 Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP的持久相关性:它还活着吗? PHP的持久相关性:它还活着吗? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在现代编程领域中依然占据重要地位。1)PHP的简单易学和强大社区支持使其在Web开发中广泛应用;2)其灵活性和稳定性使其在处理Web表单、数据库操作和文件处理等方面表现出色;3)PHP不断进化和优化,适用于初学者和经验丰富的开发者。

说明匹配表达式(PHP 8)及其与开关的不同。 说明匹配表达式(PHP 8)及其与开关的不同。 Apr 06, 2025 am 12:03 AM

在PHP8 中,match表达式是一种新的控制结构,用于根据表达式的值返回不同的结果。1)它类似于switch语句,但返回值而非执行语句块。2)match表达式使用严格比较(===),提升了安全性。3)它避免了switch语句中可能的break遗漏问题,增强了代码的简洁性和可读性。

See all articles