如何用PHP编写单元测试与程序代码库?
-
23-08-2019 - |
题
我相信大部分的单元测试的好处,我想开始应用的概念,用PHP写的一个大现有的代码库。此代码的小于10%是面向对象的。
我看几个单元测试框架(PHPUnit的,SimpleTest的,和PHPT)。但是,我还没有发现例子任何这些用于测试的程序代码。什么是我的情况的最佳框架以及是否有使用非面向对象的代码进行单元测试的PHP的例子?
解决方案
可以单元测试程序PHP,没有问题。而你绝对不是运气,如果你的代码与HTML混合。
目前应用或验收测试水平,你的程序PHP可能依赖于超全局的值($_POST, $_GET, $_COOKIE
等)来确定的行为,和通过包括一个模板文件和吐出的输出结束。
要执行的应用程序级的测试,可以只设置超全局值;启动输出缓冲器(保持一串HTML从充斥屏幕);调用页面;断言针对缓冲器内的东西;和垃圾末尾的缓冲区。 所以,你可以做这样的事情:
public function setUp()
{
if (isset($_POST['foo'])) {
unset($_POST['foo']);
}
}
public function testSomeKindOfAcceptanceTest()
{
$_POST['foo'] = 'bar';
ob_start();
include('fileToTest.php');
$output = ob_get_flush();
$this->assertContains($someExpectedString, $output);
}
即使是巨大的,有很多的包括,这种测试会告诉你,如果你有工作或没有应用级功能“框架”。这是怎么回事,你开始改善你的代码是非常重要的,因为即使你相信数据库连接器仍然工作,看起来比以前好了,你要点击一个按钮,看看,是的,你仍然可以登录并通过数据库注销。
目前较低水平,有依赖于可变范围小的变化和功能是否由副作用工作(返回真或假),或者直接返回结果。
是变量绕过明确地,作为功能之间的参数的参数或数组?或者,变量很多不同的地方设置,并含蓄地传递作为全局?如果它是(好)明确的情况下,可以进行单元测试(1)包括保持功能的文件,然后(2)直接供给功能测试值,以及(3)捕获输出和断言针对它的功能。如果你使用全局变量,你就必须要格外小心(如上,在$ _POST示例)认真空了所有的测试之间的全局。这也是特别是有助于保持测试很小(5-10行,1-2断言)与推拉大量全局的功能的时候。
另一个基本问题是功能是否通过返回的输出工作,或者通过改变PARAMS传入,返回真/假代替。在第一种情况下,测试比较容易,但再次,它可能在这两种情况下:
// assuming you required the file of interest at the top of the test file
public function testShouldConcatenateTwoStringsAndReturnResult()
{
$stringOne = 'foo';
$stringTwo = 'bar';
$expectedOutput = 'foobar';
$output = myCustomCatFunction($stringOne, $stringTwo);
$this->assertEquals($expectedOutput, $output);
}
在不好的情况下,你的代码工作的副作用并返回true或false,你仍然可以测试很容易地:
/* suppose your cat function stupidly
* overwrites the first parameter
* with the result of concatenation,
* as an admittedly contrived example
*/
public function testShouldConcatenateTwoStringsAndReturnTrue()
{
$stringOne = 'foo';
$stringTwo = 'bar';
$expectedOutput = 'foobar';
$output = myCustomCatFunction($stringOne, $stringTwo);
$this->assertTrue($output);
$this->Equals($expectedOutput, $stringOne);
}
希望这有助于。
其他提示
什么单元测试做的很好,并且你应该使用它们,就是当你有一段代码,你给输入一些号码,你希望得到的输出一定数量的退了出去。这个想法是,当你在以后添加的功能,您可以运行测试,并确保它仍然执行旧功能相同的方式。
所以,如果你有一个程序代码库,你可以做到这一点您的通话功能,在测试方法
require 'my-libraries.php';
class SomeTest extends SomeBaseTestFromSomeFramework {
public function testSetup() {
$this->assertTrue(true);
}
public function testMyFunction() {
$output = my_function('foo',3);
$this->assertEquals('expected output',$output);
}
}
这招用PHP代码库中,往往你的库代码将与您的测试框架的运行干扰,因为你的代码和测试框架将有大量的代码与在Web浏览器设置应用程序环境(会话,共享的全局变量等)。预计花一段时间获得到一个地步,你可以包括你的库代码和运行污垢简单的测试(上述testSetup功能)。
如果您的代码不具备的功能,并且仅仅是一系列的PHP文件输出HTML页面,你是那种运气不好。你的代码不能被分成不同的单元,这意味着单元测试是不会有太大的利用你的。你会断在“验收测试”水平的产品,如花费时间更好硒和的的Watir 。这些会让你自动浏览器,然后检查内容具体地点/表单的页面。
您可以尝试使用,包括您的非OOP代码到测试类
require_once 'your_non_oop_file.php' # Contains fct_to_test()
和PHPUnit的定义你的测试功能:
testfct_to_test() {
assertEquals( result_expected, fct_to_test(), 'Fail with fct_to_test' );
}