开放的编程资料库

当前位置:我爱分享网 > PHP教程 > 正文

phpt教程

正如我在今天早些时候的文章中所承诺的,这是我使用phpt在PHP中进行单元测试的速成教程。

首先,据我所知,phpt测试文件是作为PHP-QA工作的一部分创建的。虽然我在PHP-QA站点中找不到链接,但他们有一个详细介绍phpt测试文件的页面,并且该页面显示了phpt测试文件的所有部分,尽管它们不一定显示每个部分的示例。

此外,您可能会发现这篇InternationalPHPMagazine文章内容丰富;在其中,AaronWormus给出了关于它们的简短教程,以及一些使用PHPUnit进行phpt测试的方法。

最后,在开始之前,我想说明:我不是单元测试方面的专家。但是,单元测试背后的想法很简单:保持代码简单和模块化,并测试每个小部分(或模块)所有类型的输入和输出。如果您正在测试的代码是函数或类方法,请测试可以传递给它的参数的所有排列,以及所有可能的返回值。

好的,让我们开始吧!

概览

phpt测试文件的基本格式如下所示:

--TEST--
test name
--FILE--
<?php
// your PHP code goes here
?>
--EXPECT--
Expected output from the PHP code

如您所见,该文件分为几个部分,每个部分都以--TITLE--开头。--TEST--为测试名称;这可以是函数名、类名、类方法名或一些自由文本。尝试让它变得有意义。--FILE--是将要执行的PHP代码,--EXPECT--是此PHP代码的预期输出。如果PHP代码的输出符合预期,则测试通过。

您还可以使用其他一些部分;我使用--SKIPIF--部分类型来测试存在哪个版本的PHP(例如,Cgiapp2仅支持PHP5);如果满足条件,则跳过测试。您还可以指定--EXPECTF----EXPECTREGEX--而不是--EXPECT--,但我发现在大多数情况下,我可以控制我的代码的输出,这样就不需要这些了。

编写测试的技巧

首先,我对phpt测试的唯一经验是测试Cgiapp和Cgiapp2,它们是类;这些提示在其他情况下可能没有意义。

其次,提示以粗体突出显示

我发现您应该为每种方法创建一个测试文件。(一般来说,我遇到过一些需要多个文件的情况,主要是在测试使用header()的代码时。)在那个测试文件中,你想测试:

  • 方法参数
  • 方法返回值

这意味着您需要为多种情况编写代码。在编写了一些测试之后,我发现如果不在测试代码中包含信息输出,调试就会变得很困难。创建有关正在测试的内容的信息输出:

<?php
echo "Test 1: single string argument\n";
?>

当测试失败时,这些陈述是无价的;然后,您可以一目了然地看到您正在测试的内容。

如果您在代码中使用trigger_error()PEAR_Error(您是,不是吗?),在您的测试中包含一个错误处理程序代码,以便您可以捕获这些并将它们转换为您可以格式化和控制的消息。

据推测,--GET----POST--部分允许您指定这些数组中存在的变量以用于测试目的。然而,这只适用于CGI版本的PHP……而且,如果您像我一样,那么您正在使用CLISAPI。简单的解决方法是简单地--FILE--部分中构建$_GET$_POST数组。

$_SESSION也是如此。但是,如果您指定session_start()$_SESSION数组出现;它只是空的。

如果需要包含文件,请将其包含在相对于测试目录的目录中。要确定该目录是什么(不要假设它是.),使用构造dirname(__FILE__)

require_once dirname(__FILE__) . '/setup.php.inc';

运行测试

一旦您有了测试文件,只需执行pearrun-teststestFile.phpt(当然,替换为您的测试文件的名称)。如果您希望一次从多个文件运行多个测试,您可以将每个文件的名称作为参数包含在内。如果您想在目录中运行所有测试,只需执行不带任何参数的pearrun-tests

运行测试时,您将在屏幕上看到信息。如果测试失败,则给出测试文件的名称和测试名称。

调试失败的测试

最终,测试会失败。可能是你写错了,或者你的代码中确实有错误。问题是,phpt测试如何帮助您确定是哪一个?

当对一个文件运行测试时,该文件被拆分成多个部分。--FILE--部分实际上写入了一个以测试文件命名的文件,但扩展名为.php--EXPECT--部分被写入一个包含.exp部分的文件;输出通过管道传输到具有.out部分的文件;并将发生的事件的日志写入扩展名为.log的文件中。最后,如果测试失败,将创建一个.diff文件,其中包含.exp.out文件之间的差异。例如,如果我们有一个名为testFile.phpt的测试文件,但它未通过测试,我们现在将拥有以下文件:

run-tests.log
testFile.diff
testFile.exp
testFile.log
testFile.out
testFile.php
testFile.phpt

您的第一站应该是.diff文件。您一眼就能看出,例如,是否发生了PHP错误。我在我的几个测试中发现,当我看到这些差异中弹出语法错误警告时,我在测试代码中漏掉了分号或大括号。

如果.diff没有为您充分解释差异,请打开您的.exp.out文件。我使用VIM,我通常会执行:vsplit这样我就可以并排加载这些文件并进行比较。这样做时,我可以直观地看到输出开始与预期不同的地方。(有好几次我在预期中发现了错别字,这意味着我改正错字后测试运行正常。)

还记得我之前说过创建关于正在测试的内容的信息输出吗?这就是它发挥作用的地方。我发现输出内容如下:

.
.
Bad argument passed
something

比以下更难理解:

Test 1: current directory as argument
.
Test 2: no argument passed
.
Test 3: object as argument
Bad argument passed
Test 4: 'something' as argument
something

在上面的示例中,如果测试2的预期是其他内容,我现在确切地知道我的测试文件中的哪个测试失败了——这有助于我确定我可能需要在我的代码中修复它的位置。

总结

编写测试的技巧

  • 为每个方法创建一个测试文件
  • 创建有关正在测试的内容的信息输出
  • 如果触发错误,则在测试代码中包含一个错误处理程序
  • --FILE--部分构建你的$_GET$_POST数组;它比--GET----POST--
  • 使用构造dirname(__FILE__)更便携

运行测试

  • pear运行测试testFile.phpt
  • pear运行测试testFile1.phpttestFile2.phpt
  • pear运行测试

调试失败的测试

  • 检查.diff文件;在测试代​​码中查找PHP错误
  • 并排比较.exp.out文件:
    • 检查预期输出中的拼写错误
    • 检查信息输出以确定测试的哪一部分失败

从这里去哪里

显然,要完全理解测试,唯一的方法就是亲自动手。有大量可用的单元测试资源;c2wiki有一些很好的资源,许多书籍都涵盖了这个主题(ThePragmaticProgrammer浮现在脑海中)。

我读过一些论据,认为您应该首先测试界面。这意味着您不会在函数/方法中抛出意外参数。稍后,在代码成熟之后,您可以为意外参数添加测试,或者为已报告的错误添加测试。PHP-QA站点建议为该方法提供一个测试文件,但也有解决特定错误的测试文件;我还没有进行测试。

最后,我在许多资源中读到真正的单元测试应该在您开始编程之前开始。虽然我在一定程度上理解了这个原则,但我也发现,在我编写代码时,我发现了我之前无法预料到的问题中的复杂性……而这些复杂性的解决方案通常是新方法。为此,我觉得编写测试应该在代码初稿之后进行。这样做提供了代码的第一个接口,也有助于在应用程序测试开始之前清理代码和查找错误。但是,这只是我的拙见。

测试愉快!

未经允许不得转载:我爱分享网 » phpt教程

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏