unit testingWinforms UI

我正在为我的用户控件编写一个测试用例,它会提示使用MessageBox.Show进行用户操作,要求处理或取消操作。 如何设计我的unit testing来模仿用户交互以继续?

我不想重构将逻辑移到中间层。 这是获得用户同意并继续进行中间层呼叫的简单案例。 此方案的任何帮助/想法重组UI也将有所帮助。

单击按钮只不过是调用相应的click事件。 所以你可能想围绕它建立你的测试。

更好的是(如果还不是这样),将代码从前端移出,并围绕业务操作构建unit testing,否则单击按钮即可调用。

作者编辑后更新
只要你不准备拆分东西,你就不会让它工作,你不能围绕’点击这里’,’点击那里’建立你的unit testing。 想象一下以下代码:

 private int MyFunction() { bool insideVariable = false; if(insideVariable) return 1; else return 2; } 

永远无法对insideVariable设置为true的情况进行unit testing; 你可以:

  1. 重构您的代码,以便return 1语句位于中间层的某个位置
  2. 重构,以便return 1语句是GUI中的方法。 然后,您可以测试该function。

应用程序前端应该很容易替换,因此不应该存储任何业务逻辑。 unit testing只是生活在主GUI旁边的另一个前端。

使用UI方法或相关方法发布,提供解决方案会更容易。 同时看到TestMethod甚至可以帮助不完整的方法。

如果我理解你的测试目的是确定不同的点击可能性会发生什么?

您可以使用Inversion of Control和Dependency Injection来设置触发MessageBox实际方法,如下所示:

 public class ClassUnderTest { private static Func _messageBoxLocator = MessageBox.Show; public static Func 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 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自动化? https://msdn.microsoft.com/en-us/library/aa348551.aspx