Могу ли я использовать BDD путем тестирования кода низкого уровня абстракции?

Я проверил несколько ( реальных) примеров BDD, но все, что я нашел, это e2e-тесты с использованием селена. Мне было интересно, можно ли писать модульные тесты с BDD? Если да, то как такой юнит-тест должен выглядеть в корнишоне? Мне трудно представить, что записать в описание функции и сценария и как их использовать для создания документации, например, с помощью инфраструктуры сбора java.

редактировать

Я нашел пример здесь: http://jonkruger.com/blog/2010/12/13/using-cucumber-for-unit-tests-why-not/comment-page-1/

функции:

Feature: Checkout

  Scenario Outline: Checking out individual items
    Given that I have not checked anything out
    When I check out item 
    Then the total price should be the  of that item

  Examples:
    | item | unit price |
    | "A"  | 50         |
    | "B"  | 30         |
    | "C"  | 20         |
    | "D"  | 15         |

  Scenario Outline: Checking out multiple items
    Given that I have not checked anything out
    When I check out 
    Then the total price should be the  of those items

  Examples:
    | multiple items | expected total price | notes                |
    | "AAA"          | 130                  | 3 for 130            |
    | "BB"           | 45                   | 2 for 45             |
    | "CCC"          | 60                   |                      |
    | "DDD"          | 45                   |                      |
    | "BBB"          | 75                   | (2 for 45) + 30      |
    | "BABBAA"       | 205                  | order doesn't matter |
    | ""             | 0                    |                      |

  Scenario Outline: Rounding money
    When rounding "" to the nearest penny
    Then it should round it using midpoint rounding to ""

    Examples:
      | amount | rounded amount |
      | 1      | 1              |
      | 1.225  | 1.23           |
      | 1.2251 | 1.23           |
      | 1.2249 | 1.22           |
      | 1.22   | 1.22           |

определения шагов (ruby):

require 'spec_helper'

describe "Given that I have not checked anything out" do
  before :each do
    @check_out = CheckOut.new
  end

  [["A", 50], ["B", 30], ["C", 20], ["D", 15]].each do |item, unit_price|
  describe "When I check out an invididual item" do
    it "The total price should be the unit price of that item" do
      @check_out.scan(item)
      @check_out.total.should == unit_price
    end
  end
end

  [["AAA", 130], # 3 for 130
    ["BB", 45],  # 2 for 45
    ["CCC", 60],
    ["DDD", 45],
    ["BBB", 75], # (2 for 45) + 30
    ["BABBAA", 205], # order doesn't matter
    ["", 0]].each do |items, expected_total_price|
    describe "When I check out multiple items" do
      it "The total price should be the expected total price of those items" do
        individual_items = items.split(//)
        individual_items.each { |item| @check_out.scan(item) }
        @check_out.total.should == expected_total_price
      end
    end
  end
end

class RoundingTester
  include Rounding
end

[[1, 1],
  [1.225, 1.23],
  [1.2251, 1.23],
  [1.2249, 1.22],
  [1.22, 1.22]].each do |amount, rounded_amount|
  describe "When rounding an amount of money to the nearest penny" do
    it "Should round the amount using midpoint rounding" do
      RoundingTester.new.round_money(amount).should == rounded_amount
    end
  end
end

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

2 ответа

Ключевой идеей здесь является понимание разницы между описанием поведения и тестированием. В этом контексте описание поведения:

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

Тестирование имеет тенденцию быть:

  • точный
  • подробный
  • исчерпывающий
  • технический

Когда вы используете инструмент BDD, например, Cucumber для написания модульных тестов, вы, как правило, получаете тесты, которые

  1. подробный
  2. полный технических деталей, которые могут оценить только несколько человек
  3. очень дорогой в управлении
  4. трудно поддерживать

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

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

BDD описывают системы как черный ящик. Если у вас есть какие-либо слова, относящиеся к реализации, это уже не BDD. Inf3rno опубликовал пример с правильной абстракцией.

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

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

      good step definition
Given An account "FOO" with username <username> and password <password>


bad step definition (only applies to ui)
Given I am at the login page
And I enter <username> as the username
And I enter <password> as the password

Full example
Given An account "FOO" with username <username> and password <password>
When Creating an account with username <username> and password BAR
Then An error "Username already in use" is returned

Обратите внимание, что я мог бы реализовать этот последний пример для пользовательского интерфейса, для API, но я также мог бы реализовать его с помощью голосовых команд;)

Другие вопросы по тегам