Меня представили easyb не кто иной, как создатель easyb : Эндрю Гловер . Несмотря на то, что я много слышал и читал о easyb от Энди, у меня никогда не было возможности поработать над easyb. Итак, на прошлых выходных я потратил пару часов, чтобы углубиться в эту структуру и посмотреть, было ли easyb вообще легким.
easyb — это инфраструктура BDD для платформы Java. Если вы не знаете, что такое BDD, вот цитата с сайта easyb:
Разработка, основанная на поведении (или BDD), не является чем-то новым или революционным — это всего лишь эволюционный результат разработки, основанной на тестировании, в которой слово «тест» заменяется словом «должен». Помимо семантики, многие люди обнаружили, что концепция должна быть гораздо более естественным фактором развития, чем концепция тестирования. Фактически, когда вы мыслите с точки зрения поведения (то есть, должны), вы обнаружите, что сначала писать спецификации проще, что является целью разработки, управляемой тестами, в первую очередь.
С easyb вы выражаете свою историю и спецификацию, используя специфичный для Groovy предметный язык (DSL). Вы можете использовать easyb для приложений Java и Groovy .
Что это за история? История может содержать любое количество сценариев. Каждый сценарий имеет:
* Дано (контекст)
* Когда (что-то происходит)
* Затем (что-то еще происходит)
Я использую простое приложение для входа в систему, которое было написано на Spring 2.5 и EJB 3.0. Чтобы протестировать функциональность входа в систему, мы можем написать здесь три простых сценария:
- Пользователь вводит действительные учетные данные.
- Пользователь вводит неверные учетные данные.
- Неверный логин с пустым паролем.
Позвольте мне перечислить бизнес-интерфейсы и мой класс домена здесь:
1. AccountService
package com.stelligent.easyb.samples.service;
import com.stelligent.easyb.samples.domain.Account;
/**
*
* @author msubbarao
*/
public interface AccountService {
public Account createAccount(Account info);
public Account findAccount(String userid);
}
2. ЛогинСервис
package com.stelligent.easyb.samples.service;
import com.stelligent.easyb.samples.domain.Account;
import com.stelligent.easyb.samples.exception.BusinessException;
/**
*
* @author msubbarao
*/
public interface LoginService {
public Account login(String userid, String password) throws BusinessException;
}
3. Класс домена учетной записи:
package com.stelligent.easyb.samples.domain;
import java.io.Serializable;
/**
*
* @author msubbarao
*/
public class Account implements Serializable {
private String userid;
private String email;
private String firstname;
private String lastname;
private String password;
public Account() {
}
public Account(String userid, String email, String firstname, String lastname, String password) {
this.userid = userid;
this.email = email;
this.firstname = firstname;
this.lastname = lastname;
this.password = password;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
......
}
Чтобы начать использовать easyb, вам нужно скачать библиотеки здесь .
Затем создайте папку с названием «Рассказы», в которую вы будете помещать все свои истории, как показано ниже:
Истории в easyb должны и должны быть в файле, заканчивающемся расширением .story . Таким образом, наша история входа будет помещена в файл с именем LoginServiceTest.story .
Если у вас есть история с именем AccountServiceTest.groovy , вы получите исключение как таковое:
Buildfile: /Users/meerasubbarao/Development/easyb-samples/build.xml
init:
run.easyb.stores:
[easyb] easyb готовится обработать 2 файл (ы)
[easyb] Файл поведения Easyb должен заканчиваться в Story.groovy, .story, Specification.groovy или .specification . Смотрите документацию easyb для более подробной информации.
[easyb] easyb выполнение FAILED
BUILD SUCCESSFUL
Общее время: 1 секунда
В приведенном выше случае, как показывает трассировка стека, история должна заканчиваться на « Story.groovy », и вот здесь AccountServiceTest . groovy должен быть AccountServiceTestStory.groovy.
Давайте напишем сценарий для 1 выше: пользователь вводит действительные учетные данные
scenario "User enters valid credentials", {
given "user account already exists",{
}
when "user logins",{
}
then "the system should return a valid account",{
}
}
В сценарии выше, у нас есть данные , когда и тогда . Это довольно легко, тебе не кажется? Любой в команде может написать эти сценарии. Мой следующий шаг — реализовать следующие два сценария.
scenario "User enters invalid credentials", {
given "user account already exists",{
}
when "user logins with invalid password",{
}
then "a null account should be returned",{
}
}
и последний:
scenario "Invalid login with a null password", {
given "user account already exists",{
}
when "user logins with null password", {
}
then "an exception should be thrown", {
}
}
Вышеуказанные сценарии являются просто голыми, давайте добавим немного реального кода и попробуем их запустить.
Как я упоминал ранее, у меня есть простые фиктивные реализации для AccountService и LoginService.
Три сценария с допустимым кодом будут выглядеть так:
scenario "User enters valid credentials", {
given "user account already exists",{
accountService = new AccountServiceImpl()
loginService = new LoginServiceImpl()
loginService.setAccountService(accountService)
}
when "user logins",{
account = loginService.login("meera", "password")
}
then "the system returns a valid account",{
account.getUserid().shouldBe "meera"
account.getPassword().shouldBe "password"
}
}
scenario "User enters invalid credentials", {
given "user account already exists",{
accountService = new AccountServiceImpl()
loginService = new LoginServiceImpl()
loginService.setAccountService(accountService)
}
when "user logins with invalid password",{
account = loginService.login("meera", "meera")
}
then "a null account should be returned",{
account.shouldBe null
}
}
scenario "Invalid login with a null password", {
given "user account already exists",{
accountService = new AccountServiceImpl()
loginService = new LoginServiceImpl()
loginService.setAccountService(accountService)
}
when "user logins with null password", {
enternull = {
loginService.login("meera", null)
}
}
then "an exception should be thrown", {
ensureThrows(BusinessException.class){
enternull()
}
}
}
Как только вы написали историю, нам нужно запустить ее. easyb может быть вызван через:
* командную строку
* Ant
* Maven
* IntelliJ
Я большой поклонник автоматизации, поэтому я выбрал легкий путь; Ant .
Довольно легко запустить easyb из Ant. Вот что вам нужно сделать:
1. Определить задачу:
<taskdef name="easyb" classname="org.disco.easyb.ant.BehaviorRunnerTask">
<classpath>
<path refid="easyb.classpath" />
</classpath>
</taskdef>
2. Запустите задачу:
<easyb>
<classpath>
<path refid="easyb.classpath" />
<pathelement path="${test.classes.dir}" />
<pathelement path="${build.classes.dir}" />
</classpath>
<report location="build/story.txt" format="txtstory" />
<behaviors dir="stories">
</behaviors>
</easyb>
3. Проверьте вывод:
Buildfile: /Users/meerasubbarao/Development/easyb-samples/build.xml
init:
run.easyb.stores:
[easyb] easyb is preparing to process 1 file(s)
[easyb] Running login service test story (LoginServiceTest.story)
[easyb] Scenarios run: 3, Failures: 0, Pending: 0, Time Elapsed: 0.486 sec
[easyb] 3 total behaviors run with no failures
[easyb] easyb execution passed
BUILD SUCCESSFUL
Total time: 1 second
4. История печати:
В задаче Ant в 2 мы создали report
элемент с его format
атрибутом, установленным txtstory
следующим образом:
<report location="build/story.txt" format="txtstory" />
Если вы откроете файл story.txt в папке сборки, он будет содержать отчет о сценариях выполнения, как показано ниже:
3 сценария (в том числе 0 ожидающих) выполнены успешно.
История:
сценарий тестирования службы входа. Пользователь вводит действительные учетные данные,
если учетная запись пользователя уже существует,
когда пользователь входит в систему,
затем система возвращает действительныйсценарий учетной записи. Пользователь вводит недействительные учетные данные,
если учетная запись пользователя уже существует,
когда пользователь входит в систему с неверным паролем.
тогда должна быть возвращена нулевая учетная записьсценарий Неверный вход в систему с нулевым паролем,
если учетная запись пользователя уже существует,
когда пользователь входит в систему с нулевым паролем,
тогда должно быть выдано исключение
Вышеприведенный отчет выглядит так, как мог понять даже пятиклассник, верно?
Если вы хотите использовать easyb из Maven , из командной строки или даже из IntelliJ , обратитесь к сайту easyb, где есть примеры для всех из них.
Вы можете иметь столько же given
s , when
s и then
s , сколько and
s связывает их в своих сценариях.
easyb поддерживает следующий синтаксис для must и sure. Помните, вы также можете проверить, что ваш код генерирует исключение, используя ensureThrows
вариант ensure
замыкания; как мы сделали в нашем третьем сценарии.
Вот перечень РЕКОМЕНДУЕМОГО и обеспечить синтаксис:
И вот, наконец, вердикт. Легко ли Easyb? На мой взгляд, это было очень
Что вы думаете? Попробуйте, это легко .
Обновление: Йохен Бедерсдорфер отметил, что было бы интересно посмотреть, что произойдет, если тест не пройден. Итак, вот что происходит:
В моем случае я изменил пароль для учетной записи. Первый сценарий должен был подтвердить, что имя пользователя было «meera», а пароль — «пароль». Когда вы запускаете то же самое:
Buildfile: /Users/meerasubbarao/Development/easyb-samples/build.xml
init:
run.easyb.stores:
[easyb] easyb готовится обработать 1 файл (ы)
[easyb] Запуск истории тестирования службы входа в систему (LoginServiceTest.story)
[easyb] СБОЙ Сценарии: 3, Сбои: 1, Ожидание: 0, Время истекло: 0,529 с
[easyb] «система возвращает действительную учетную запись» — ожидаемый
пароль1, но был пароль [easyb]
[easyb] easyb выполнение FAILED
BUILD SUCCESSFUL
Общее время: 1 секунда
И в файле Story.txt вы также увидите выходные данные как таковые для сценария, который не удался:
сценарий Пользователь вводит действительные учетные данные,
если учетная запись пользователя уже существует,
когда пользователь входит в систему, а
затем система возвращает действительную учетную запись [FAILURE: ожидаемый пароль1, но был паролем]