ソフトウェアテストの小ネタ Advent Calendar 2017 - Qiitaの7日目の記事です。
テスト業務でFreeMindを使っている現場をちらほら見ます。このFreeMindについてですが、中身はテキストベースのXMLフォーマットなので、容易に読み出しや変更を行えます。XMLパーサでスクリプトを組めば、自動で他の成果物と連携させたり、ツリーの整合性を維持したりできるようになります。
今回は実践例として、このFreeMindを使ってテスト設計技法であるクラシフィケーションツリー法の簡易的なツールを作ります(クラシフィケーションツリー法の詳細は「クラシフィケーション・ツリー法入門」を参照ください。題材の完成形は「https://github.com/hiro-iseri/fm_ctm」)。
1. FreeMindでクラシフィケーションツリーを表現する。
まずFreeMindでクラシフィケーションツリーを描きます。
クラシフィケーションツリーの表現では、最低限クラスとクラシフィケーションの区別が必要です。その区別は一般的には枠線の形で行いますが、今回は区別に操作容易なアイコンを用います。具体的には、テストの入力に指定する末端のクラシフィケーションに、フォルダアイコンを付与する表記ルールを取ります。
例題として、ラーメン二郎のツリーを描いてみました。
2. Freemindのツリーを読み込む
次にFreeMindから、テスト条件となるクラシフィケーションとクラスの抽出を行います。
今回はPythonのXMLパーサを用います。処理としては、マインドマップのノードを再帰的に巡回し、フォルダーアイコンが付与されたノード(属性BUILTINに「"folder"」格納)と、その子ノードのテキストを抽出していきます。
コードは例えば以下のようになります。ファイルパスinput_fileのファイルを解析し、クラシフィケーション名をキー、クラス名のリストを値とするディクショナリを_clsf_dictに格納しています。
import xml.etree.ElementTree as ET _clsf_dict = {} def _get_testcon_from_node(parent): """FreeMindのノードを再帰的に巡回。クラシフィケーションとクラスの組を_clsf_dictへ格納""" if [x for x in parent if x.attrib == {'BUILTIN': 'folder'}]: class_list = [] for node in list(parent): if 'TEXT' in node.attrib: class_list.append(node.attrib['TEXT'].encode(sys.stdout.encoding)) cf_text = parent.attrib['TEXT'].encode(sys.stdout.encoding) _clsf_dict[cf_text] = class_list else: for node in list(parent): _get_testcon_from_node(node) return _clsf_dict ... cls_tree = ET.parse(input_file) _get_testcon_from_node(cls_tree.getroot()) # _clsf_dictに結果格納 ...
3. ツリー結果をPICTに入力し、テスト条件リストを生成する。
最後にテスト条件一覧を出力します。
今回はFreeMindから抽出したクラシフィケーションとクラスの組を、組み合わせテストツールPICTに入力して、2ワイズカバレッジ100%のテスト条件組み合わせを出力させます。
コードは例えば以下のようになります。
前述の「2.」のディクショナリclsf_dictを入力にして、結果を標準出力に出力しています。
def _print_testcondition(clsf_dict): """クラシフィケーションとクラスの組をインプットにpictを実行。その結果を標準出力に出力""" # クラスとクラシフィケーションの組をpict形式ファイルtemp.csvとして保存 with open("temp.csv", "w") as pict_input_file: for key, classlist in clsf_dict.iteritems(): line = key + ':' + ",".join(classlist) + '\n' pict_input_file.write(line) subprocess.Popen("pict temp.csv", shell=True)
表示例は以下の通りです。
豚 アブラ 野菜 ニンニク 辛め 麺 サイズ 豚W なし 増し 増し なし 普通 小 普通 増し あり なし あり 硬め 大 豚入り あり 増し あり 増し 硬め 大 豚入り あり なし なし あり 普通 小 普通 なし なし 増し 増し 普通 大 豚W なし あり なし 増し 硬め 小 豚W あり なし あり なし 硬め 大 豚入り あり あり 増し あり 硬め 小 豚入り 増し あり あり なし 普通 小 豚W 増し 増し あり あり 普通 大 普通 なし 増し あり あり 硬め 小 豚入り なし 増し なし なし 硬め 小 豚W 増し なし 増し 増し 硬め 小 普通 あり なし あり なし 普通 大