ペアワイズ法(またはオールペア法)という、パラメータが多いテスト対象のパラメータをいい感じに生成してくれる手法と、その考えをもとにパラメータを生成してくれるPICTというコマンドラインツールがあります。
今回はそのPICTをEmacsから使うパッケージを作ってみたよというお話をしましょう。
Emacs 29以降を使っていればインストールはめちゃくちゃ簡単。
(package-vc-install
'(pict :url "git@github.com:zonuexe/pict.el.git"
:main-file "pict.el"))
この式を評価するだけでおしまいです。
PICTコマンドは別にインストールする必要がありますが、macOSユーザーなら brew install pict
だけで入ります。他のOSのユーザーは各自適当にぐぐってインストールしておいてください。
ペアワイズ法について
どんなときにペアワイズ法とPICTが役に立つかは、Web上に情報があるので各自お読みください。
筆者はテストとか詳しくない… 俺たちはプリキュアで学んで雰囲気でPICTを使っている…
org-babelを使う
「EmacsでPICTを使う」と言ったのですが、実体としてはorg-modeをインターフェイスとして活用していきましょう。
みなさまはorg-babelをご存じでしょうか。org-modeはMarkdownのような軽量マークアップ言語… ではあるのですが、より多くの豊かな機能がEmacsに統合されているのです。
そのひとつがorg-babel。
これも語るべきことは数多くありますが、Markdownのコードブロックのように文章中に埋め込んだものをさくっと実行して、結果を記録したりできます。
要はEmacs上でJupyter Notebookみたいなものが使えると考えるのがいいでしょう。
詳しくは @takeokunn の記事を読めば雰囲気が掴めるかもしれません。
ob-pictを使う
適当に新しいファイル pict-sample.org
を作って以下のコードを貼り付けてみましょう。
* Check web pages by operating system, browser and language
#+begin_src pict
OS: Windows, macOS, Debian, Android, iOS
Browser: Firefox, Chrome, Safari
Lang: English, Traditioal Chinese, Simplified Chinese, Japanese, Korean
if [OS] NOT IN {"macOS", "iOS"} then [Browser] <> "Safari";
if [OS] = "iOS" then [Browser] = "Safari";
#+end_src
ここでは、開発中のWebサービスの動作チェックをする際の「OS × ブラウザ × 言語設定」の組み合わせを絞ることを考えています。
上の部分はテストで組み合わせたいパラメータの種類、下のif
は「SafariはmacOSとiOSでだけ動作する」「iOSではSafariだけテストすればいい」という制約条件を表しています。
あくまで組み合わせを考える上での例題みたいなものなので、PICTを使ってテストケースを減らすことが実用的なのかは各自で考えてみてね!
pict.el
のインストールに成功していれば、構文にいい感じの色がついてるはずです。
#+begin_src
#+end_src
の部分がコードブロックです。Markdownの ```
に比べてずいぶんややこしいと思ったでしょう。私も三日前までそう思ってました。
C-c C-, s
で入力できます。私はリズムで体に叩き込みました。
で、このコードブロックにカーソルを合わせて C-c C-c
を押します。
すると「コードブロックのpictコードをお前のシステムで実行しちゃってええか?」みたいなことを聞かれるのでyes
と答えてやってください。
そうすると、PICTコマンドがきちんとセットアップできていれば:+RESULTS
に続いて以下のようなテーブルが展開されます。
なんか総当たりしなくても、そこそこ網羅できそうだなって組み合わせが出てきましたね!
出力はorg-tableという、org-mode組み込みの機能で表組みをいい感じにサクサクいじれるようになっています。
表を見やすくするために、C-c ^
でソートしてみましょう。
まあわかりやすくなったんじゃないでしょうか。
入園料問題を解く
もうちょっと別の例として、テストのパターンを列挙するだけではなく、「この組み合わせのときはこうなる」という結果まで含めて考えてみましょう。
PICTは「デシジョンテーブル(決定表)」を作るための手助けもできます。
次の例題として、JaSST'07 Tokyoで発表されたらしいという、「三賢者、テストを語る (DTvsCEGvsCFD)」から『入園料問題』を考えてみましょう。
上の図の通りの制約をPICTに起こしてみましょう。
#+begin_src pict
区分1: 個人, 団体
区分2: 一般, 小学生, 65歳以上, 6歳未満
県内在住: Yes, No
入場料: 1200円, 1000円, 600円, 500円, 無料
IF [区分1] = "個人" AND [区分2] = "一般" THEN [入場料] = "1200円";
IF [区分1] = "団体" AND [区分2] = "一般" THEN [入場料] = "1000円";
IF [区分1] = "個人" AND [区分2] = "小学生" THEN [入場料] = "600円";
IF [区分1] = "団体" AND [区分2] = "小学生" THEN [入場料] = "500円";
IF [区分2] = "小学生" AND [県内在住] = "Yes" THEN [入場料] = "無料";
IF [区分2] = "65歳以上" THEN [入場料] = "無料";
IF [区分2] = "6歳未満" THEN [入場料] = "無料";
#+end_src
すると以下のような表が出力されます。
このまま扱ってもいいのですが、表の縦横を転置するには:var style="transpose"
を追加します。
-#+begin_src pict
+#+begin_src pict :var style="transpose"
区分1: 個人, 団体
さらにこのままでもいいのですが、:var style="matrix"
にしてみましょう。
org-tableはM-[←↓↑→]
で上下左右の行と列をさくさく入れ替えられます。
最高!
まとめ
これらを応用すればパラメタライズドテスト(PHPUnitでいうところのDataProvider)のコード生成まで一気にこなせそうですが、一旦はここまでEmacs上で試行錯誤できるだけでそこそこ満足しています。
現状ほかのツールだとPictMasterというExcelで動くツールはもっと機能が充実していたり、CIT-BACHという別の生成エンジンと組み合わせたりランダムに複数回実行して組み合わせを自動圧縮したり賢くやってくれるみたいです。
もっとやれることはたくさんありそうなので、アイディアがある方はじゃんじゃん提案してくださいね!