How do I write unit tests in PHP with a procedural codebase?(如何使用程序代码库在 PHP 中编写单元测试?)
问题描述
I'm mostly convinced of the benefits of unit testing, and I would like to start applying the concept to a large existing codebase written in PHP. Less than 10% of this code is object-oriented.
I've looked at several unit testing frameworks (PHPUnit, SimpleTest, and phpt). However, I haven't found examples for any of these that test procedural code. What's the best framework for my situation and are there any examples of unit testing PHP using non-OOP code?
You can unit-test procedural PHP, no problem. And you're definitely not out of luck if your code is mixed in with HTML.
At the application or acceptance test level, your procedural PHP probably depends on the value of the superglobals ($_POST, $_GET, $_COOKIE
, etc.) to determine behavior, and ends by including a template file and spitting out the output.
To do application-level testing, you can just set the superglobal values; start an output buffer (to keep a bunch of html from flooding your screen); call the page; assert against stuff inside the buffer; and trash the buffer at the end. So, you could do something like this:
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);
}
Even for enormous "frameworks" with lots of includes, this kind of testing will tell you if you have application-level features working or not. This is going to be really important as you start improving your code, because even if you're convinced that the database connector still works and looks better than before, you'll want to click a button and see that, yes, you can still login and logout through the database.
At lower levels, there are minor variations depending on variable scope and whether functions work by side-effects (returning true or false), or return the result directly.
Are variables passed around explicitly, as parameters or arrays of parameters between functions? Or are variables set in many different places, and passed implicitly as globals? If it's the (good) explicit case, you can unit test a function by (1) including the file holding the function, then (2) feeding the function test values directly, and (3) capturing the output and asserting against it. If you're using globals, you just have to be extra careful (as above, in the $_POST example) to carefully null out all the globals between tests. It's also especially helpful to keep tests very small (5-10 lines, 1-2 asserts) when dealing with a function that pushes and pulls lots of globals.
Another basic issue is whether the functions work by returning the output, or by altering the params passed in, returning true/false instead. In the first case, testing is easier, but again, it's possible in both cases:
// 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);
}
In the bad case, where your code works by side-effects and returns true or false, you still can test pretty easily:
/* 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);
}
Hope this helps.
这篇关于如何使用程序代码库在 PHP 中编写单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何使用程序代码库在 PHP 中编写单元测试?


- 带有通配符的 Laravel 验证器 2021-01-01
- 如何定位 php.ini 文件 (xampp) 2022-01-01
- 正确分离 PHP 中的逻辑/样式 2021-01-01
- 从 PHP 中的输入表单获取日期 2022-01-01
- PHP Count 布尔数组中真值的数量 2021-01-01
- SoapClient 设置自定义 HTTP Header 2021-01-01
- Laravel 仓库 2022-01-01
- Mod使用GET变量将子域重写为PHP 2021-01-01
- 没有作曲家的 PSR4 自动加载 2022-01-01
- Oracle 即时客户端 DYLD_LIBRARY_PATH 错误 2022-01-01