我正在为我的用户控件编写一个测试用例,它将提示使用MessageBox.Show为用户操作请求处理或取消操作。 如何设计我的单元测试以模仿用户交互进行?单元测试Winforms UI
我不想重构将逻辑移动到中间层。这是获得用户许可并继续进行中间层调用的一个简单情况。任何关于此场景的帮助/想法重构UI也会有所帮助。
我正在为我的用户控件编写一个测试用例,它将提示使用MessageBox.Show为用户操作请求处理或取消操作。 如何设计我的单元测试以模仿用户交互进行?单元测试Winforms UI
我不想重构将逻辑移动到中间层。这是获得用户许可并继续进行中间层调用的一个简单情况。任何关于此场景的帮助/想法重构UI也会有所帮助。
单击按钮无非是调用相应的click
事件。所以你可能想要围绕这一点进行测试。
甚至更好(如果情况并非如此),将代码移出前端,然后围绕业务操作构建您的单元测试,否则您将通过单击按钮来调用。按作者编辑后
更新
你不会得到,只要你不准备分裂的事情这个工作,你不能建立一个围绕“点击这里”单元测试“下,点击有”。想象一下下面的代码:
private int MyFunction()
{
bool insideVariable = false;
if(insideVariable)
return 1;
else
return 2;
}
你将永远能够单元测试,其中insideVariable设置为true的情况;您可以:
return 1
声明是在某处你的中间层return 1
声明是在你的GUI的方法。然后您可以测试该功能。应用程序前端应该很容易替换,所以不应该存储业务逻辑。单元测试只是居住在主GUI旁边的另一个前端。
我可以使用SendKeys.SendWait类似的东西,但这里的问题是ShowDialog是一个阻塞呼叫 – SKG 2009-12-15 20:28:20
你不应该尝试真的点击按钮,但只是像'new Form1()。Button1_Click(this,null)'' 。 – 2009-12-15 20:29:10
+1 - 如果UI拥有足够的逻辑来重复其操作需要实际使用UI代码,那么UI包含的逻辑太多。这可能值得注意的例外 - 在这方面表现逻辑总是很棘手 - 但通常来说,可测试的代码并不在用户界面中开始。 – 2009-12-15 20:32:17
通过发布UI方法或相关方法,提供解决方案将变得更容易。也看到TestMethod(s)可以帮助甚至不完整的方法。
如果我了解您的测试目的是确定发生在不同的点击可能性上会发生什么?
你可以设置一个使用Inversion of Control和Dependency Injection这样触发MessageBox
您的实际方法:
public class ClassUnderTest
{
private static Func<string, string, MessageBoxButtons, DialogResult>
_messageBoxLocator = MessageBox.Show;
public static Func<string, string, MessageBoxButtons, DialogResult>
MessageBoxDependency
{
get { return _messageBoxLocator; }
set { _messageBoxLocator = value; }
}
private void MyMethodOld(object sender, EventArgs e)
{
if (MessageBox.Show("test", "", MessageBoxButtons.YesNo) ==
System.Windows.Forms.DialogResult.Yes)
{
//Yes code
AnsweredYes = true;
}
else
{
//No code
}
}
public bool AnsweredYes = false;
public void MyMethod(object sender, EventArgs e)
{
if (MessageBoxDependency(
"testText", "testCaption", MessageBoxButtons.YesNo)
==
System.Windows.Forms.DialogResult.Yes)
{
//proceed code
AnsweredYes = true;
}
else
{
//abort code
}
}
}
,然后测试方法(记住包括using Microsoft.VisualStudio.TestTools.UnitTesting;
在顶部)会是这样:
[TestMethod]
public void ClassUnderTest_DefaultAnsweredYes_IsFalse()
{
var classUnderTest = new ClassUnderTest();
Assert.AreEqual(false, classUnderTest.AnsweredYes);
}
[TestMethod]
public void MyMethod_UserAnswersYes_AnsweredYesIsTrue()
{
//Test Setup
Func<string, string, MessageBoxButtons, DialogResult>
fakeMessageBoxfunction =
(text, caption, buttons) =>
DialogResult.Yes;
//Create an instance of the class you are testing
var classUnderTest = new Testing.ClassUnderTest();
var oldDependency = Testing.ClassUnderTest.MessageBoxDependency;
Testing.ClassUnderTest.MessageBoxDependency = fakeMessageBoxfunction;
try
{
classUnderTest.MyMethod(null, null);
Assert.AreEqual(true, classUnderTest.AnsweredYes);
//Assert What are you trying to test?
}
finally
{ //Ensure that future tests are in the default state
Testing.ClassUnderTest.MessageBoxDependency = oldDependency;
}
}
也许我们可以试试微软正式推出的UI Automation? https://msdn.microsoft.com/en-us/library/aa348551.aspx
请使这个评论。 – ckruczek 2015-10-12 06:10:48
所以你想测试一下你的控件在点击这些控件时会做什么?或者测试本身具有阻止消息框对话框来查看中间层是否可以安全测试? – Maslow 2010-01-08 16:56:15