GUIアプリケーションの単体テストをどのように行うか?

GUIが絡むアプリケーションを作っていて困るのは、テストを意識せずにマニュアル通りの手順で作ってしまうと単体テストが容易に実行出来ない点だ。入力がGUI依存ではテストコードから上手く呼び出せないし、また処理結果をGUIに表示するような構成では人間が目視しない限り結果の成否を判断出来ない。

だから、このようなアプリケーションの開発では、単体テストでの検証を考慮して下記のような設計にしておく必要が有る。

  • GUIレイヤーと、実際の処理を行うレイヤーを分離しておく。実動作時はGUIから、単体テスト実行時はテストコードから、実処理を行うレイヤーの機能を呼び出す。もちろん実処理を行うレイヤーはGUIレイヤーに依存しないようにしておく。
  • 実処理レイヤーの結果は、デザインパターンのオブザーバーパターンにてGUIレイヤーに通知し、GUIを更新させる。これなら単体テスト実行時にはGUIに関係なく(呼び出すことなく、或いはリンクさせることなく)動作可能となる。

どうやって単体テストを行うべきか考えれば幾らでも方法は有るし、上記の構成はその一つに過ぎないけれど、いずれにしても必要なのは「テストを考慮した設計上の工夫」だと思う。GUIベッタリのロジックを書き続ける限り、テストを行う度にひたすらマウスクリックを続ける必要が有るし、その都度、処理結果を目視で確認しなければならない。そんなの面倒でしょ?

そんな手法を開発者に説明してもどういう訳か上手く伝わらないことがある。どうしてだろうかと考えてみたところ、開発環境にその一因があるのではないかと気がしてきた。例えば、VisualStudioなどの統合開発環境では画面リソースにボタンをペタペタと貼り付けて、そこをダブルクリックすればボタン押下時の処理を簡単に書けてしまう。確かに開発環境としては優れているし、簡単なアプリケーションを作るには便利だけど、単体テストを行うことを前提とした大規模アプリケーションを同じ方法で作ってしまうのは好ましくないと思う。開発規模はもちろんのこと、テスト戦略の違いによって設計や実装手法が異なるのは当然のことではないだろうか?

厄介なのは、テストの容易性云々よりも「開発環境が用意してくれるから、この方法が正しい」と頑なに思い込んでいる開発者がいることで、そんな人は「テストのためにそんな構成を自分で作るのは面倒くさい」と拒否反応を示すことも少ない。テスト実行時にひたすらマウスクリックを続ける方がずっと面倒だと思うのだけど、悲しいかな長年に渡って染みついた習慣を変えることはなかなか難しいようだ。

そんなわけで、知らないと困るので一通りの説明は行い、前向きな反応を示す開発者ならもう少し具体的な実装方法を補足し、やる気を示さないのならそこで打ち切るようにしている。手間を省いて楽をする方法は幾らでもあるのに、自分で工夫しないのは残念なことだと思うし、テスト時にひたすらマウスクリックを続ける姿を省みて「これはおかしい」と気がつかない姿勢も開発者としていかがなものかと思っている。



関連