Основанное на сценарии модульное тестирование: организация - PullRequest
1 голос
/ 21 февраля 2011

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

Если мы создадим новое тестовое приспособление для каждого сценария, мы будем создавать много приспособлений. Куда мы их положим? В одном мамонте файла? Или мы должны создать новый файл для каждого сценария и поместить этот файл в папку со всеми другими тестовыми приборами?

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

Ответы [ 2 ]

2 голосов
/ 22 февраля 2011

Тестирование на основе сценариев великолепно, и, конечно же, существует множество вариантов организации тестов.

Вложенные классы

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

[TestFixture]
public class MyClassSpecs
{
    // common helper methods here

    // additional specs/scenarios here...
    [TestFixture]
    public class WhenTheViewIsLoaded : MyClassSpecs
    {
        [Test]
        public void EnsureThatTheButtonIsEnabled()
        {
           /* etc */
        }
    }
}

В NUnit подклассы сглаживаются, и имя корневого и вложенного классов отображается как часть имени Fixture:

MyClassSpecs+WhenTheViewIsLoaded
   > EnsureThatTheButtonIsEnabled

В моих проектах я обычно создаю один классфайл по теме и сохранить все сценарии как вложенные классы.Я использую схему Visual Studio, чтобы свернуть вложенные классы.Таким образом, я могу довольно быстро увидеть все сценарии.

Файл на сценарий

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

MyClassSpecs.Scenario1.cs
MyClassSpecs.Scenario2.cs

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

Лично я разделил бы на несколько файлов, только если бы это было оправдано.

Файловая стратегия тестирования

Хотя я лично не одобряю разбиение своих приборов на несколько файлов, одна область, в которой я вижу это, имеет большой смысл:если у вас разные стратегии тестирования.Например, рассмотрим две стратегии тестирования, в которых один набор модульных тестов использует объекты Mock в качестве зависимостей, а другой - с использованием конкретных зависимостей.

MySpecs.UsingMocks.cs
MySpecs.Integration.cs

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

0 голосов
/ 23 февраля 2011

То, что вы описываете, звучит для меня очень похоже на BDD - Behavior Driven Development.Семантически вы говорите о спецификациях, а не о тестах.А ваши спецификации написаны в виде серии сценариев, часто написанных в формате, подобном Given-When-Then (GWT для краткости).Это означает, что если система находится в каком-то состоянии Когда выполняется действие Тогда происходит заметное изменение.Есть много реализаций, чтобы справиться с этим.Мой любимый на данный момент mspec (спецификации машины), фреймворк, который работает через NUnit или XUnit.Net.Другие включают Specflow и RSpec (реализация на основе ruby).

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

Надеюсь, это поможет, Ассаф.

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