CircleCIでPHPUnit
Aug 23, 2020
PHP
GitHub
PHPUnit
Composer
CircleCI
#Introduction This article aims to automate CI with PHPUnit using CircleCI, and the following figure is a memorandum through one sequence. ![Screenshot 2020-08-08 17.21.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/a44f6bc3-b0f9-301d-76f3-(7e7a0c424d6d.png)
GitHub repository is here [https://github.com/sakamotoyuya/circleci-phpunit)
#Environment macOS Catalina:10.15.5 (19F101) php 7.4.9 composer 1.10.10 PHPUnit 9.3.7
table of contents
- Preconditions
- Register CircleCI
- Create a repository for CI integration on GitHub
- get composer
- install PHPUnit with composer
- Create a test file to execute manually with PHPUnit
- Run PHPUnit manually
- Link repository created by CircleCI and GitHub
- Modify the Test code and push it to GitHub to make PHPUnit work with CircleCI
- Bonus: About the point that stumbled when creating config.yml
Assumptions
The procedure in this article is based on the assumption that GitHub registration work has been completed in advance. Also, as shown in the figure above, knowledge of the following technologies is required.
- git
- docker
- php
- composer
- PHPUnit
- UNIX command
Register CircleCI
- Access CircleCI ![Screenshot 2020-08-08 22.07.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/8638c07d-31d0-2def-e8cb-(d4ca02839c19.png)
- Click “Sign up with GitHub” -If you have not authenticated with GitHub, you will be prompted to authenticate with CircleCI, so authenticate with your GitHub account.
- The screen looks like this. ![Screenshot 2020-08-08 22.17.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/b7df9ea9-0c20-5513-03bb-(ad2b426975c2.png)
Create a repository for CI integration on GitHub
- Log in to GitHub (You need to register GitHub in advance.) ![Screenshot 2020-08-08 22.37.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/a07b6f71-ddb4-7754-b7c9-(0c096b832cb6.png)
- Click New. ![Screenshot 2020-08-08 22.38.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/0dd8e47c-6930-43b0-aab6-(40df73875c1c.png)
- Enter an arbitrary repository name in “Repository name”. This time, set “circleci-php unit”.
- Click on “Create repository” to display the following screen. ![Screenshot 2020-08-09 8.03.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/c8d2d232-bf6b-c28a-1e6d-(6cc0324c7b5b.png)
- It shows how to link with GitHub for each current state of bare repository (GitHub side) and non-bear repository (local side). This time, “…or create a new repository on the command line” (method to push to bare repository after creating non-bear repository locally) will be adopted.
- Copy the above command by clicking the icon in the upper right of the frame.
- Create a folder for git management. This time create it with the same name as the repository name (circleci-phpunit).
- Open “terminal.app”, move to the created “circleci-phpunit” layer, paste the one copied with the icon on the screen of GitHub and execute it.
- If the “README.md” added by the command on the GitHub page exists, the repository is ready for operation.
Get # composer To get composer, you need to install php on mac and cut the path in advance. By the way, mac includes php from the beginning, but when the version of macOS is raised, the php settings may change as backup, so in my environment [xampp](https://www.apachefriends.org/(jp/index.html) is downloaded and put in “xamppfies/bin” of xampp not through path so that php command can be used from terminal. In this state, composer can be downloaded by the following procedure.
First, move to the directory where you want to download composer.
cd project folder
Then download composer referring to the following.
Excerpt from composer homepage
php -r "copy('https://getcomposer.org/installer','composer-setup.php');"
php -r "if (hash_file('sha384','composer-setup.php') ==='e5325b19b381bfd88ce90a5ddb7823406b2a38cff6bb704b0acc289a09c8128d4a8ce2bbafcd1fcbdc38666422fe2806') (echo'installer'er echo'installer verify'installer verified' php');} echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
After downloading composer.phar, make sure the composer you downloaded works excluding the extension. *Although it can be operated as phar, the extension is omitted to shorten the command.
sakamotoyuya:circleci-phpunit sakamotoyuya$ mv composer.phar composer
sakamotoyuya:circleci-phpunit sakamotoyuya$ ./composer -v
______
/ ____/___ ____ ___ ____ ____ ________ _____
/ / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__) __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
/_/
Composer version 1.10.10 2020-08-03 11:35:19
Usage:
command [options] [arguments]
Options:
...
Install PHPUnit with composer
- Create a “composer.json” file with the following contents in the same level as the downloaded composer (hereafter called the root directory). Conducted with reference to PHPUnit homepage startup.
{
"autoload": {
"classmap": [
"src/"
]
},
"require-dev": {
"phpunit/phpunit": "^9"
}
}
There are psr-4
, psr-0
, classmap
, and files
in the autoload method, but this time we will target the classmap
that reads all the specified directories. ..
See the following for details on autoloading. composer documentation-autoload
The destination of autoload is set to src/
, and the following modules are automatically loaded in this folder.
require-dev
is called a package link.
See the following for details of the package link.
composer documentation-package links
There are two package links, require
(for production) and require-dev
(for development).
For details on how to use this, refer to the following for easy understanding.
[Laravel] Development of composer require-dev, separation in production
$ composer install --no-dev
Since the development package is not required in the production environment, execute the composer command with the –no-dev option. Then the libraries listed in the require-dev option will not be installed in vendorIn short, whether to install the package is decided by switching the compile option. Since PHPUnit is not used for production, by putting it in
require-dev
and adding the –no-dev compile option, the operation will not be introduced.
- Create a src folder in the root directory.
- The folder structure is as follows.
Root directory
|-.git: hidden folder
|- src folder
|- composer file
|- composer.json file
|- README.md file
- Move to root directory.
cd root directory
- Install PHPUnit with the following command.
$ ./composer install
To execute the composer command, you need the executable file composer
and the configuration file composer.json
read by the executable file. You need to move to the place where the file is stored and execute it.
This procedure creates the vendor folder.
Packages are installed in the vendor folder below, but this folder is often large or variable, so create a .gitignore file and exclude it from git management.
- Make a .gitignore file with the following contents.
vendor
- The directory is as follows.
Root directory
|-.git: hidden folder
|-.gitignore file...⭐️
|- src folder...
|- vendor: Folder installed by ⭐️ composer
| |-bin
│ | | |- phpunit・・・⭐️ phpunit executable
| ~
|- composer file
|- composer.json file
|- README.md file
Create a test file to execute manually with PHPUnit
- Create Human.php of operating module in src folder
<?php
class Human{
public function helloString(){
return "Hello";
}
public function goodnightString(){
return "Good night";
}
}
- Create a tests folder in the root folder. The folder structure is as follows.
Root directory
|-.git: hidden folder
|- src folder...
│ |- Human.php ・・・⭐️ Evaluation target module
|
|-tests folder...⭐️
|- vendor: folder installed by composer
| |- bin
| | |- phpunit... phpunit executable file
| ~
|- composer file
|- composer.json file
|- README.md file
- Create test code HumanTest.php to test Human.php in tests folder
<?php
use PHPUnit\Framework\TestCase;
final class SakamotoTest extends TestCase{
public function testA(){
$obj = new Human();
$this->assertSame("hello", $obj->helloString());
}
public function testB(){
$obj = new Human();
// $this->assertSame("Oh Ma Iyuga!", $obj->goodnightString());
$this->assertSame("Good night", $obj->goodnightString());
}
public function testD(){
$obj = new Human();
$this->assertSame("Good night", $obj->goodnightString());
}
}
There is a rule for the file name of the test code, and it is necessary to use something like "file name of the module you want to test + Test.php"
. Since we want to test Human.php
this time, the file name is HumanTest.php
. Also, it seems that the class name in the contents of HumanTest.php
can be operated even if it is different from the file name. The test could be executed even with the SakamotoTest
class as a trial. There is no point in doing so, so it is better to read the class name as HumanTest
according to the file name. This time it is a trial code as above, but let’s use the HumanTest
class when actually creating it.
- The folder structure at this time is as follows
Root directory
|-.git: hidden folder
|- src folder...
| |- Human.php ・・・ Module to be evaluated
|
|- tests ・・・ folder
| |-- HumanTest.php・・・⭐️Test file
|
|- vendor: folder installed by composer
| |- bin
| | |- phpunit... phpunit executable file
| ~
|- composer file
|- composer.json file
|- README.md file
Run PHPUnit manually
- Updated source code, so update autoload
$ ./composer dump-autoload
You need to run this command if you have updated the files in your project. If you do not do this, it will start in the state before the change.
- Run PHPUnit manually
$ ./vender/bin/phpunit tests
Specify the folder that contains the test code. This time, specify the tests folder. If there is no problem, the result will be as follows.
sakamotoyuya:circleci-phpunit sakamotoyuya$ ./vendor/bin/phpunit tests
PHPUnit 9.3.7 by Sebastian Bergmann and contributors.
Warning: Test case class not matching filename is deprecated
in /Users/sakamotoyuya/Documents/GitHub/circleci-phpunit/tests/HumanTest.php
Class name was'SakamotoTest', expected'HumanTest'
... 3/3 (100%)
Time: 00:00.016, Memory: 4.00 MB
OK (3 tests, 3 assertions)
... 3/3 (100%)
Time: 29 ms, Memory: 4.00 MB
OK (3 tests, 3 assertions)
If the result is OK like this, the test is OK.
Since the sample code HumanTest.php
only compares the character strings, you can check it even if it is NG by replacing the commented out parts. Up to here for manual confirmation.
From now on, this flow will be automated using CircleCI.
- Once you’ve done that, commit and push to GitHub.
git add.
git commit -m "create test environment with phpunit"
git push
Here’s what GitHub looks like after the push. ![Screenshot 2020-08-23 8.20.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/b7abd4f7-83d6-6a19-bed6-(fe7da7027046.png)
Link CI Circle and repository created on GitHub
- Login to CircleCI> Open Projects ![Screenshot 2020-08-23 9.10.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/b89cea88-0d69-af10-e1c3-(3a0ea463157d.png) Since it is linked to GitHub when registering CircleCI, the list of repositories created on GitHub is displayed.
- Click
Set Up Project
ofcircleci-phpunit
![Screenshot 2020-08-23 9.19.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/be2e5c66-ac7e-aeeb-3815-(5007f3a78e50.png) - Click
Use Existing Config
![Screenshot 2020-08-23 9.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/ac5ea9b6-6589-4100-a56e-(edee093d2c0b.png)
Did you add the config.yml file?
If you have already added .circleci/config.yml then you can start building your project.
If not, download the config.yml file before starting the build and
Add to a new folder named .circleci at the root of the repository.
The configuration file of .circleci/config.yml
is required directly under the root directory, so create the configuration file according to this.- .circleci/config.ymlを以下の内容で作成する。
version: 2.1
jobs:
build:
environment:
TZ: "Asia/Tokyo"
DEBIAN_FRONTEND: noninteractive
docker:
- image: ubuntu:latest # the primary container, where your job's commands are run
environment:
TZ: "Asia/Tokyo"
DEBIAN_FRONTEND: noninteractive
steps:
- checkout # check out the code in the project directory
- run: apt-get update && apt-get install -y tzdata
- run: apt-get install -y wget sudo gnupg
- run: sudo apt-get update
- run: sudo apt-get upgrade -y
- run: sudo apt install -y php
- run: sudo apt-get install -y php-mbstring
- run: sudo apt-get install -y php-xml
- run: sudo apt-get install -y zip
- run: sudo apt-get install -y unzip
- run: echo "Set disable_coredump false" >> /etc/sudo.conf
- run: php ./composer install && ./vendor/bin/phpunit tests
設定ファイルの詳細は後で記載する。
- 現在のフォルダ構成は以下の通りとなる
ルートディレクトリ
|- .git ・・・隠しフォルダ
|- .circleci
| |- config.yml ・・・⭐️circleciの設定ファイル
|
|- src ・・・フォルダ
| |- Human.php ・・・評価対象モジュール
|
|- tests ・・・フォルダ
| |- HumanTest.php・・・Testファイル
|
|- vendor ・・・composerによりインストールされたフォルダ
| |- bin
| | |- phpunit・・・phpunitの実行ファイル
| ~
|- composer ・・・ファイル
|- composer.json ・・・ファイル
|- README.md ・・・ファイル
- 設定ファイルを作成したら再度コミットしてプッシュする。
git add .
git commit -m "CircleCIの設定ファイル(config.yml)を作成"
git push
※GitHubの画面は省略する。
- CircleCIへログイン > Projects > phpunit-circleciのSet Up Project > Use Existing Config > Start Buildingをクリックする。
このようになるのでcircleci-phpunit #2
Actionsの一番左のアイコンをクリックする。
セットアップできているか確認できるのでSUCCESSとなっていれば問題ありませんね。 CircleCIとGitHubリポジトリとの連携は完了です。 これでローカルのソースコードを修正してGitHubにプッシュした際にCircleCIが自動的にデバッグphpunitを実行してくれる環境を作成することができました。 実際にプッシュして試す。
CircleCIでPHPUnitを動作させるためにGitHubにTestコードを修正してプッシュしてみる
- すでに成功する環境が作ってあるので、
README.md
にテストを追加してcommitしてプッシュする。
# circleci-phpunit
テスト
コマンドで以下を実行する。
git add .
git commit -m "README.mdの修正"
git push
-
CircleCI > Projects > phpunit-circleciをクリックするとこのようになっている。
RUNNING状態でconfig.yml
ファイルに従ってビルド実行中がわかる。 -
青色塗り潰し箇所の
RUNNING
をクリックすると以下の画面になる。 -
build
をクリックすると以下の画面になる。 この画面は、config.ymlファイルの設定に従って実行中の実行内容がリアルタイムで閲覧可能な画面になりる。
config.yml
ファイルを修正する際は、config.yml修正後にpush操作をして、この画面をみながら問題有無をチェックして問題あれば修正するという流れとする。
この画像ではすでにSUCCESS表示となっているが、CircleCIの無料版ではビルド時間に制限があるので、ここを確認してビルドが終わらないような問題がある場合は「・・・」からビルドの停止ができるので停止するなどしましょう。ビルドが成功または失敗する場合は、ビルド終了となる。 -
CircleCIでビルドが成功するとGitHub表示も成功表示となる。
緑色のチェック表示が入り、ビルドに失敗すると×表示となる。
おまけ・・・config.yml作成時につまづいた点について
- circleciでcheckoutした後にいる、現在の作業ディレクトリはGitHubからcheckoutしたプロジェクトのルートディレクトリとなる
- phpインストール時にタイムゾーンが聞かれてずっと停止したままとなってしまっていた。
- DockerでUbuntuを立ててそれ上に構築しようとしていたため以下を参考にしていたがわからず。
https://qiita.com/yagince/items/deba267f789604643bab - で、以下の記事を参考にtzdataをインストールすることで解決した。
https://sleepless-se.net/2018/07/31/docker-build-tzdata-ubuntu/ - タイムゾーンの設定の仕方はこれを参考にした。
- runコマンドでUNIXコマンドが叩ける。
- circleciのWEB画面上で環境変数の設定が実はできる。
- CircleCIドキュメント上の上部の検索窓も便利