Подтвердить что ты не робот

Рекомендации по тестированию модулей приложения Windows Forms

Я написал приложение Windows Forms, и теперь я хочу написать для него некоторые модульные тесты (не точно тестирование, основанное на разработке, поскольку я пишу тесты после того, как я разработал, но лучше поздно, чем никогда!) Мой вопрос в том, что с такое приложение, как вы собираетесь писать модульные тесты, учитывая, что почти все методы и события являются частными? Я слышал о NUnit Forms, но я слышал хорошие и плохие вещи об этом, также не было никакой реальной разработки в этом проекте какое-то время, поэтому он выглядит заброшенным. Также общепризнано, что проект имеет адекватное модульное тестирование на месте, если я написал unit test случаи для всех событий, которые пользователь запускал бы нажатием/нажатием кнопок, или мне нужно было бы писать и писать unit test случаи для всех методов и выяснить способ тестирования моих личных методов?

EDIT:. Моя бизнес-логика отделена от моей логики представления, есть 1 или 2 общедоступных метода, которые моя бизнес-логика предоставляет, чтобы форма могла получить к ним доступ, но как насчет всех частных методов, которые находятся в бизнес-логика?

4b9b3361

Ответ 1

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

Теперь это все равно может оставить некоторые непроверенные функции, специфичные для конкретной формы. I.E., это форма, подключенная к сервису правильно? Для этого вы все равно можете рассмотреть что-то вроде NUnit Forms или другой альтернативы.

Ответ 2

Ключ к графическим приложениям Unit Testing состоит в том, чтобы убедиться, что вся большая часть бизнес-логики находится в отдельном классе, а не в коде.

Модели проектирования, такие как Model View Presenter и Model View Controller, могут помочь при разработке такой системы.

Чтобы привести пример:

public partial class Form1 : Form, IMyView
{
    MyPresenter Presenter;
    public Form1()
    {
        InitializeComponent();
        Presenter = new MyPresenter(this);
    }

    public string SomeData
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            MyTextBox.Text = value;
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Presenter.ChangeData();
    }
}

public interface IMyView
{
    string SomeData { get; set; }
}

public class MyPresenter
{
    private IMyView View { get; set; }
    public MyPresenter(IMyView view)
    {
        View = view;
        View.SomeData = "test string";
    }

    public void ChangeData()
    {
        View.SomeData = "Some changed data";
    }
}

Как вы можете видеть, у Формы есть только код инфраструктуры для всего. Вся ваша логика находится внутри класса Presenter, который знает только о интерфейсе View.

Если вы хотите использовать unit test, вы можете использовать инструмент Mocking, например Rhino Mocks, чтобы высмеять интерфейс View и передать его вашему ведущему.

[TestMethod]
public void TestChangeData()
{
    IMyView view = MockRepository.DynamickMock<IMyView>();
    view.Stub(v => v.SomeData).PropertyBehavior();

    MyPresenter presenter = new MyPresenter(view);

    presenter.ChangeData();

    Assert.AreEqual("Some changed data", view.SomeData);
}

Ответ 3

У вас есть несколько вариантов.

  • Используйте инструмент, например Coded UI, для тестирования через ваш пользовательский интерфейс. Это не отличный вариант, поскольку он медленнее, чем модульное тестирование, и тесты, как правило, более хрупкие.

  • Отделите свою бизнес-логику от логики представления. Если в вашем пользовательском интерфейсе имеется множество частных методов, выполняющих бизнес-логику, вы тесно связали свою бизнес-логику с презентацией. Начните идентифицировать их и переместить их для разделения классов с общедоступными интерфейсами, которые вы можете проверить. Ознакомьтесь с принципами SOLID, которые помогут вам сохранить ваш код свободно связанным и проверяемым.

Ответ 4

Разделите всю бизнес-логику на отдельный проект и unit test. Или, по крайней мере, переместить всю логику из форм в отдельные классы.

Ответ 5

Единичное тестирование представления достаточно просто, используя утверждения (www.approvaltests.com или nuget). здесь есть видео: http://www.youtube.com/watch?v=hKeKBjoSfJ8

Однако также кажется, что вы беспокоитесь о том, чтобы сделать функцию по умолчанию или публичной для того, чтобы быть в состоянии проверить функциональность.

Они обычно называются швами; способы проникновения в ваш код для тестирования. и они хороши. Когда-то люди путают конфиденциальность/общественность с безопасностью и боятся превратить частную функцию в общественность, но размышление вызовет либо, так что это не очень безопасно. В других случаях люди обеспокоены интерфейсом API для класса. Но это имеет значение только в том случае, если у вас есть открытый API, и если у вас есть приложение winform, оно, вероятно, должно быть на верхнем уровне (другие пользователи его не называют).

Вы программист, и, как таковой, вы можете легко разработать свой код. Это обычно означает немного больше, чем изменение нескольких общедоступных методов и создание нескольких методов приведения в действие, позволяющих передавать зависимости.

Например:

buttonclick += (o,e)=> {/*somecode*/};

очень сложно проверить.

private void button1_Click(object sender, EventArgs e) {/*somecode*/}

все еще сложно проверить

public void button1_Click(object sender, EventArgs e) {/*somecode*/}

легче протестировать

private void button1_Click(object sender, EventArgs e) { DoSave();}
public void DoSave(){/*somecode*/}

Действительно легко проверить!

Это удваивается, если вам нужна информация из события. то есть.

public void ZoomInto(int x, int y)

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

Ответ 6

Можно использовать шаблон MVVM (Model-View-ViewModel) с Reactive.UI, чтобы создать тестовый код WinForms. Чтобы получить разделение проблем действительно нужно. См.: Reactive.UI https://reactiveui.net/ Основной недостаток использования Winforms/MVVM/Reactive.UI заключается в том, что примеров очень мало его использование (для WinForms). Поверхность заключается в том, что она применима практически ко всем ракурсам рабочего стола и языкам. Вы учите его одному, но принципы применимы ко всем. Когда у вас много частных методов, это нормально. ИМХО: попробуйте использовать общедоступные методы, чтобы начать бизнес-процесс, который вы хотите протестировать. Вы можете использовать tell-don't-ask: https://martinfowler.com/bliki/TellDontAsk.html и по-прежнему сохранять все эти методы частными.

Можно также протестировать код, управляя пользовательским интерфейсом, но это не так рекомендуется, потому что полученные тесты (1) очень хрупкие, (2) труднее работать, а IMHO, (3) не может быть написанные на том же уровне штрафа, что и чистые тесты кода; (4) Наконец: если вы используете базу данных, вам нужно будет рассмотреть возможность ее заполнения тестовыми данными и, поскольку ваша база данных должна быть в чистом, четко определенном состоянии перед каждым тестом, (5) ваши тесты могут работать еще медленнее чем ваша мысль, поскольку вы повторно инициализируете данные для каждого теста.

Сводка: напишите свой код с хорошим SoC (например, с помощью MVVM), тогда ваш код будет иметь гораздо лучшую тестируемость.