PHP 使用Travis CI持续集成composer包

这篇文章的内容可以说是上一篇文章[发布自己的composer包](/my-composer-package/)的后续。主要内容分为2个部分...

这篇文章的内容可以说是上一篇文章发布自己的composer包的后续。主要内容分为2个部分:

  1. 单元测试,PHPUnit
  2. 持续集成,Travis CI

单元测试

首先单元测试的概念这里就不细说了,网上有很多资料,然后有关单元测试有没有必要这个问题,我觉得存在即是合理的,实际在使用composer可以看到很多依赖的包中本身就保留了测试的部分,往往是一个tests目录。

PHP项目的测试常用的久是PHPUnit了,PHPUnit是一个单元测试框架,关于PHPUnit可能会出一个专门的系列,这里先埋一个坑。接下来将结合实例介绍PHPUnit的安装、编写和使用。

目录结构

现在看下我们composer包的结构,如果你看过我们上一篇文章,对该结构应该会比较熟悉:

src/               
tests/              
composer.json
phpunit.xml

我们把一些类似README.md的文件先去除了,因为它们和该篇文章无关。

可以看到我们新建了一个tests目录用来存放测试的代码,然后还有一个phpunit.xml是用来配置phpunit的,后面会讲到。

安装PHPUnit

PHPUnit的全局安装和Composer的安装类似,具体的操作请看官网。我们这里就用composer来安装phpunit了。

composer require --dev phpunit/phpunit

请根据你项目的实际需要来选择phpunit的版本,当前phpunit最新版本适用于php5.6以上。

composer.json中有个字段require-dev用来列出开发或测试的依赖。--dev参数安装的就是require-dev字段中列出的包。
执行这个命令后我们的composer.json就是多出如下一段:

    "require-dev": {
        "phpunit/phpunit": "^5.7"
    }

并且我们项目下生成一个vendor的文件夹,其中存在的就是我们项目的依赖。vendor/bin/phpunit就是phpunit的二进制文件。

配置PHPUnit

当我们需要系统化的测试整个项目的时候,我们可以通过phpunit.xml(或者phpunix.xml.dist)文件来配置PHPUnit。

<?xml version="1.0" encoding="UTF-8" ?>

<phpunit bootstrap="tests/autoload.php" colors="true">
    <testsuites>
        <testsuite name="Helpers Utils Suite">
            <directory suffix="Test.php">./tests</directory>
        </testsuite>
    </testsuites>

    <filter>
        <whitelist>
            <directory suffix=".php">src</directory>
        </whitelist>
    </filter>
</phpunit>

简单的解释下上面的文件内容。首先它是个xml文件,配置内容在节点中。该节点中比较关键的一个属性是bootstrap,它需要给定一个php文件,PHPUnit在运行测试前会引入一个文件。在这里我们需要在tests目录下创建一个autoload.php文件,并自动加载composer的依赖。我们在autoload.php文件中引入composer的依赖,这样就可以在测试代码中使用依赖。

require dirname(__DIR__) . '/vendor/autoload.php';

中的需要给出测试文件的所在目录,在我们这里就是tests目录,当然测试文件都必须是*Test.php的命名。最后,节点及其子节点用于配置代码覆盖率报告所使用的白名单,这个代码覆盖度后面再说,在这里我们在给出源代码的所在目录。

编写PHPUnit

在编写我们的测试代码前,我们首先需要有一个测试的对象,我们先在src目录下写一个类。

<?php

class Arr
{
    /**
	 * Get the first value
	 * @param  $arr
	 * @return mixed|null
	 */
	public static function first(array $arr)
	{
		return reset($arr);
	}
}

这里我们写了一个Arr类,它只有一个first方法。方法很简单,用来返回数组的第一个元素。有了被测试的对象我们来写测试类,我们在tests目录下创建一个对应的测试类ArrTest.php

<?php 

class ArrTest extends \PHPUnit_Framework_TestCase
{
    public function testFirst()
    {
        $arr = [1, 2, 3];
        $this->assertEquals(1, Arr::first($arr));
    }
}

这里简单的讲一下测试类的几个点。

  1. 测试类需要继承\PHPUnit\_Framework_TestCase
  2. 类方法的名称以test开头。
  3. assertEquals用来用来对实际值与预期值的匹配做出断言。
运行PHPUnit

最后我们可以使用一下命令来执行测试。

vendor/bin/phpunit -c phpunit.xml

这时候正常情况下的输出如下图,表示测试通过。

然后我们来讲讲前面提到的代码覆盖度,再讲之前,首先要说明下我们要先装一个生成代码覆盖度的引擎,我这里用的是php的扩展xdebug,关于xdebug请自行安装。代码覆盖度一个很大的作用就是告诉我们有没有未做测试的代码。它会报告所有你在下的php文件,我们可以用下面的命令生成代码覆盖度报告:

vendor/bin/phpunit -c phpunit.xml --coverage-html coverage


其实就比前面多加了一个选项--coverage-html,这个选项指定代码覆盖度报告存放的目录。执行命令后会在converage目录下生成一个index.html文件,打开文件就可以在浏览器中看到代码覆盖度的报告。

持续集成

持续集成这个名词可能很多人都听过,但是不知道它的概念,这篇文章也许会帮到你。持续集成一个很大的好处是我们这里主要讲下如何使用Travis CI持续集成我们的项目。

第一步

首先我们将我们的项目push到github上,然后前往Travis的官网用github账号登陆,进入个人主页,在我们的项目前打钩。

第二步

在项目目录下创一个.travis.yml文件,Travis CI通过读取这个文件里的配置来进行相应的操作,那我们可以测试的命令放在这个文件里,已达到自动化测试的功能。

language: php

php:
  - 5.6
  - 7.0
  - '7.1.0alpha1'

before_script:
  - composer install

script:
  phpunit -c phpunit.xml.dist

注意我们的测试代码需要composer依赖,所以在执行测试前需要执行composer install

更多关于.travis.yml的配置请查看官方文档,我们写好.travis.yml后提交到github。

第三步

现在每当我们提交一次代码到github,Travis CI将会自动测试我们的项目。下面的示例图片是我在composer的一个项目,地址

题外话

最后,我们讲一个提高我们的README.md文档逼格的点。细心的朋友可以注意到上图中有个小图标很常见,就是这个
Build Status
这个图标可以直接让别人看到我们项目的build现状,放在文档中效果不错。

它在markdown里的形式其实就是一个图片,上图你点击这个图片它会有显示图片的地址。

示例markdown代码:

[![Build Status](https://travis-ci.org/Sidfate/helpers.svg?branch=master)](https://travis-ci.org/Sidfate/helpers)