使用PHPUnit进行单元测试并生成代码覆盖率报告的方法 |
安装PHPUnit 使用 #查看composer的全局bin目录 将其加入系统 path 路径 方便后续直接运行安装的命令 composer global config bin-dir --absolute #全局安装 phpunit composer global require --dev phpunit/phpunit #查看版本 phpunit --version 使用Composer构建你的项目 我们将新建一个 创建项目结构 mkdir unit && cd unit && mkdir app tests reports #结构如下 ./ ├── app #存放业务代码 ├── reports #存放覆盖率报告 └── tests #存放单元测试 使用Composer构建工程 #一路回车即可 composer init #注册命名空间 vi composer.json ... "autoload": { "psr-4": { "App\": "app/", "Tests\": "tests/" } } ... #更新命名空间 composer dump-autoload #安装 phpunit 组件库 composer require --dev phpunit/phpunit 到此我们就完成项目框架的构建,下面开始写业务和测试用例 。 编写测试用例 创建文件 <?php namespace App; class Example { private $msg = "hello world"; public function getTrue() { return true; } public function getFalse() { return false; } public function setMsg($value) { $this->msg = $value; } public function getMsg() { return $this->msg; } } 创建相应的测试文件 <?php namespace Tests; use PHPUnitFrameworkTestCase as BaseTestCase; use AppExample; class ExampleTest extends BaseTestCase { public function testGetTrue() { $example = new Example(); $result = $example->getTrue(); $this->assertTrue($result); } public function testGetFalse() { $example = new Example(); $result = $example->getFalse(); $this->assertFalse($result); } public function testGetMsg() { $example = new Example(); $result = $example->getTrue(); // $result is world not big_cat $this->assertEquals($result, "hello big_cat"); } } 执行单元测试 [root@localhost unit]# phpunit --bootstrap=vendor/autoload.php tests/ PHPUnit 6.5.14 by Sebastian Bergmann and contributors. ..F 3 / 3 (100%) Time: 61 ms, Memory: 4.00MB There was 1 failure: 1) TestsExampleTest::testGetMsg Failed asserting that 'hello big_cat' matches expected true. /opt/unit/tests/ExampleTest.php:27 /root/.config/composer/vendor/phpunit/phpunit/src/TextUI/Command.php:195 /root/.config/composer/vendor/phpunit/phpunit/src/TextUI/Command.php:148 FAILURES! Tests: 3, Assertions: 3, Failures: 1. 这是一个非常简单的测试用例类,可以看到,执行了共3个测试用例,共3个断言,共1个失败,可以参照 代码覆盖率 代码覆盖率反应的是 测试覆盖率的检测对象是我们的业务代码,PHPUnit通过检测我们编写的测试用例调用了哪些函数,哪些类,哪些方法,每一个控制流程是否都执行了一遍来计算覆盖率 。
--coverage-clover <file> Generate code coverage report in Clover XML format. --coverage-crap4j <file> Generate code coverage report in Crap4J XML format. --coverage-html <dir> Generate code coverage report in HTML format. --coverage-php <file> Export PHP_CodeCoverage object to file. --coverage-text=<file> Generate code coverage report in text format. --coverage-xml <dir> Generate code coverage report in PHPUnit XML format. 同时需要使用 phpunit --bootstrap vendor/autoload.php --coverage-html=reports/ --whitelist app/ tests/ #查看覆盖率报告 cd reports/ && php -S 0.0.0.0:8899 这样我们就对业务代码 基境共享测试数据 可能你会发现我们在每个测试方法中都创建了 我们没有办法在 即测试的执行模式并不是 testObj = new ExampleTest(); testObj->testMethod1(); testObj->testMethod2(); 而是 testObj1 = new ExampleTest(); testObj1->testMethod1(); testObj2 = new ExampleTest(); testObj2->testMethod2(); 所以
public static function setUpBeforeClass()/tearDownAfterClass()//测试类构建/解构时调用 protected function setUp()/tearDown()//测试方法执行前/后调用 protected function assertPreConditions()/assertPostConditions()//断言前/后调用 当运行测试时,每个测试类大致就是如下的执行步骤 #测试类基境构建 setUpBeforeClass #new一个测试类对象 #第一个测试用例 setUp assertPreConditions assertPostConditions tearDown #new一个测试类对象 #第二个测试用例 setUp assertPreConditions assertPostConditions tearDown ... #测试类基境解构 tearDownAfterClass 所以我们可以在测试类构建时使用 <?php namespace Tests; use AppExample; use PHPUnitFrameworkTestCase as BaseTestCase; class ExampleTest extends BaseTestCase { // 类静态属性 private static $example; public static function setUpBeforeClass() { self::$example = new Example(); } public function testGetTrue() { // 类的静态属性更新 self::$example->setMsg("hello big_cat"); $result = self::$example->getTrue(); $this->assertTrue($result); } public function testGetFalse() { $result = self::$example->getFalse(); $this->assertFalse($result); } /** * 依赖 testGetTrue 执行完毕 * @depends testGetTrue * @return [type] [description] */ public function testGetMsg() { $result = self::$example->getMsg(); $this->assertEquals($result, "hello big_cat"); } } 或者使用 public function testMethod1() { $this->assertTrue(true); return "hello"; } /** * @depends testMethod1 */ public function testMethod2($str) { $this->assertEquals("hello", $str); } #执行模式大概如下 testObj1 = new Test; $str = testObj1->testMethod1(); testObj2 = new Test; testObj2->testMethod2($str); 理解测试执行的模式还是很有帮助的,其他高级特性请浏览官方文档 。 使用phpunit.xml编排测试套件 使用测试套件来管理测试, <?xml version="1.0" encoding="UTF-8"?> <phpunit backupGlobals="false" backupStaticAttributes="false" bootstrap="./vendor/autoload.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false"> <testsuites> <!--可以定义多个 suffix 用于指定待执行的测试类文件后缀--> <testsuite name="Tests"> <directory suffix="Test.php">./test</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <!--可以定义多个 对./app下的业务代码做覆盖率统计--> <directory suffix=".php">./app</directory> </whitelist> </filter> <logging> <!--覆盖率报告生成类型和输出目录 lowUpperBound低覆盖率阈值 highLowerBound高覆盖率阈值--> <log type="coverage-html" target="./reports" lowUpperBound="35" highLowerBound="70"/> </logging> </phpunit> 然后直接运 [root@localhost unit]# phpunit PHPUnit 6.5.14 by Sebastian Bergmann and contributors. Time: 81 ms, Memory: 4.00MB No tests executed! Generating code coverage report in HTML format ... done 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家 。 您可能感兴趣的文章:
|