初めに
状態遷移図を作成することで、システムやプログラムの振る舞いを視覚的に表現することができる。
状態遷移表を作成することで、システムやプログラムの設計やテストにおいて、状態遷移の漏れや抜けを防ぐことができる。
状態遷移図と状態遷移表は、補完関係にあり、どちらか一方では不十分である。
ここでは、状態遷移表の元となるデータをCSVで作成して、状態遷移表と状態遷移図(PlantUML)を自動生成する方法を提示する。
さらに、Nスイッチカバレッジの抽出も行い、効率的なテストの手順を提示する。
状態遷移表の元となるデータ
状態遷移とは、ある状態(s1)においてイベント(ev)が発生すると次の状態(s2)に遷移することを指す。
つまり、状態遷移は、2つの状態と1つのイベントで表現することができる。
そこで、
事前状態(s1)、事後状態(s2)、イベント(ev)
の形式でデータを作れば、状態遷移表と状態遷移図を生成できるはずである。
PlantUMLの書式は、
state s1
state s2
s1 --> s2 : ev
であるので、簡単に変換できそうだ。
データフォーマットは、上記で示したs1,s2,evに、矢印の色などの属性を表現するためのattrという項目を加えて、下記のようにする。
attrはオプションとする。
区切り文字はここでは「|」としたが、お好みでよい。
s1|s2|ev|attr
具体的な遷移のデータのサンプルを用意しよう。
いわゆるstop watchの動作の状態遷移を考える。
stop watchにはスタートボタンがあり、初期状態は「準備中」で、スタートボタンを押すと
計測中になり、再度スタートボタンを押すと停止中になるものとしよう。
これを状態遷移で表現すると以下のようになる。
もちろんこれで完成ではない。
これから状態遷移図や状態遷移表を作ることで、抜けをあぶりだして、順次完成させていく。
準備中|計測中|スタートボタン|[#blue]
計測中|停止中|スタートボタン|[#blue]
停止中|計測中|スタートボタン|[#blue]
状態遷移図(PlantUML)を生成するプログラム(awk)
ここではawkを使って変換プログラムを作る。
エラーが出ないように、自前でaliasの値を定めることにする。
関数getStateAlias()では、与えられた状態に対しaliasを発行する。
既出であれば、定義済みのalias値を戻すだけ。
初出であればstate文を出力して、発行したalias値を返す。
「[*]」は、開始および終了を示すもので、PlantUmlで事前に定義されているので、aliasは発行しない。
alias発行しないものがほかにもあればstateAliasMapに定義を加えておく。([H]とか)
function printUml(s1,s2,ev,attr) {
alias1=getStateAlias(s1);
alias2=getStateAlias(s2);
print(alias1" -"attr"-> "join(" : ",alias2,ev));
}
function join(sep,str1,str2) {
if(str1=="") {
return str2;
}
if(str2=="") {
return str1;
}
return str1""sep""str2;
}
function getStateAlias(state ,alias) {
if(stateAliasMap[state]=="") {
# 初出の時に、aliasを作成し、state文を出力する
alias = "A"(sprintf("%03d",stateAliasNumber++));
stateAliasMap[state]=alias;
print("state \""state"\" as "alias);
}
return stateAliasMap[state];
}
BEGIN{
print("@startuml");
print("hide empty description");
stateAliasMap["[*]"]="[*]";
stateAliasNumber=1;
}
NF>1{
printUml($1,$2,$3,$4);
}
END{
print("@enduml");
}
変換してみる
awk -F\| -f stateCsv2pu.awk stopWatch.state.txt > stopWatch.state.pu
@startuml
hide empty description
state "準備中" as A001
state "計測中" as A002
A001 -[#blue]-> A002 : スタートボタン
state "停止中" as A003
A002 -[#blue]-> A003 : スタートボタン
A003 -[#blue]-> A002 : スタートボタン
@enduml
stopWatch.state.puを表示できる環境で表示する。
参考までに、私はplantuml-1.2023.1.jarを使ってローカルでpngファイルを生成して表示したり、VsCodeの拡張機能で表示したりしている。
Qiitaでは、ファイル形式を「plantuml」にすれば表示できるので、Qiitaに貼り付けてもよい。
終わりに
状態遷移表の元となるデータから状態遷移図の出力は出来た。
これを見ると、おおよそstop watchらしい動きになっていることが確認できた。
あなたも、簡単な遷移のための項目を考えてCSVを起こし、stateCsv2pu.awkを使って変換してみて欲しい。
どのような構成でも、とりあえずは状態遷移図になって表示される。
状態遷移図を眺めるだけでも、足りないところが見えてくるだろう。
次回は、状態遷移表の元となるデータから2種類の状態遷移表を出力するプログラムを作成して、この図で良いか検証する。