概要
phpunit
, phpcs
, phpmd
をcomposer test
コマンドで簡単に実行できるようにします。
準備
※ 現在のBEAR.Sundayのアプリケーションスケルトンはこの準備は完了していています。
composer.json
に以下のエントリーを記述します。
"require-dev": {
"phpunit/phpunit": "~4.8",
"squizlabs/php_codesniffer": "~2.3",
"phpmd/phpmd": "~2.3"
},
"scripts" :{
"test": [
"php vendor/phpmd/phpmd/src/bin/phpmd src text ./phpmd.xml",
"php vendor/squizlabs/php_codesniffer/scripts/phpcs",
"php vendor/phpunit/phpunit/phpunit"
]
}
phpunit.xml.dist
, phpcs.xml
, phpmd.xml
ファイルを用意します。
<phpunit bootstrap="vendor/autoload.php">
<testsuites>
<testsuite>
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
<logging>
<log type="coverage-html" target="build/coverage"/>
<log type="coverage-clover" target="build/logs/clover.xml"/>
<log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false"/>
</logging>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>
<?xml version="1.0"?>
<ruleset>
<description>The coding standard used for applications using BEAR.Sunday Framework.</description>
<rule ref="Generic.NamingConventions.UpperCaseConstantName"/>
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter"/>
<rule ref="Generic.Strings.UnnecessaryStringConcat"/>
<rule ref="PSR2">
<exclude name="Generic.Files.LineLength"/>
<exclude name="PSR2.Classes.PropertyDeclaration.Underscore"/>
<exclude name="PSR2.Methods.MethodDeclaration.Underscore"/>
</rule>
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<rule ref="PEAR.Commenting.FunctionComment">
<exclude name="PEAR.Commenting.FunctionComment.MissingReturn"/>
<exclude name="PEAR.Commenting.FunctionComment.MissingParamComment"/>
<exclude name="PEAR.Commenting.FunctionComment.SpacingBeforeTags"/>
<exclude name="PEAR.Commenting.FunctionComment.MissingParamTag"/>
<exclude name="PEAR.Commenting.FunctionComment.Missing"/>
<exclude name="PEAR.Commenting.FunctionComment.MissingReturn"/>
<exclude name="PEAR.Commenting.FunctionComment.ParameterCommentsNotAligned"/>
<exclude name="PEAR.Commenting.FileComment.Missing"/>
</rule>
<file>src</file>
<file>tests</file>
</ruleset>
<ruleset
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<!--codesize-->
<rule ref="rulesets/codesize.xml/CyclomaticComplexity">
<properties>
<property name="reportLevel" value="20"/>
</properties>
</rule>
<rule ref="rulesets/codesize.xml/NPathComplexity">
<properties>
<property name="minimum" value="200"/>
</properties>
</rule>
<rule ref="rulesets/codesize.xml/ExcessiveClassComplexity">
<properties>
<property name="maximum" value="100"/>
</properties>
</rule>
<rule ref="rulesets/codesize.xml/ExcessiveClassLength"/>
<rule ref="rulesets/codesize.xml/ExcessiveMethodLength"/>
<rule ref="rulesets/codesize.xml/ExcessiveParameterList"/>
<rule ref="rulesets/codesize.xml/ExcessivePublicCount"/>
<rule ref="rulesets/codesize.xml/TooManyFields"/>
<rule ref="rulesets/codesize.xml/TooManyMethods"/>
<!--design-->
<rule ref="rulesets/design.xml/EvalExpression"/>
<rule ref="rulesets/design.xml/ExitExpression"/>
<rule ref="rulesets/design.xml/GotoStatement" />
<rule ref="rulesets/design.xml/NumberOfChildren"/>
<rule ref="rulesets/design.xml/DepthOfInheritance"/>
<!-- <rule ref="rulesets/design.xml/CouplingBetweenObjects" /> -->
<!--naming-->
<rule ref="rulesets/naming.xml/ConstantNamingConventions"/>
<rule ref="rulesets/naming.xml/BooleanGetMethodName"/>
<!--unusedcode-->
<rule ref="rulesets/unusedcode.xml/UnusedFormalParameter"/>
<rule ref="rulesets/unusedcode.xml/UnusedLocalVariable"/>
<rule ref="rulesets/unusedcode.xml/UnusedPrivateField"/>
<rule ref="rulesets/unusedcode.xml/UnusedPrivateMethod"/>
<!--controversial-->
<rule ref="rulesets/controversial.xml/CamelCaseClassName"/>
<rule ref="rulesets/controversial.xml/CamelCasePropertyName"/>
<rule ref="rulesets/controversial.xml/CamelCaseMethodName"/>
<!--cleancode-->
<rule ref="rulesets/cleancode.xml/BooleanArgumentFlag"/>
<!-- <rule ref="rulesets/cleancode.xml/ElseExpression" /> -->
</ruleset>
phpunitの実行
vendor/bin/phpunit
で実行したユニットテストはbuild/coverage/index.html
でテストカバレッジが確認できます。
$ vendor/bin/phpunit
....
Time: 2.76 seconds, Memory: 14.50Mb
OK (4 tests, 5 assertions)
Generating code coverage report in Clover XML format ... done
Generating code coverage report in HTML format ... done
composer testの実行
composer test
コマンドでphpunit
だけでなく、phpcs
やphpmd
を合わせて実行することができます。
composer test
> php vendor/phpmd/phpmd/src/bin/phpmd src text ./phpmd.xml
> php vendor/squizlabs/php_codesniffer/scripts/phpcs
> php vendor/phpunit/phpunit/phpunit
設定値を調整する
phpmd
やphpcs
の設定ファイルを自分のプロジェクトの方針に合わせて調整します。
phpmd
CyclomaticComplexity
, NPathComplexity
, ExcessiveClassComplexity
はプログラムの複雑さ()についての値です。<properties>
タグの値を半分にするとデフォルトの厳しい値になります。
「else
句は使わない」というルールを採用する場合は<rule ref="rulesets/cleancode.xml/ElseExpression" />
のコメントを外します。
(BEAR.Sundayは全パッケージで採用しています。なぜelse
を問題にするかは http://tkramar.blogspot.jp/2008/01/else-is-evil.html を参照してください。)
ルールの詳細はhttp://phpmd.org/rules/index.html をご覧ください。
phpcs
phpcsはsrc/
とtests/
フォルダを対象にしています。
ルールの詳細はhttps://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml をご覧ください。
活用ヒント
git hook
commit時にテストが実行されます。
#!/bin/sh
composer test
phpStormのExternal Toolsで
Tools > External Tools > QA Toolsで実行できます。