探索 PHP project 或 package 的合理开发姿势
合适的开发姿势对于开发优秀的项目或产品是很重要的,无奈本人经验有限,若有不同看法或者错误的表述,欢迎交流指正,以免无人子弟 ^ ^
基于 PDS-Skeleton 创建一个新项目,并且安装 phpunit。
git clone https://github.com/php-pds/skeleton blog
cd blog
composer require phpunit/phpunit --dev
进入项目目录后,可以看到当前的结构为
ryandeMacBook-Pro:blog ryan$ pwd
/Users/ryan/dev/product/blog
ryandeMacBook-Pro:blog ryan$ ll
total 176
-rw-r--r-- 1 ryan staff 211 12 4 16:56 CHANGELOG.md
-rw-r--r-- 1 ryan staff 20137 12 4 16:56 LICENSE
-rw-r--r-- 1 ryan staff 5636 12 4 16:56 README.md
drwxr-xr-x 3 ryan staff 102 12 4 16:56 bin
-rw-r--r-- 1 ryan staff 484 12 4 16:57 composer.json
-rw-r--r-- 1 ryan staff 52116 12 4 16:57 composer.lock
drwxr-xr-x 3 ryan staff 102 12 4 16:56 docs
drwxr-xr-x 6 ryan staff 204 12 4 16:56 src
drwxr-xr-x 4 ryan staff 136 12 4 16:56 tests
drwxr-xr-x 14 ryan staff 476 12 4 16:57 vendor
检验当前目录是否符合 PDS 标准
创建web 项目缺失的几个标准目录(如果是开发第三方包,不需要这些目录),注意generate 后面一定要指定项目目录,否则文件将会被创建到家目录中 - -
ryandeMacBook-Pro:blog ryan$ bin/pds-skeleton generate ./
Created /Users/ryan/dev/product/blog/config
Created /Users/ryan/dev/product/blog/public
Created /Users/ryan/dev/product/blog/resources
Created CONTRIBUTING.md
再看一下现在的目录结构,可以看到的确多了上面输出结果提示的 4个文件夹和文件
可以看到这样的目录结构就我们要的完整结构,下面让我们删掉额外的文件
rm bin/* src/* docs/* tests/*
我们决定以 TDD 的方式开发项目,在项目根目录下创建 phpunit.xml,写入以下内容
<phpunit colors="true" bootstrap="tests/autoload.php">
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
<log type="tap" target="tests/build/report.tap"/>
<log type="junit" target="tests/build/report.junit.xml"/>
<log type="coverage-html" target="tests/build/coverage" charset="UTF-8" yui="true" highlight="true"/>
<log type="coverage-text" target="tests/build/coverage.txt"/>
<log type="coverage-clover" target="tests/build/logs/clover.xml"/>
</logging>
<testsuites>
<testsuite name="converter">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
</phpunit>
bootstrap 节点会告诉phpunit 在测试开始前需要加载哪些PHP 文件;创建 tests/autoload.php 并写入一下内容
<?php
require_once __DIR__.'/../vendor/autoload.php';
现在假设我们要测试 BlogEngineDomainPost 类。让我们先写测试,创建 tests/Blog/Engine/Domain/PostTest.php
mkdir -p ./tests/Blog/Engine/Domain/ && touch ./tests/Blog/Engine/Domain/PostTest.php
PostTest.php 代码如下
<?php
namespace Blog\Engine\Domain;
use PHPUnit\Framework\TestCase;
class PostTest extends TestCase
{
public function testPost()
{
$post = new Post();
$this->assertInstanceOf('\Blog\Engine\Domain\Post', $post);
}
}
如果我们现在执行 php vendor/bin/phpunit,会得到以下错误
ryandeMacBook-Pro:blog ryan$ php vendor/bin/phpunit
PHPUnit 6.5.2 by Sebastian Bergmann and contributors.
E 1 / 1 (100%)
Time: 107 ms, Memory: 4.00MB
There was 1 error:
1) Blog\Engine\Domain\PostTest::testPost
Error: Class 'Blog\Engine\Domain\Post' not found
/Users/ryan/dev/product/blog/tests/Blog/Engine/Domain/PostTest.php:10
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
错误很明显,BlogEngineDomainPost 找不到,我们马上来写一个
mkdir -p ./src/Blog/Engine/Domain/ && touch ./src/Blog/Engine/Domain/Post.php
Post.php 文件包含如下代码,TDD 方式开发时,业务代码只需刚好满足测试通过即可
<?php
namespace Blog\Engine\Domain;
class Post
{
}
我们再执行 php vendor/bin/phpunit,仍然会得到以下错误
ryandeMacBook-Pro:blog ryan$ php vendor/bin/phpunit
PHPUnit 6.5.2 by Sebastian Bergmann and contributors.
E 1 / 1 (100%)
Time: 107 ms, Memory: 4.00MB
There was 1 error:
1) Blog\Engine\Domain\PostTest::testPost
Error: Class 'Blog\Engine\Domain\Post' not found
/Users/ryan/dev/product/blog/tests/Blog/Engine/Domain/PostTest.php:10
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
oops~,什么情况,还是找不到类的定义,看一下当前的 composer.json 文件内容
{
"name": "pds/skeleton",
"type": "standard",
"description": "Standard for PHP package skeletons.",
"homepage": "https://github.com/php-pds/skeleton",
"license": "CC-BY-SA-4.0",
"autoload": {
"psr-4": {
"Pds\\Skeleton\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Pds\\Skeleton\\": "tests/"
}
},
"bin": ["bin/pds-skeleton"],
"require-dev": {
"phpunit/phpunit": "^6.5"
}
}
你一定注意到了 autoload 和 autoload-dev,这个选项可以指定psr-4 的命名空间和其对应的文件路径,下面我们来指定一下 Blog 命名空间指向的路径
{
"name": "pds/skeleton",
"type": "standard",
"description": "Standard for PHP package skeletons.",
"homepage": "https://github.com/php-pds/skeleton",
"license": "CC-BY-SA-4.0",
"autoload": {
"psr-4": {
"Blog\\": "src/Blog"
}
},
"autoload-dev": {
"psr-4": {
"Blog\\": "tests/Blog"
}
},
"bin": ["bin/pds-skeleton"],
"require-dev": {
"phpunit/phpunit": "^6.5"
}
}
重新执行 php vendor/bin/phpunit,bravo~
ryandeMacBook-Pro:blog ryan$ php vendor/bin/phpunit
PHPUnit 6.5.2 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 91 ms, Memory: 4.00MB
OK (1 test, 1 assertion)