科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件利用单元测试在每个层上对PHP代码进行检查(2)

利用单元测试在每个层上对PHP代码进行检查(2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在本文中,您将学习到如何在模块、数据库和用户界面(UI)层对自己的PHP代码进行单元测试。现在是凌晨3点。我们怎样才能知道自己的代码依然在工作呢?

作者:Jack D. Herrington 来源:51CTO.com 2007年9月1日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
 

数据库测试

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

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

清单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


require_once 'dblib.php';

require_once 'PHPUnit2/Framework/TestCase.php';

class TestAuthors extends PHPUnit2_Framework_TestCase

{

function test_delete_all() {

$this->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


require_once('DB.php');

class Authors

{

public static function get_db()

{

$dsn = 'mysql://root:password@localhost/unitdb';

$db =& DB::Connect( $dsn, array() );

if (PEAR::isError($db)) { die($db->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.php

PHPUnit 2.2.1 by Sebastian Bergmann.

FFF

Time: 0.007500171661377

There 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


require_once('DB.php');

class Authors

{

public static function get_db()

{

$dsn = 'mysql://root:password@localhost/unitdb';

$db =& DB::Connect( $dsn, array() );

if (PEAR::isError($db)) { die($db->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;

}

}

?>

在对这段代码运行测试时,所有的测试都可以没有问题地运行,这样我们就可以知道自己的代码可以正确工作了。


    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章