# 附录:单元测试 [TOC] 仿照PHPUnit提供一个简易的单元测试框架 ## TestCase 这是基类,请继承。 ## 方法 test开头的public方法才能作为测试用例,其余将被忽略。 ## setUpBeforeClass与tearDownAfterClass setUpBeforeClass\(\) 与 tearDownAfterClass\(\) 模板方法将分别在测试用例类的第一个测试运行之前和测试用例类的最后一个测试运行之后调用 ## setUp与tearDown 测试类的每个测试方法都会运行一次 setUp\(\) 和 tearDown\(\) 模板方法 ## coroutineRequestHttpController 启动一个http的模拟访问。 ```php $testRequest = new TestRequest('/TestController/test'); $testResponse = yield $this->coroutineRequestHttpController($testRequest); $this->assertEquals($testResponse->data, 'helloworld'); ``` TestRequest中可以设置请求的一些方法。 testResponse为返回的数据。其中data为返回的值,其余见类成员。 ## coroutineRequestTcpController 启动一个tcp的模拟访问 ```php if ($this->config['server']['pack_tool'] != 'JsonPack') { $this->markTestSkipped('协议解包不是JsonPack'); } $data = ['controller_name' => 'TestController', 'method_name' => 'test', 'data' => 'helloWorld']; $reusult = yield $this->coroutineRequestTcpController($data); $this->assertCount(2, $reusult); ``` $data传进去的是一个协议体 $result是返回的服务器具体操作步骤,详情可以自己打印。 --- 特别注意这是模拟的方式,所以服务器不会产生任何的send操作,只是记录操作。 使用controller内提供的方法才能被记录,get\_instance\(\)的方法不会被记录,可能还会产生错误。 ## markTestSkipped 表示该测试被跳过。 ## @needTestTask 标注needTestTask 被标注的将会在测试的时候额外进行task同步测试。 ## @codeCoverageIgnore 标注codeCoverageIgnore 被标注的会在测试的时候被忽略 ## @depends 标注depends 对测试方法之间的显式依赖关系进行声明。 被标注的将产生依赖,和phpunit一样 ```php public function testEmpty() { $stack = []; $this->assertEmpty($stack); return $stack; } /** * @depends testEmpty */ public function testPush(array $stack) { array_push($stack, 'foo'); $this->assertEquals('foo', $stack[count($stack)-1]); $this->assertNotEmpty($stack); return $stack; } /** * @depends testPush */ public function testPop(array $stack) { $this->assertEquals('foo', array_pop($stack)); $this->assertEmpty($stack); } ``` 在上例中,第一个测试, testEmpty\(\),创建了一个新数组,并断言其为空。随后,此测试将此基境作为结果返回。第二个测试,testPush\(\),依赖于 testEmpty\(\) ,并将所依赖的测试之结果作为参数传入。最后,testPop\(\) 依赖于 testPush\(\)。 ## @dataProvider 标注dataProvider 测试方法可以接受任意参数。这些参数由数据供给器方法提供。用 @dataProvider 标注来指定使用哪个数据供给器方法。 数据供给器方法必须声明为 public,其返回值要么是一个数组,其每个元素也是数组 例子:使用带有命名数据集的数据供给器 ```php /** * @dataProvider additionProvider */ public function testAdd($a, $b, $expected) { $this->assertEquals($expected, $a + $b); } public function additionProvider() { return [ 'adding zeros' => [0, 0, 0], 'zero plus one' => [0, 1, 1], 'one plus zero' => [1, 0, 1], 'one plus one' => [1, 1, 3] ]; } ``` 如果测试同时从 @dataProvider 方法和一个或多个 @depends 测试接收数据,那么来自于数据供给器的参数将先于来自所依赖的测试的。来自于所依赖的测试的参数对于每个数据集都是一样的 例子: 在同一个测试中组合使用 @depends 和 @dataProvider ```php public function provider() { return [['provider1'], ['provider2']]; } public function testProducerFirst() { $this->assertTrue(true); return 'first'; } public function testProducerSecond() { $this->assertTrue(true); return 'second'; } /** * @depends testProducerFirst * @depends testProducerSecond * @dataProvider provider */ public function testConsumer() { $this->assertEquals( ['provider1', 'first', 'second'], func_get_args() ); } ``` ## 各种简易断言 assertEquals assertEmpty assertNotEmpty ………………