Модульное тестирование Winforms UI - PullRequest
5 голосов
/ 15 декабря 2009

Я пишу контрольный пример для своего пользовательского элемента управления, который будет запрашивать использование MessageBox.Show for User Action с просьбой обработать или отменить операцию. Как я могу разработать свой модульный тест, чтобы имитировать взаимодействие с пользователем для продолжения?

Я не хочу, чтобы рефакторинг переместил логику на средний уровень. Это простой случай получения согласия пользователя и продолжения вызова среднего уровня. Любой интерфейс справки / идеи по реструктуризации для этого сценария также будет полезен.

Ответы [ 3 ]

7 голосов
/ 15 декабря 2009

Нажатие кнопки - это не что иное, как вызов соответствующего события click. Таким образом, вы можете построить тест вокруг этого.

Еще лучше (если это еще не так), переместите свой код из внешнего интерфейса и создайте свои юнит-тесты вокруг бизнес-действий, в противном случае вы бы вызвали их, нажав кнопку.

обновление после редактирования автором
Вы не сможете заставить это работать, пока вы не готовы разделить вещи, вы не можете строить свои модульные тесты вокруг «нажмите здесь», «нажмите там». Представьте себе следующий код:

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

Вы никогда не сможете провести модульное тестирование в случае, когда insideVariable имеет значение true; Вы можете либо:

  1. Рефакторинг вашего кода, чтобы оператор return 1 находился где-то на среднем уровне
  2. Выполните рефакторинг, чтобы оператор return 1 был методом в вашем графическом интерфейсе. Затем вы можете проверить эту функцию.

Интерфейсы приложений должны быть достаточно легко заменяемыми, поэтому там не должно храниться бизнес-логика. Модульные тесты - это просто еще один интерфейс, живущий рядом с вашим основным графическим интерфейсом.

3 голосов
/ 08 января 2010

Обеспечение решения было бы намного проще с помощью метода пользовательского интерфейса или связанных методов. Также просмотр TestMethod (s) может помочь даже неполным методам.

Если я понимаю, что ваша цель теста - определить, что происходит при разных возможностях кликов?

Вы можете настроить свой фактический метод, который запускает 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;
        }
    }
0 голосов
/ 12 октября 2015

Может быть, мы можем попробовать UI Automation, который официально от Microsoft? https://msdn.microsoft.com/en-us/library/aa348551.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...