2008-11-19 80 views
6

我目前正在編寫一些方法,對窗體控件進行一些基本操作,例如文本框,組框,這些操作都是通用的,並且可以在任何應用程序中使用。使用UI控件的單元測試方法

我開始編寫一些單元測試,只是想知道應該使用System.Windows.Forms中的真實窗體控件,還是應該模擬我試圖測試的部分。因此,例如:

說我有這個方法,這需要控制,如果它是一個文本框將清除Text屬性是這樣的:

 public static void clearall(this Control control) 
     { 
      if (control.GetType() == typeof(TextBox)) 
      { 
       ((TextBox)control).Clear(); 
      } 
     } 

然後我想測試這個方法讓我做一些事情像這樣:

 [TestMethod] 
     public void TestClear() 
     { 
      List<Control> listofcontrols = new List<Control>(); 
      TextBox textbox1 = new TextBox() {Text = "Hello World" }; 
      TextBox textbox2 = new TextBox() { Text = "Hello World" }; 
      TextBox textbox3 = new TextBox() { Text = "Hello World" }; 
      TextBox textbox4 = new TextBox() { Text = "Hello World" }; 

      listofcontrols.Add(textbox1); 
      listofcontrols.Add(textbox2); 
      listofcontrols.Add(textbox3); 
      listofcontrols.Add(textbox4); 

      foreach (Control control in listofcontrols) 
      { 
       control.clearall(); 
       Assert.AreEqual("", control.Text); 
      } 
     } 

我應該加入到全球化志願服務青年來System.Window.Forms我的單元測試和使用真正的文本框對象?還是我做錯了?

注意:上面的代碼只是一個例子,我沒有編譯或運行它。

回答

6

如果您嘗試通過模擬與UI控件的交互來單元測試應用程序邏輯,則應該使用MVC pattern進行一些抽象。然後,您可以擁有存根視圖並從單元測試中調用控制器方法。

如果它是您正在嘗試單元測試的實際控件,那麼您已經擁有了我。

+0

我同意,在測試.NET Framework時沒有真正的用處。微軟已經在很大程度上做到了這一點:)。 – Tigraine 2008-11-20 00:34:02

3

如果你的代碼依賴於System.Windows.Forms.Control,你所建議的甚至不會編譯。您的Control和Textbox版本只是錯誤的類型。

相反,如果你用分離的界面UI和邏輯,那麼你可以這樣做......事情是這樣的:

public interface ITextBox 
{ 
    public string Text {get; set;} 
} 

public class TextBoxAdapter : ITextBox 
{ 
    private readonly System.Windows.Forms.TextBox _textBox; 
    public TextBoxAdapter(System.Windows.Forms.TextBox textBox) 
    { 
     _textBox = textBox; 
    } 

    public string Text 
    { 
     get { return _textBox.Text; } 
     set { _textBox.Text = value; } 
    } 
} 

public class YourClass 
{ 
    private ITextBox _textBox; 
    public YourClass(ITextBox textBox) 
    { 
     _textBox = textBox; 
    } 

    public void DoSomething() 
    { 
     _textBox.Text = "twiddleMe"; 
    } 
} 

然後,在您的測試,所有你需要做的就是創建一個假的或存根ITextBox並通過它。

當我做這樣的事情時,我創建了一個稍高一級的接口......我創建了一個接口,看起來很像整個UI,並有UI實現界面。然後,我可以將所有需要的用戶界面都轉換出來,而無需真正知道它是一個Forms控件。

順便說一句,如果你想要去創造實際控制的方法,可以考慮這個博客帖子大約是:http://www.houseofbilz.com/archive/2008/10/12/winforms-automation-extensions.aspx

5

有幾種模式,是有用的從UI邏輯,包括型號 - 分離UI演示View-Controller和Model-View-Presenter(AKA Humble Dialog)的各種版本。 Humble Dialog專門爲編寫單元測試而編寫的。你應該在你的設計工具庫中有一個這樣的UI模式。

但是我發現對於簡單的表單,當框架支持它時,直接對真正的UI控件進行測試非常簡單。我已經在Java Swing和Windows.Forms中完全構建了相當健壯的用戶界面(UI)。我無法在SWT或ASP.NET中管理它,並恢復爲MVP。

爲了測試這樣的事情......

[Test] public void ShouldCopyFromAvailableToSelectedWhenAddButtonIsCLicked(){ 
    myForm.AvailableList.Items.Add("red"); 
    myForm.AvailableList.Items.Add("yellow"); 
    myForm.AvailableList.Items.Add("blue"); 

    myForm.AvailableList.SelectedIndex = 1; 
    myForm.AddButton.Click(); 

    Assert.That(myForm.AvaiableList.Items.Count, Is.EqualTo(2)); 
    Assert.That(myForm.SelectedList.Items[0], Is.EqualTo("yellow")); 
} 

...直接針對UI控件工作正常。但是如果你想開始測試鼠標移動,擊鍵或拖放,你最好選擇一個更健壯的UI模式,比如Brian建議的模式。