BDD, как и всё то, что заканчивается на DD, всё чаще и чаще используется в тестировании. При правильном подходе BDD приносит неплохой профит, но эта статья больше про инструментарий для C#.
NSpec
NSpec позволяет генерить тесты на основе спецификаций. На основе ваших тестов сгенерируется некая документация, по которой будет видно, что и как тестируется. В тестах не требуются атрибуты того же NUnit или xUnit. Поэтому выбор тестового фреймворка не будет мучительный, также вы можете ощутить всю мощность лямбда — выражений.
MSpec
MSpec практически идентичен NSpec. Вся суть схожа — спецификация описывается в коде. Он поддерживает Arrange-Act-Assert подход. Из отличий только наличие атрибутов и не такая удобность чтения кода (хотя это на любителя). Можете сравнить всё сами:
Пример для NSpec:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
void describe_Account() { //contexts can be nested n-deep and contain befores and specifications context["when withdrawing cash"] = () => { before = () => account = new Account(); context["account is in credit"] = () => { before = () => account.Balance = 500; it["the Account dispenses cash"] = () => { account.CanWithdraw(60).should_be_true(); } }; context["account is overdrawn"] = () => { before = () => account.Balance = -500; it["the Account does not dispense cash"] = () => { account.CanWithdraw(60).should_be_false(); } }; }; } |
Пример для MSpect:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[Subject("Authentication")] public class When_authenticating_an_admin_user { Establish context = () => { Subject = new SecurityService(); }; Because of = () => { Token = Subject.Authenticate("username", "password"); }; It should_indicate_the_users_role = () => { Token.Role.ShouldEqual(Roles.Admin); }; It should_have_a_unique_session_id = () => { Token.SessionId.ShouldNotBeNull(); }; static SecurityService Subject; static UserToken Token; } |
BDDfy
BDDfy может работать с любым тестовым фреймворком или, вообще, без него. Вы можете в одном файле хранить описание стори и имплементацию сценария (более подробный пример с исходным кодом смотрите по ссылке чуть раньше) и после выполнения получать красивый отчёт в BDD — стиле. Так же используя Fluent API можно сами тесты вынести в отдельный класс, полезно для тех, кто хочет больше контроля. Также данный фреймворк можно очень гибко кастомизировать под себя и свой проект. Как по мне, так данная тула наиболее удобна, чем предыдущие.
ApprovalTests
ApprovalTests очень интересная штука. Все её особенности я описывать не буду (в репозитории находится вся необходимая инфа). Использование ApprovalTests даёт профит в основном при работе с легаси кодом, который правильно работает годами вопреки всему, но его надо поддерживать и модифицировать. И вот используя эту тулу мы пишем тест, получаем результат и подтверждаем его. Файл с отчётом храним в системе контроля версий. Если мы что-то не то сделаем, то увидим сразу несостыковку результатом и дальше мы фиксим баг или аппруваем новый результат и считаем его правильным.
SpecFlow
SpecFlow для меня является самым удобным инструментом для BDD. Он позволяет держать сценарии и реализацию степов отдельно друг от друга и переходить между ними, также можно некоторые степы сделать доступными только для одного сценария, а другие расшарить между всем сценариями. Существуют и различные атрибуты, как в тестовых фреймворках. Можно также шарить объекты между сценариями и фичами. Имеется также куча и других плюшек, таких как параметры для шага, различные трансформации для описания реализации каждого шага сценария и т.д. SpecFlow предлагает платную и бесплатную версии, но мне в проде бесплатной хватило за глаза.
Все описанные инструменты можно установить через Nuget — пакеты.