Как я могу получить SEPFFLOW, чтобы ожидать исключения?
-
04-10-2019 - |
Вопрос
Я использую FexFlow, и я хотел бы написать сценарий, такой как следующее:
Scenario: Pressing add with an empty stack throws an exception
Given I have entered nothing into the calculator
When I press add
Then it should throw an exception
Это calculator.Add()
это будет выбрасывать исключение, так как я могу справиться с этим в методе, отмеченном [Then]
?
Решение
Отличный вопрос. Однако я не являюсь экспертом BDD, ни специфики, однако, мой первый посудок будет делать шаг назад и оценить ваш сценарий.
Вы действительно хотите использовать термины «бросить» и «исключение» в этом спецификации? Имейте в виду, что идея BDD - использовать вездесущий язык с бизнесом. В идеале они должны быть в состоянии прочитать эти сценарии и интерпретировать их.
Подумайте об изменении вашей фразы «Тогда», чтобы включить что-то вроде этого:
Scenario: Pressing add with an empty stack displays an error
Given I have entered nothing into the calculator
When I press add
Then the user is presented with an error message
Исключение все еще брошено на заднем плане, но конечный результат - это простое сообщение об ошибке.
Scott Cellware касается этой концепции в этом подкасте: http://herdingcode.com/?p=176.
Другие советы
Как новичок в специфике, я не скажу вам, что это то способ сделать это, но один способ сделать это было бы использовать ScenarioContext
для хранения исключения, брошенного в Когда;
try
{
calculator.Add(1,1);
}
catch (Exception e)
{
ScenarioContext.Current.Add("Exception_CalculatorAdd", e);
}
В твоем потом Вы могли бы проверить брошенное исключение и делать на нем утверждать;
var exception = ScenarioContext.Current["Exception_CalculatorAdd"];
Assert.That(exception, Is.Not.Null);
С этим сказал; я согласен с Scoarescoare. Когда он говорит, что вы должны сформулировать сценарий немного более «дружественными для бизнеса». Однако, используя специфику, чтобы привлечь реализацию вашей доменной модели, отготавшими исключениями и делать утверждения на них могут пригодиться.
BDD можно практиковать по поведению уровня функций или / и по поведению единичного уровня.
SEPFLOW - это инструмент BDD, который фокусируется на поведении уровня функций. Исключения не являются чем-то, что вы должны указать / наблюдать на поведении уровня функций. Исключения должны быть указаны / наблюдаются по поведению единичного уровня.
Подумайте о сценариях спецификации как живая спецификация для не технического заинтересованного участника. Вы также не пишете в спецификации, что исключение брошено, но как система ведет себя в таком случае.
Если у вас нет никаких технических заинтересованных сторон, то SEPFLOW является неправильным инструментом для вас! Не тратьте энергию в создании чтения деловых характеристик, если никто не заинтересован в чтении их!
Есть инструменты BDD, которые сосредоточены на поведении уровня единицы. В .NET Самый популярный - MSPEC (http://github.com/machine/machine.speciations.). BDD на уровне единицы также может легко быть практикой со стандартными структурами модуля-тестирования.
Что сказал, ты все еще можно проверить на исключение в Fexflow.
Вот еще несколько обсуждений BDD на уровне единицы против BDD на уровне функций:Тестирование устройства SEPFLOW / BDD VS BDD для приемочных тестов против BDD для модульных тестов (или: ATDD против TDD)
Также посмотрите на этот блог пост:Классифицирующие BDD Tools (English-Test-Test vs. Примещенные тестирование) и немного истории BDD
Изменение сценария, чтобы не иметь исключения, это возможно, хороший способ иметь сценарий больше ориентированного пользователем. Однако, если вам еще нужно работать, пожалуйста, рассмотрите следующее:
Поймайте исключение (я действительно рекомендую ловить конкретные исключения, если только вам действительно не нужно ловить) на шаге, который вызывает операцию и передает ее в контекст сценариев.
[When("I press add")] public void WhenIPressAdd() { try { _calc.Add(); } catch (Exception err) { ScenarioContext.Current[("Error")] = err; } }
Проверьте, что исключение хранится в контексте сценария
[Then(@"it should throw an exception")] public void ThenItShouldThrowAnException() { Assert.IsTrue(ScenarioContext.Current.ContainsKey("Error")); }
PS Это очень близко к одному из существующих ответов. Однако, если вы попробуйте получить значение из сценариоконтестка, используя синтаксис, как ниже:
var err = ScenarioContext.Current["Error"]
Он бросит другое исключение в случае, если «ошибка» не существует (и что выйдет из строя всех сценариев, которые выполняют расчеты с правильными параметрами). Так ScenarioContext.Current.ContainsKey
может быть просто более подходящим
Если вы тестируете пользовательские взаимодействия, я только советую, что уже говорилось о сосредоточенности сосредоточиться на пользовательском опыте: «Тогда пользователь представлен сообщением об ошибке». Но, если вы проверяете уровень под UI, я бы хотел поделиться своим опытом:
Я использую SEPFFLOW для разработки бизнес-слоя. В моем случае мне не волнует взаимодействие пользовательских интерфейсов, но я все еще нахожусь чрезвычайно полезным подход BDD и Fexflow.
В бизнес-уровне я не хочу спецификации, которые говорят: «Тогда пользователь представлен сообщение об ошибке«, но на самом деле проверяя, что сервис правильно отвечает на неправильный ввод. На некоторое время я сделал то, что уже говорилось о том, чтобы ловить исключение на «Когда» и проверяя его на «тогда», но я нахожу этот вариант не оптимальной, потому что если вы повторно используете «когда« шаг », который вы можете глотать Исключение, где вы этого не ожидали.
В настоящее время я использую явные «Тогда» пункты, несколько раз без «Когда», таким образом:
Scenario: Adding with an empty stack causes an error
Given I have entered nothing into the calculator
Then adding causes an error X
Это позволяет мне конкретно код действия и обнаружение исключения за один шаг. Я могу повторно использовать его, чтобы проверить как можно больше ошибок, как я хочу, и он не делает меня добавлять неразрешенные кода в неисправность «Когда» шаги.
Мое решение включает в себя пару предметов для реализации, но в самом конце это будет выглядеть намного более элегантно:
@CatchException
Scenario: Faulty operation throws exception
Given Some Context
When Some faulty operation invoked
Then Exception thrown with type 'ValidationException' and message 'Validation failed'
Чтобы сделать эту работу, следуйте этим 3 шагам:
Шаг 1
Марк сценариев вы ожидаете исключения с некоторым тегом, например @CatchException
:
@CatchException
Scenario: ...
Шаг 2
Определить ан AfterStep
обработчик для изменения ScenarioContext.TestStatus
быть OK
. Отказ Вы можете только захотеть игнорировать ошибки для Когда шаги, так что вы все еще можете пройти тест в потом проверка исключения. Пришлось сделать это посредством отражения как TestStatus
Собственность внутреннее:
[AfterStep("CatchException")]
public void CatchException()
{
if (ScenarioContext.Current.StepContext.StepInfo.StepDefinitionType == StepDefinitionType.When)
{
PropertyInfo testStatusProperty = typeof(ScenarioContext).GetProperty("TestStatus", BindingFlags.NonPublic | BindingFlags.Instance);
testStatusProperty.SetValue(ScenarioContext.Current, TestStatus.OK);
}
}
Шаг 3
Утверждать TestError
так же, как вы что-то подтвердили ScenarioContext
.
[Then(@"Exception thrown with type '(.*)' and message '(.*)'")]
public void ThenExceptionThrown(string type, string message)
{
Assert.AreEqual(type, ScenarioContext.Current.TestError.GetType().Name);
Assert.AreEqual(message, ScenarioContext.Current.TestError.Message);
}