お世話になります。初質問です。よろしくお願いします。
NUnit1週間目くらいの初心者です。
現在下記環境にて標準のFolderBrowserDialogによるファイル選択を含むメソッドのテストを作成しようとしております。
環境:
framework:4.5.1
言語:C#
テスト対象:windowsアプリケーション(any cpu)
NUnit:2.6.3
当然のことながらダイアログが出てきてしまうので、何らかの処理をしてあげる必要があるとは思っているのですが、UIオートメーションでやるのが普通なのか、NUnitに対応した何かがあるのか調べまわってる最中です。
もし「普通こうするよ」ってやり方がございましたらご教授いただければ幸いです。
もしそもそもそういうメソッドはテストできないとかの情報でも歓迎です。
よろしくお願いします。
以上
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
モックフレームワークを使用します。
細かい説明は省きますが、
モックフレームワークを使用すると、
メソッドの返り値などを自由に設定することが出来ます。
例えば、以下のようなモックフレームワークがあります。
- Microsoft Fakes
- Microsoft Moles (Microsoft Fakes の前身)
- Moq
- Rhino
投稿2015/02/23 13:30
総合スコア1656
0
とりあえず今回は業務絡みだったのでテストコードの実装を完了しました。
サンプルコード用意して無いですが今回行ったテストの概要を残しておきます。
概要:
・ UIオートメーションを使用しました。
・ フォルダ選択ダイアログが開くのを監視して下記処理を行うスレッドを別途用意
1. ダイアログ上のツリー(ControlType.Tree)と OKボタン(ControlType.Button)を検索・取得
2. ツリー上の項目(ControlType.TreeItem)をテスト対象のフォルダパスに沿って展開する(ExpandCollapsePattern.Pattern)
3. 終着点となる項目が見つかったらその項目を選択状態にする
4. 1で取っておいたOKボタンを押す(InvokePattern)
・ スレッドの処理が正常に終わったことと、テスト対象のメソッドの戻り値が期待値どおりかの両方をもって評価としました。
結局のところですが、仮に GetDirectoryPath メソッド自体からダイアログを表示する処理を追い出しても、アプリケーションのどこかに表示させる処理があって、それに対してもテストを作らなきゃいけないと気づいてしまいました。でしたので、もうテストを手動でやるかテスト見逃してもらうか、上記のようにダイアログを外部から操作するようにするかしか思いつきませんでした。
もっと良い方法があるぜ!っという方はどしどし情報提供お願いします。
P.S.
今回の手法で自分用のコード作ったら貼っておくかもしれません。
僕らのたびはまだはじまったばk(ry
投稿2015/02/25 12:22
総合スコア85
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ウィンドウを開く処理だけ括り出すのはどうでしょう?
プロダクトコード
lang
1public class Xxx 2{ 3 ・・・ 4 5 public string GetDirectoryPath() 6 { 7 string result = null; 8 var fbd = new FolderBrowserDialog(); 9 10 while (result == null) 11 { 12 // ShowDialog をデリゲートにして括り出し。 13 // if (fbd.ShowDialog() != DialogResult.OK) 14 if (OnShowDialog(fbd) != DialogResult.OK) 15 break; 16 17 if (本当にこのパスでいいのか) 18 result = fbd.SelectedPath; 19 } 20 21 return result; 22 } 23 24 internal Func<FolderBrowserDialog, DialogResult> OnShowDialog = fbd => fbd.ShowDialog(); 25 // internal は InternalsVisibleTo 属性でテストにだけ公開。 26}
テストコード
lang
1[TestFixture] 2public class XxxTest 3{ 4 // 例えば、GetDirectoryPath は FolderBrowserDialog がキャンセルされた場合、null を返すことを確認する。 5 [Test] 6 public void GetDirectoryPath_should_return_null_if_FolderBrowserDialog_is_cancelled() 7 { 8 // Arrange 9 var m = new Mock<Func<FolderBrowserDialog, DialogResult>>(); 10 m.Setup(_ => _(It.IsAny<FolderBrowserDialog>())).Returns(DialogResult.Cancel); 11 12 var sut = new Xxx(); 13 sut.OnShowDialog = m.Object; 14 15 16 // Act 17 var result = sut.GetDirectoryPath(); 18 19 20 // Assert 21 m.VerifyAll(); 22 Assert.IsNull(result); 23 } 24}
ちなみに私は、UI が絡む処理は、よほどのことが無い限り手動でテストする派です。テストコードのメンテナンスコストが、割に合わないことがほとんどなので :)
投稿2015/02/24 11:46
総合スコア24
0
ベストアンサー
今回の場合、自動テストの途中でユーザの操作が必要なダイアログが開くために、そこでテストが中断してしまうことが問題なのだと思います。なら、あたかもダイアログを開いたかのようにふるまってくれる仕組みがあれば、中断しなくて済むわけです。
Mockフレームワークは、その「ふりをしてくれる」仕組みです。
たとえば、下記のようなテストしたいコードがあるとします。
lang
1 var fbd = new FolderBrowserDialog(); 2 fbd.Description = "フォルダを選択してください"; 3 DialogResult dr = fbd.ShowDialog(); 4 if (dr == DialogResult.OK) { 5 return fbd.SelectedPath; 6 } 7 return null;
ここで呼び出されるFolderBrowserDialogを、実物と同じようなメソッドやプロパティを持つものに置き換え、ダイアログを開かずに済ませるのがMockフレームワークの役割です。
この時、開発中のコードはできるだけそのままで済ませたいので、条件コンパイルなどでnamespaceを入れ替えるなどの工夫が必要です。
たとえば、こんな感じでしょうか。MockというnamespaceがMock版のコントロール群を持つとします。
lang
1#if FOR_TEST 2 var fbd = new Mock.FolderBrowserDialog(); 3#else 4 var fbd = new FolderBrowserDialog(); 5#endif
投稿2015/02/23 16:46
総合スコア209
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/02/24 01:39
2015/02/24 01:57
2015/02/24 02:39
2015/02/24 03:21
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/02/24 01:58
2015/02/24 02:28
2015/02/24 02:37
2015/02/24 02:44
2015/02/24 03:12
2015/02/24 03:14
2015/02/24 03:14
2015/02/24 03:21
2015/02/24 03:29
2015/02/24 03:45
2015/02/24 03:49
2015/02/24 03:54
2015/02/24 04:23
2015/02/24 04:38