(V0.03 on 2008.11.28)
ダウンロード
- ソース、サンプル、テストコード等。nswitch-0.30-dist.lzh
- exe化したもの。nswitch-exe.zip
概要
知合いが「状態遷移パステストのパスセグメントを導出するツールがあったらいいなあ」といかにも物欲しげに呟いていたので書いてみた。
Windowsで作成・動作確認・テストを行ないました。他のプラットフォームは未確認。
コマンドラインアプリケーションです。動かすにはRubyが必要です。WindowsならActiveScritpRubyがお勧め。
Rubyを持っていない人のために、exe2rbでexe化したものも置きました。
入力と出力
入力はファイルまたは標準入力(コマンドラインでファイル無指定時)。Ruby記法による行列(配列の配列)を食う。この行列は当該状態空間(状態遷移グラフ)の隣接行列を模したもので、ただし各成分は状態Aから状態Bへの遷移イベントを記述する。
出力はRuby記法による行列(配列の配列)。標準出力に書き出すので適宜リダイレクトされたい。出力行列の成分は状態Aから状態Bに遷移するイベントの連接となる。
入出力の各成分の書式は次の通り。(縦棒は実際には半角)
| (E) | イベントが1個の場合 |
| (E|E) | イベントが2個以上ある場合 |
遷移イベント(の連接)が複数ある場合は、それぞれを「|」で区切る。全体を「()」で括る。遷移イベントがひとつしかない場合も丸括弧で括る。
例えば状態Aから状態Bへの遷移イベントが三つある場合は、"(e1|e2|e3)"というように書く。
オプション
| オプション | 働き |
| -h | ヘルプ(usage)を出力 |
| -x | 正規化を抑止 |
| -pp | ちょっと整形して出力 |
| -sN | スイッチのレベル(N >= 2) |
「正規化を抑止」とは、出力をデフォルトの形式でなく乗算式の形で出力することを指す。(縦棒は実際には半角)
| デフォルト | 正規化抑止時 |
| (e1e2) | e1*e2 |
| (e1e2|e3e4) | e1*e2, e3*e4 |
スイッチレベルを指定しない場合(デフォルト)は1スイッチのパスセグメントを計算する。
コマンド行書式の例
Rubyのスクリプトとして明示。input-fileに入力の行列、結果を標準出力に書き出す
ruby nswitch.rb input-file
Rubyのスクリプトとして明示。結果をファイルoutput-fileに書き出す
ruby nswitch.rb input-file > output-file
nswitch.rbをコマンドとして実行。結果をファイルoutput-fileに書き出す
nswitch.rb input-file > output-file
Unixでnswithc.rbに実行可能ビットを立てた場合、Windowsで拡張子.rbをRubyに関連づけた場合はこのコマンド行が使える。
nswitch.rbをコマンドとして実行。入力は別のファイルから標準入力経由。結果を標準出力に書き出す
cat some-file | nswitch.rb
Windowsだと上の"cat"の代わりにtypeコマンドなどを使う。次のようにしても可。
nswitch.rb < some-file
文字コード
Windows上で書いたこともあり、文字コードはSJISとしている。積極的に日本語文字列を取扱うことはないが、スクリプトのコメントに日本語を使っているので念のため。
簡単な解説
状態遷移のテストの考え方に、「Nスイッチカバレッジ」というのがある。Nには0以上の整数が入る。
| N | 呼び方 | 意味 |
| 0 | 0スイッチ | 状態Aから状態Bに直接(ひとつのイベントで)遷移するパスを網羅する |
| 1 | 1スイッチ | 状態Aから状態Bに2回のイベントで遷移するパスを網羅する |
ある状態から別の状態にひとつのイベントで遷移するパスをすべて網羅すれば0スイッチカバレッジ100%、というわけ。関連リンクから辿れるPDFによれば、状態の遷移を「分岐(branch)」と見なしているらしい。なるほど。
これを計算する時に、状態遷移図(これは即ちグラフであるから)の隣接行列を作る。ただし行列の成分は辺の有無ではなく、遷移イベントで、複数あれば全部列挙する。隣接行列はそのまま0スイッチのパスセグメントになる。従ってこのツールでは取扱わない
この隣接行列を二乗すると、1スイッチのパスセグメントを導出できる。以下同様。
これを知った時は、こんなものを考え出した「テスト屋さん」ってすげいとちょっと感動した。よく知らないが、多分テスト屋さんが考え出したというか見つけたんじゃないかと思う。プログラム屋さん・設計屋さんは「隣接行列をN乗すれば、状態空間の遷移イベントを網羅できるよ!」なんて中中思いつかないんじゃないか?
関連リンク
おまけ
ソースアーカイブの方にはnswitch-xform.rbというおまけスクリプトを同梱している。
デフォルトの出力書式"(e1e2|e3e4|e5e6)"を、"e1e2+e3e4+e5e6"という書式に変換するだけの代物(全体の丸括弧なし、区切りの縦棒の代わりに+記号)。そういう書式の方がいいというリクエストがあったので書いた(もちろん、Rubyである必要は皆無)。ただ自分の考え方とはちょっと違うので別スクリプトにしたもの。コマンドラインで
nswitch.rb 入力ファイル | nswitch-xform.rb
とかすると、"e1e2+e3e4"形式で出力される。
注意
真っ正直に(何の工夫もなく)行列の乗算をしている。従って計算量はN^3くらいのオーダーとなる。(「くらい」って何だ)
自分のPCで試しにやってみたところ、状態数10位までは常識的な時間で終わる(勿論PCのクロックとかに依存)。終わったと思う。
状態数20で試したらどこか遠いところまで出かけてしまい途方に暮れた。
その前に状態数30で走らせたら150億光年の彼方に旅立った。
なので状態数の多いものに適用するのは控えた方がいいです。ま、状態数が10を超えているなら状態の捉え方を見直した方がいいとも言える(サブ状態として取り分けるとかできることが多いしそうできるものはそうした方がいい。デザイン側もテスト側も)。
ここを参照しているページ
#related: relatedプラグインは廃止されました。