textlintでRailsの言語リソースを校正してみる
この記事は、ソフトウェアテストの小ネタ Advent Calendar 2017 の15日目の記事です。
ソフトウェアテストの小ネタ Advent Calendar 2017
https://qiita.com/advent-calendar/2017/software-testing-koneta
『なんとかlint』をCIツールで実行して
ソフトウェアの静的テストを実施している人も多いと思いますが。
このエントリでは、
Ruby on Railsで作られたアプリケーションに含まれる自然言語に対するテストを実施してみます。
textlintとは
textlintとは、
ルールに従って文書が記載されているかを自動でチェックする校正ツールです。
textlint
https://github.com/textlint/textlint
書籍やブログの執筆を行う際に、自動校正ツールとして使われています。
説明するよりも動きを見た方がわかりやすいので、
ここまで書いたこの文章に対してtextlintを実施してみます。
# ちなみに、このブログの記事はmarkdownで管理しています
以下のように「.textlintrc」を作ります。
{
"plugins": [
"markdown"
],
"rules": {
"preset-ja-technical-writing": {
"max-ten": {
"max": 6
},
"sentence-length": {
"max": 160
},
},
"spellcheck-tech-word": true,
"no-mix-dearu-desumasu": {
"preferInHeader": "",
"preferInBody": "ですます",
"preferInList": "である",
"strict": true
}
}
}
node_modulesに、textlintを追加して実行します。
> yarn add textlint \
textlint-rule-preset-ja-technical-writing \
textlint-rule-spellcheck-tech-word \
textlint-rule-no-mix-dearu-desumasu
> node_modules/.bin/textlint source/_drafts/
・・・/takemikami.com/source/_drafts/2017-12-14-draft.md
15:25 error 弱い表現: "思います" が使われています。 preset-ja-technical-writing/ja-no-weak-phrase
32:33 error 文末が"。"で終わっていません。 preset-ja-technical-writing/ja-no-mixed-period
✖ 2 problems (2 errors, 0 warnings)
このようにルールから外れているとエラーとして表示されます。
このチェックをRailsの言語リソースに対して適用することが、
このエントリで目指すところです。
Railsアプリ内の自然言語
Railsアプリケーションで自然言語が含まれるファイルは、
(行儀よく開発されていれば)
apps/views/
とconfig/locales/
とpublic/
以下にあります。
Railsアプリケーションのディレクトリ構造のイメージ
+ apps
+ views
+ home
+ index.html.erb
+ config
+ locales
+ ja.yml
+ en.yml
+ public
+ index.html
つまり、以下のようにtexlintを実行すればチェック出来ることになります。
# config/locales以下はyaml形式以外のケースもありますが
node_modules/.bin/textlint app/views config/locales public
が、
textlintで、erbやyamlを対象として実行するpluginが無さそうなので。
プラグインを作ることにします。
textlintのプラグイン実装
ということで、yamlとerb用のpluginを作りました。
yaml用
https://github.com/takemikami/textlint-plugin-yaml
erb用
https://github.com/takemikami/textlint-plugin-erb
# erb用は中でhtmlのpluginを呼んでいるだけですが。。
以下のように追加します。
yarn add takemikami/textlint-plugin-yaml#master
yarn add takemikami/textlint-plugin-erb#master
「.textlintrc」は以下のように記載します。
{
"plugins": [
"yaml", "erb", "html"
],
"rules":
※以降省略
次のコマンドで自動チェックを実行します。
node_modules/.bin/textlint app/views config/locales public
Railsアプリへのtextlint適用
これでtextlintを実行出来るようになったので、
次は、適用するルールについて考えてみます。
以下にtextlintで使えるルールの一覧があるので、ここからピックアップしていきます。
textlintのルール一覧
https://github.com/textlint/textlint/wiki/Collection-of-textlint-rule
ここでは、以下のルールを入れてみることにします。
- textlint-rule-common-misspellings
- textlint-rule-spellchecker
以下のように追加します。
yarn add textlint-rule-common-misspellings textlint-rule-spellchecker
以下のように「.textlintrc」を編集します。
{
"plugins": [
"yaml", "erb", "html"
],
"rules": {
"common-misspellings": { "ignore": [] },
"spellchecker": {},
"preset-ja-technical-writing": {
"max-ten": {
"max": 6
},
"sentence-length": {
"max": 160
},
},
"spellcheck-tech-word": true,
"no-mix-dearu-desumasu": {
"preferInHeader": "",
"preferInBody": "ですます",
"preferInList": "である",
"strict": true
}
}
}
次のコマンドで自動チェックを実行できます。
node_modules/.bin/textlint app/views config/locales public
チェックが過剰な場合は、各ruleのパラメータを設定、
または、whitelistのfilterを使います。
textlint-filter-rule-whitelist
https://github.com/textlint/textlint-filter-rule-whitelist
以下のように「.textlintrc」にfilterを追加します。
{
※途中省略
"rules": {
※途中省略
},
"filters": {
"whitelist": { "allow": [ "word1", "word2" ] }
}
}
# word1, word2の部分に対象外とする単語を入れておきます。
このように過剰なエラーを抑制しておくとCIにも組み込むことも出来ます。
これ以外にもprhで表記ゆれをチェックするのも有効だと思います。
textlint-rule-prh
https://github.com/textlint-rule/textlint-rule-prh
今後のこと
今回、yamlの値をtextlintに読ませるpluginを作成して、
Railsの言語リソースに対して、textlintのルールを適用出来るようにしました。
が、Railsの言語リソースのyamlには、
htmlやテンプレート変数が置かれたりもするので、
その辺りはきちんとpluginで対応する必要があります(私のTODOです)。
# 今は、ひとまずwhilelistに「%{」を登録して、無視させてますが。
ソフトウェアの品質を作り込む上で、
説明やメッセージのわかりやすさも大切な部分なので。
このように自動化して、効率的に品質を上げられると嬉しいなと思いました。
ソフトウェアのメッセージのBestPracticeをまとめた、
ルールのpresetとか作ると便利な気がする。