Поблочное тестирование Winforms UI

Я пишу тестовый сценарий для своего Пользовательского элемента управления, который запросит использование MessageBox. Шоу Пользовательского Действия, просящего обработать или Отменить операцию. Как я могу разработать свой модульный тест для имитации Взаимодействия с пользователем для продолжения?.

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

5
задан SKG 15 December 2009 в 20:41
поделиться

2 ответа

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

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

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

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

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

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

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

7
ответ дан 13 December 2019 в 22:09
поделиться

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

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

Вы можете настроить свой фактический метод, который запускает 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
        }


    }
}

, а затем метод тестирования (не забудьте включить с помощью 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;
        }
    }
3
ответ дан 13 December 2019 в 22:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: