Diferenças entre Given When Then (GWT) e Arrange Act Assert (AAA)?


13

No TDD, há a sintaxe 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);
}

No BDD, os testes de gravação usam uma estrutura semelhante, mas com a sintaxe 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 */   }

Embora muitas vezes sejam considerados iguais, existem diferenças. Alguns dos principais são:

  1. O GWT pode ser mapeado diretamente para a especificação de um arquivo de recurso nas estruturas BDD

  2. O GWT é mais fácil para os não desenvolvedores entenderem, incentivando o uso de inglês simples e com uma breve descrição do que cada parte está fazendo

  3. Dado quando e depois são palavras-chave em várias estruturas do BDD, como SpecFlow e Cucumber

Minha pergunta é: existem outras diferenças (além dos nomes) entre AAA e GWT? E há alguma razão além das especificadas acima, de que uma deve ser preferida à outra?


3
Não vejo diferença, exceto pelo "lê mais como uma linguagem natural". Dado um arranjo, quando uma ação acontece, então afirme coisas sobre o novo estado.
Sjoerd Job Postmus

Acho que você encontrou alguns pontos relevantes e provavelmente não receberá uma resposta com diferenças adicionais. Pelo que vale, eu uso exclusivamente o AAA para testes de unidade, pois o formato é completamente independente da metodologia, mas incentiva pequenos testes independentes.
amon

Respostas:


9

Acho que você listou muito bem as diferenças na sua pergunta, no entanto, acrescentarei algumas de minhas opiniões sobre como vejo as duas abordagens.

AAA é muito útil para mim quando estou testando meu próprio código. Se estou trabalhando em um projeto ou uma biblioteca para mim, o AAA é o caminho a seguir. Ele permite que eu configure o que for necessário para executar meu teste e depois testá-lo . É rápido de configurar e rápido para verificar se meu código está funcionando conforme o esperado.

O GWT é útil em ambientes comerciais, onde o trabalho realizado pelos programadores precisa ser mapeado para o valor comercial. O valor comercial é mapeado por recursos e, esperançosamente, por recursos que não apresentam bugs. Existem muitas estratégias para mapear recursos para tarefas de programação, mas uma delas é através de requisitos. Na minha experiência, os requisitos variam de requisitos no nível do usuário até pequenas tarefas para a execução do usuário. Isso é útil porque é fácil para os gerentes entenderem como o trabalho do programador está impactando seus clientes / usuários e, portanto, por que os programadores estão agregando valor aos seus negócios

  • Requisito no nível do usuário: dado que o armazém possui pelo menos N item (s) no estoque, quando um usuário compra N item (s), o armazém envia N item (s) ao usuário
  • Requisito no nível do sistema 1: dado que o sistema de inventário possui N itens no inventário, quando uma solicitação de N item é inserida no sistema de inventário, o sistema diminui a contagem de inventário para esse tipo de item
  • Requisito 2 em nível de sistema: dado que o sistema de pagamento possui N itens no inventário, quando uma solicitação de N item é inserida no sistema de pagamento, o sistema de pagamento cobra ao usuário N itens
  • ...
  • Requisito no nível do programador 1: Dado que 5 blusas estão no inventário, quando 3 blusas são removidas do inventário, restam 2 lugares no inventário
  • ...

Esse tipo de estrutura de requisitos permite um design semelhante a uma árvore, onde todos os Requisitos no Nível do Programador mapeiam a árvore para os Requisitos no Nível do Usuário. Dessa forma, quando um requisito no nível do programador falha, você sabe qual requisito no nível do usuário é afetado.

Por outro lado, um teste AAA pode ser assim. Isso para mim é muito voltado para programadores e não é útil para os negócios. Isso não quer dizer que uma estrutura de árvore semelhante de requisitos não possa ser feita a partir de uma estratégia de teste AAA, mas nada no idioma da AAA facilita isso.

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
}

Eu sempre acho interessante quando as pessoas questionam se os computadores (e, portanto, os programadores) estão agregando valor aos seus negócios. Poderia realmente ser apenas um grande bambolê egoísta? Eu acho que um gerente de negócios deve aprender o suficiente sobre programação para entender como está alcançando seus objetivos, ou simplesmente confiar nisso e não se preocupar. Talvez eu não entenda realmente como funciona uma substância química que influencia o início da corrente retificadora retardada nas células atriais, mas posso definitivamente sentir como é bom não ter mais arritmia cardíaca.

A abstração é importante fora da Ciência da Computação. As pessoas terão experiência em diferentes áreas, e ser capaz de comunicar essa experiência com outras pessoas é crucial para os negócios. O GWT é uma abstração útil para que os programadores e gerentes (programa | projeto) se comuniquem. Segundo, como programador, é fácil imaginar que os programadores têm o potencial de produzir pouco ou nenhum valor para uma empresa. Por fim, vale a pena notar que o GWT não é a única maneira de fazer com que programadores e gerentes se comuniquem, mas uma das muitas ferramentas que uma empresa pode querer experimentar.
Frank Bryce

Além disso, gostaria que meu médico entendesse por que meu mecanismo de correção da arritmia cardíaca funciona antes de colocá-lo, não apenas o que faz. Os testes GWT devem ajudar a responder o "porquê". O GWT, ajudando a comunicação entre programador e gerente de produto, é análogo a uma comunicação entre químico e médico. Um gerente de produto comunica aos usuários quais recursos eles estão obtendo enquanto o médico está comunicando aos pacientes qual valor eles estão obtendo com a correção da arritmia cardíaca.
Frank Bryce

4

Eu acho que depende da estrutura que você está usando. Geralmente, até onde eu entendo, o AAA é suportado pela estrutura NUnit e, portanto, é a escolha natural a esse respeito. Quanto às diferenças teóricas entre TDD e BDD, elas parecem pequenas. Veja este link, alguém mais qualificado que eu para lhe dar uma explicação.


2

Não há nenhuma diferença.
Três estados de teste:
Dado = Organizar,
Quando = Agir e
Depois = Afirmar.

As diferenças que você forneceu na pergunta são as diferenças entre TDD e BDD e não GWT e AAA.

No TDD, você pode ter três métodos diferentes para um teste

public class TestsOfFormatMethod
{        
    public void Arrange() { // set dependencies }
    public string Act() { // return formattted result }
    public string AssertThatFormatIsEmpty()
    {
        Arrange();
        var actual = Act();
        Assert.IsEmpty(actual);
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.