我正在编写一组简单的 PHP 函数,我只使用纯 PHP7,没有框架,什么都没有。这些函数稍后将在 CMS 的插件中使用,但这不是重点。我想使用 Codeception 为我的函数编写单元测试(为了熟悉它,我知道 Codeception 在这里基本上只运行 PHPUnit),但我真的不知道如何以合理的方式将 Codeception 指向我的代码。
我的结构如下:我有path/to/functions.php
它包含我想测试的功能,大致如下:
<?php
namespace App;
if (!defined('CONST')) {
die('What are you doing? Get out of here!');
}
function change_string($string){
return $string . '123';
}
我使用 Composer 将 Codeception 安装到我项目的根目录,并使用 Codeception bootstrap 开始,然后我还使用 Codeception 生成单元测试文件,并在其中添加了单元测试。现在大多数关于该主题的教程/解释/文章只是编写测试,而 Codeception 神奇地知道在哪里可以找到要测试的代码。这对我来说是零意义的,并且在我的情况下不起作用。所以我所做的是以下内容:
<?php
class NamesPathsTest extends \Codeception\Test\Unit
{
/**
* @var \UnitTester
*/
protected $tester;
protected function _before()
{
defined('CONST') or define('CONST', 'XXX');
require_once('path/to/functions.php');
}
protected function _after()
{
}
// tests
public function testChangeString() {
$this->assertEquals('a123',App\change_string('a'));
}
}
这是有效的,但我认为必须有更好的方法来向 Codeception 解释代码在哪里运行,而不是使用require_once('path/to/functions.php')
. 这该怎么做?将 Codeception 指向我的代码的智能方法是什么?它还可以处理定义常量,以便我可以实际测试函数吗?
你的应用程序代码如何知道函数和类在哪里?
神奇的成分称为自动加载。
由于你已经在使用 Composer,因此最简单的方法是配置 Composer 以加载你的类和函数。
自动加载仅适用于类,对于它们,你可以将命名空间前缀映射到目录,
{
"autoload": {
"psr-4": {
"Monolog\\": "src/",
"Vendor\\Namespace\\": ""
}
}
}
包含功能的文件必须被包括在内,但作曲家帮助与太:
{
"autoload": {
"files": ["path/to/functions.php"]
}
}
综合结果:
{
"autoload": {
"files": ["path/to/functions.php"]
"psr-4": {
"Monolog\\": "src/",
"Vendor\\Namespace\\": ""
}
}
}
由于 Codeception 是使用 Composer 安装的,因此无需额外工作即可在测试中获得自动加载工作。要从应用程序代码中的自动加载中受益,你必须require 'vendor/autoload.php';
靠近入口点。
关于你的不变问题,没有人使用这种方式来阻止直接执行文件,将代码从公共目录中移开并只留下可以直接在公共目录中访问的小 index.php 文件要简单得多,也更安全。
谢谢,这有点帮助。自动加载是正确的方法,除了 PHP 不支持自动加载常量(人们可以解决这个问题,创建一些 const.php 来定义可以在我的带有函数的文件之前自动加载的常量)。不幸的是,这段代码是 CMS 插件的一部分,所以我不能把文件放到服务器不可访问的部分,我能做的就是用 .htaccess 保护它。