模块 - 扩展单元测试

  • 作者:KK

  • 发表日期:2015.12.13


为什么要扩展

比如有个数组我们要断言它包含了哪些key,像下面这样的代码:

$urlInfo = parse_url('http://aa.com/bb/cc/dd.html');
$this->assertArrayHasKey('scheme', $urlInfo);
$this->assertArrayHasKey('host', $urlInfo);
$this->assertArrayHasKey('path', $urlInfo);

要断言parse_url解析出来的数组会包含scheme,host,path三个key于是用了三行代码去断言,但有些人肯定觉得这样写代码很烦了,虽然能复制修改一下就行,我个人也想优化这个东西,我设想比较方便的断言方法可以这样写:$this->assertArrayHasKeys('scheme,host,path', $urlInfo),这样多方便啊呵呵,哪要写三句代码那么多的?可是Codeception和PHPUnit都没有提供这样的断言方法,怎么办呢?嗯,本节内容教你增加自己的断言方法来扩展它!


实践

tests/_support目录下有几个Helper类,其实我们针对单元测试添加扩展就编辑那个已经存在的UnitHelper.php(单元测试配置中的模块)就行了,打开这个类,它是继承了Codeception\Module的,然后是一个空的类,我们增加方法代码:

use \PHPUnit_Framework_Assert;

class UnitHelper extends \Codeception\Module{
	/**
	 * 这是我们扩展的方法
	 */
	public function assertArrayHasKeys($keys, $array, $message = ''){
		foreach(explode(',', $keys) as $key){
			PHPUnit_Framework_Assert::assertArrayHasKey($key, $array, '断言' . $key . '时失败,外部消息:' . $message);
		}
	}
}

好了,可是你觉得就真的能在测试用例里$this->assertArrayHasKeys这样调用新扩展的方法了吗?不行哦,因为测试用例并不继承Helper,那怎么调用法呢?

记不记得我们生成的测试用例都有一个protected $tester这样的$tester属性声明,是它!是它!就是它!它就是Helper,来来聪明的小孩

//在测试用例里调用
$this->tester->assertArrayHasKeys('scheme,host,path', $urlInfo);

可是运行还是出错了,说assertArrayHasKeys这个方法不存在,怎么可能呢?不是说通过tester来调用吗?

调用是这样调没错,但是其实我们还少了一个重要的步骤,在《重构测试器》中已经提到过,一旦模块发生变动就要重构,所以我们需要执行以下命令:

E:
cd project1-tests	#注意要切换到测试项目目录
php E:\codecept.phar build		#就是这句代码!使用build命令使新的扩展方法生效

实际上我们这个扩展只是为UnitHelper模块增加了方法,扩展了方法,但我们并没有添加模块来扩展,接下来才是通过添加新的模块来实现扩展↓↓↓↓↓


增加自己的模块(Helper)

(这个其实不急着学,你可以先学后面的,以后真要增加自己的模块了再回来学这个小节吧^-^)

我们修改unit.suite.yml这个属于单元测试的配置文件

modules - enabled默认定义了Asserts断言模块和UnitHelper单元助手模块,一个模块就是一个类,除了自带的模块,自定义模块的开发默认情况下都在tests/_support目录下,Assert属于自带模块,UnitHelper则不属于所以你会发现_support目录下有UnitHelper.php却没有Assert.php这个类

接下来我们在_support目录下新建一个Command.php以表示我们企图增加一个叫Command的模块-_-

类名叫Command,这里顺带一提,Codeception也是遵守PSR4标准的,所以默认情况下文件前缀名请跟类名一致

记得要继承Codeception\Module这个类,这个类在codecept.phar这个压缩包里,不用管,照写就是,然后在里面写一些测试方法

回到unit.suite.yml配置文件中,在modules - enabled配置项中增加Command这个模块名称,再重构测试器即可