一步一步用laravel开发回风博客系统-04-Markdown和测试

原作者网站:http://laravelcoding.com/blog?tag=L5+Beauty
可以参考中文站点:http://laravelacademy.org/resources/blog

我是基于5.2的,而且有些东西我觉得有必要有的没必要,所以思路是跟着以上两个参考着搞,具体还是有区别的,我最终代码放在了Github:https://github.com/wedojava/hfblog.dev

由于正在补英语,所以有些我能看懂的就没从原作者那里翻译。

上节,我们完成了用户登录和注册,本节,我们将安装 Markdown 依赖包,并创建相应的服务和测试。

在本博客项目中我们将使用 Markdown 格式编辑文章。Markdown 是一种轻量级的标记语言,Markdown 的理念是能让文档更容易读、写和随意改。Markdown 格式文本可以被轻松转化为 HTML。
我们将要使用 TDD 开发流程构建将 Markdown 文本转化为 HTML 文本的服务。

安装 Markdown 依赖包

有很多 PHP 包可用于将 Markdown 转化为 HTML。这里我们使用 Michel Fortin 提供的包 SmartyPants,在本地主机上使用 Composer 安装下面两个依赖包:

composer require michelf/php-markdown 
composer require "michelf/php-smartypants=1.6.0-beta1"

如果报错:

Failed to decode response: zlib_decode(): data error
Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info

可以尝试运行:composer self-update,我是这么解决的。

创建 Markdown 测试类

请先编辑根目录下的 gulpfile.js 文件如下:

// 省略其他代码
elixir(function(mix) {
// 省略其他代码
mix.phpUnit();
// 省略其他代码
});

这里我们调用 elixir() 方法,接收的 mix 对象可以用于处理很多事情。你可以用它来将 LESS 文件编译成 CSS 文件,也可以用它来将多个 CSS 文件合并到一起,并且为合并后的文件添加版本控制,等等等等。所有这些事情都可以通过调用 mix 对象提供的接口方法来实现。

但是现在,我们只运行 PHPUnit 测试。

开启 TDD 首先要做的事情就是触发 gulp 为 tdd 模式(如果已经开启略过此步):

gulp tdd

现在 Gulp 已经在监听文件修改,一旦有“风吹草动”,就会立即运行 PHPUnit。

下面我们来创建测试类 tests\Services\MarkdownerTest.php,编辑文件内容如下:

<?php

class MarkdownerTest extends TestCase
{

protected $markdown;
public function setup()
{

$this->markdown = new \App\Services\Markdowner();
}
public function testSimpleParagraph()
{

$this->assertEquals(
"<p>test</p>\n",
$this->markdown->toHTML('test')
);
}
}

保存后,立马会在终端显示错误信息:

PHP Fatal error:  Class 'App\Services\Markdowner' not found in /home/k3/git/Code/hfblog.dev/tests/Services/MarkdownerTest.php on line 10

我们现在创建它 Class 'App\Services\Markdowner'

创建Markdowner服务

这里我们创建一个封装前面使用 Composer 安装的 php-markdown 和 php-smartypants 包的简单服务类。

新建文件:App\Services\Markdowner.php

<?php

namespace App\Services;

use Michelf\MarkdownExtra;
use Michelf\SmartyPants;

class Markdowner
{

public function toHTML($text)
{
$text = $this->preTransformText($text);
$text = MarkdownExtra::defaultTransform($text);
$text = SmartyPants::defaultTransform($text);
$text = $this->postTransformText($text);
return $text;
}

protected function preTransformText($text)
{
return $text;
}

protected function postTransformText($text)
{
return $text;
}
}

此时依然会报错,我们关闭默认的测试方法,注释ExampleTest.php里的:

public function testBasicExample()
{
// $this->visit('/')
// ->see('Laravel 5');
}

此时应该不报错了。

更加复杂的迭代测试

诚然,这并不是 TDD 的最佳示例,因为这只是先创建一个简单的测试类,然后创建实现类修复测试出现的问题。在实际应用场景中,TDD 应该有更多次的迭代,其大致流程应该像这样:

  • 创建 MarkdownerTest,定义测试方法
  • 测试失败
  • 创建 Markdowner 类,硬编码 toHTML() 进行测试
  • 测试成功
  • 修改 Markdowner 类使用 MarkdownExtra
  • 测试成功
  • 添加 testQuotes() 方法到 MarkdownerTest 类
  • 测试失败
  • 修改 Markdowner 类使用 SmartyPants
  • 测试成功

以此类推。甚至 Markdowner 类的结构都是有缺陷的,要对该类进行纯正的单元测试,应该将 MarkdownExtraSmartyPants 的实例注入到 Markdowner 的构造函数中,这样的话我们的单元测试可以注入模拟的对象并且只验证 MarkdownExtra 的行为而不是其调用的类。

但是本系列教程不是关于测试的,实际上,我们只会在这里讨论测试,我们仍将保留其结构但是会添加更多的测试。

修改 MarkdownerTest.php 文件内容如下:

<?php

class MarkdownerTest extends TestCase
{


protected $markdown;

public function setup()
{

$this->markdown = new \App\Services\Markdowner();
}

/**
* @dataProvider conversionsProvider
*/

public function testConversions($value, $expected)
{

$this->assertEquals($expected, $this->markdown->toHTML($value));
}

public function conversionsProvider()
{

return [
["test", "<p>test</p>\n"],
["# title", "<h1>title</h1>\n"],
["Here's Johnny!", "<p>Here&#8217;s Johnny!</p>\n"],
];
}
}

这里我们修改测试类同时进行多个转化测试。