Различия между заданным, когда тогда (GWT) и Arrange Act Assert (AAA)?

13

В TDD есть синтаксис Arrange Act Assert (AAA):

[Test]
public void Test_ReturnItemForRefund_ReturnsStockOfBlackSweatersAsTwo_WhenOneInStockAndOneIsReturned()
{
    //Arrange
    ShopStock shopStock = new ShopStock();
    Item blackSweater = new Item("ID: 25");
    shopStock.AddStock(blackSweater);
    int expectedResult = 2;
    Item blackSweaterToReturn = new Item("ID: 25");

    //Act
    shopStock.ReturnItemForRefund(blackSweaterToReturn);
    int actualResult = shopStock.GetStock("ID: 25");

    //Assert
    Assert.AreEqual(expectedResult, actualResult);
}

В тестах написания BDD используется аналогичная структура, но с синтаксисом Given When Then (GWT):

    [Given(@"a customer previously bought a black sweater from me")]
    public void GivenACustomerPreviouslyBoughtABlackSweaterFromMe()
    { /* Code goes here */   }

    [Given(@"I currently have three black sweaters left in stock")]
    public void GivenICurrentlyHaveThreeBlackSweatersLeftInStock()
    { /* Code goes here */   }

    [When(@"he returns the sweater for a refund")]
    public void WhenHeReturnsTheSweaterForARefund()
    { /* Code goes here */   }

    [Then(@"I should have four black sweaters in stock")]
    public void ThenIShouldHaveFourBlackSweatersInStock()
    { /* Code goes here */   }

Хотя их часто считают одинаковыми, есть различия. Вот несколько ключевых:

  1. GWT может быть сопоставлен непосредственно со спецификацией файла объектов в инфраструктурах BDD

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

  3. Given When и Then являются ключевыми словами в различных средах BDD, таких как SpecFlow и Cucumber.

Мой вопрос: есть ли другие различия (помимо названий) между AAA и GWT? И есть ли какая-либо причина помимо указанных выше, что одно должно быть предпочтительнее другого?

Cognitive_chaos
источник
3
Я не вижу разницы за исключением «читает больше как естественный язык». Учитывая договоренность, когда действие происходит, тогда утверждают вещи о новом государстве. '
Sjoerd Job Postmus
Я думаю, что вы нашли пару важных моментов и вряд ли получите ответ с дополнительными отличиями. Что бы ни стоило, я исключительно использую AAA для модульных тестов, так как формат полностью независим от методологии, но поощряет небольшие независимые тесты.
Амон

Ответы:

9

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

AAA очень полезен для меня, когда я тестирую свой собственный код. Если я работаю над проектом или библиотекой для себя, AAA - это мой путь. Это позволяет мне настроить все, что мне нужно для выполнения теста, а затем просто проверить его . Быстро настроить и быстро проверить, что мой код работает, как я ожидаю.

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

  • Требование на уровне пользователя: учитывая, что на складе имеется не менее N товара (ов) в инвентаре, когда пользователь покупает N товара (ов), тогда склад отгружает N товара (ов) пользователю
  • Требование уровня системы 1: учитывая, что в системе инвентаризации имеется N элементов в инвентаре, когда в систему инвентаризации вводится запрос на N элементов, система инвентаризации уменьшает количество инвентарных единиц для данного типа позиции.
  • Требование 2-го уровня системы: учитывая, что платежная система имеет N товар (ов) в инвентаре, когда запрос на N товар (ов) вводится в платежную систему, тогда платежная система взимает с пользователя плату за N товар (ов)
  • ...
  • Требование на уровне программиста 1: Если 5 свитеров находятся в инвентаре, когда 3 свитера вынуты из инвентаря, тогда 2 инвентаря остаются в инвентаре
  • ...

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

Напротив, тест ААА может выглядеть следующим образом. Для меня это очень важно для программиста и не полезно для бизнеса. Это не означает, что подобная древовидная структура требований не может быть создана из стратегии тестирования AAA, но ничто на языке AAA не облегчает это.

public void Test_CaseWhereThereAreEnoughSweatersLeft() {
    // Arrange
    // setup Sweater Inventory mock (DB mocks, etc)
    // count = 5
    // when The number of sweaters remaining is request, return count
    // when Inventory is requested to remove N items, then count = count - N

    // Act
    // call the Unit Under Test to remove 3 items from inventory

    // Assert
    // the number of sweaters in the inventory is 2
    // the removal should return indicating a successful removal of items from the inventory
}

public void Test_CaseWhereThereAreNotEnoughSweatersLeft() {
    // Arrange
    // setup Sweater Inventory mock (DB mocks, etc)
    // count = 2
    // when The number of sweaters remaining is request, return count
    // when Inventory is requested to remove N items, then count = count - N

    // Act
    // call the Unit Under Test to remove 3 items from inventory

    // Assert
    // the number of sweaters remaining is still 2
    // the removal should return an error indicating not enough items in the inventory
}
Фрэнк Брайс
источник
Мне всегда интересно, когда люди задаются вопросом, повышают ли компьютеры (и, следовательно, программисты) ценность для их бизнеса. Неужели это действительно большая корыстная коряга? Я думаю, что бизнес-менеджер должен либо достаточно узнать о программировании, чтобы понять, как оно выполняет свои цели, либо просто верить в это и не беспокоиться. Возможно, я не совсем понимаю, как работает химическое вещество, которое влияет на начало тока замедленного выпрямителя в клетках предсердия, но я определенно чувствую, как хорошо, что у него больше нет сердечной аритмии.
Абстракция важна не только для информатики. Люди будут обладать опытом в различных областях, и способность общаться с другими людьми имеет решающее значение для бизнеса. GWT - это абстракция, которая полезна для общения программистов и менеджеров (программ | проектов). Во-вторых, как программисту легко представить, что у программистов есть потенциал, чтобы приносить мало или вообще ничего для бизнеса. Наконец, стоит отметить, что GWT - это не единственный способ общения программистов и менеджеров, а один из многих инструментов, которые бизнес может захотеть попробовать.
Фрэнк Брайс
Кроме того, я бы хотел, чтобы мой врач понял, почему мой механизм коррекции сердечной аритмии работает до того, как его включили, а не только, что он работает. Тесты GWT должны помочь ответить на вопрос «почему». GWT помогает взаимодействию между программистом и менеджером по продукту аналогично общению между химиком и врачом. Менеджер по продукту сообщает пользователям, какие функции они получают, в то время как врач сообщает своим пациентам, какую ценность они получают с коррекцией аритмии сердца.
Фрэнк Брайс
4

Я думаю, это зависит от используемой вами структуры. В общем, насколько я понимаю, AAA поддерживается структурой NUnit и, таким образом, является естественным выбором в этом отношении. Что касается теоретических различий между TDD и BDD, то они кажутся незначительными. Смотрите эту ссылку, кто-то более квалифицированный, чем я, чтобы дать вам объяснение.

Джордж Грейнджер
источник
2

Там нет никакой разницы вообще.
Три состояния теста:
Дано = Расположить,
Когда = Действовать,
Тогда = Утвердить.

Различия, которые вы указали в вопросе, - это различия между TDD и BDD, а не GWT и AAA.

В TDD вы можете иметь три разных метода для одного теста

public class TestsOfFormatMethod
{        
    public void Arrange() { // set dependencies }
    public string Act() { // return formattted result }
    public string AssertThatFormatIsEmpty()
    {
        Arrange();
        var actual = Act();
        Assert.IsEmpty(actual);
    }
}
Fabio
источник