воскресенье, 11 октября 2015 г.

Cucumber configurations

Иногда нужно проверить только один сценарий, для этого мы указываем кукумберу в опциях его имя:
$ mvn test -Dcucumber.options="--name 'Message is too long'"
Scenario: Message is too long
  When Sean shouts:
  """  
  This is a really long message  so long in fact that 
  I am not going to be allowed  to send it, at list 
  if I keep typing like this  until the length is over 
  the limit of 180  characters...  
  """  
  Then nobody nears Sean's message
Кроме того в имя мы можем подствить регулярное выражение и запустить несколько сценариев, которые ему подойдут!



Мы также можем указать номер строки в фича-файле:
$ mvn test -Dcucumber.options="src/test/resources/shouty/shout.feature:33"
И даже промежуток строк в файле и несколько файлом с желаемыми местами:
$ mvn test -Dcucumber.options="src/test/resources/shouty/shout.feature:18:33 other.feature:97"

В фичафайлах можно примегять теги(как аннотации) для фильтрации конкретных сценариев:
$ mvn test -Dcucumber.options="--tags @focus"
@focus
Scenario: Listener is out of range
  When Sean shouts "Free bagels!"
  Then Larry does not hear Sean's message

Теги чудесно подходят, чтобы пометить ряд сценариев для смок теста и запускать локально тесты только в смок режиме, а регрессия уже будет отлавливаться CI системой:
Feature: Distance based Shout

  In order to send location-sensitive messages to people nearby
  As a shouter
  I want to broadcast messages to people near me

  Rules:
  - max length of message is 180 characters
  - only shout to people within a certain distance
  - people remember everything they've heard

  To do:


  Background:    
    Given the range is 100    
    And the following people:
      | name      | Lucy  | Sean  | Larry |      
      | location  | 100   | 0     | 150   |
  
  @smoke  
  Scenario: Listener is within range
    When Sean shouts "Free bagels!"
    Then Lucy hears Sean's message
    
  Scenario: Listener is out of range
    When Sean shouts "Free bagels!"
    Then Larry does not hear Sean's message
  
  @smoke  
  Scenario: Two shouts
    When Sean shouts "Free bagels!"
    And Sean shouts "Free toast"
    Then Lucy hears the following messages:
      | Free bagels! |      
      | Free toast  |


Еще чудестно подоходит пометить фича-файл номером таски, потом мы без проблем можем проверять не произошла ли у нас регресия для какой-нибуть конкретной таски:
@SHUOTY-11
Feature: Distance based Shout

  In order to send location-sensitive messages to people nearby
  As a shouter
  I want to broadcast messages to people near me

  Rules:
  - max length of message is 180 characters
  - only shout to people within a certain distance
  - people remember everything they've heard


И конечно у нас есть возможность исключить указанные теги из выполнения тестов:
$ mvn test -Dcucumber.options="--tags ~@slow"

Мы можем также манипулировать несколькими тегами.
Для логического OR мы используем запятую:
$ mvn test -Dcucumber.options="--tags @important,@latest"
Для логического AND мы используем повторное указание ключевого слова:
$ mvn test -Dcucumber.options="--tags @important,@latest --tags ~@slow"

Что не знаем, что забыли, тогда так:
$ mvn test -Dcucumber.options="--help"

Плагины(-p | --plugin) мы используем для генерации репортов в разном формате(-f | --format это деприкейтид ключ).
$ mvn test -Dcucumber.options="--plugin html:target/cucumber-report"
$ mvn test -Dcucumber.options="-p json:target/cucumber-report/report.json"

Очень полезный плагин junit, который выводит результаты тестов в формате xml junit-а, а его формат понимают многие CI и выводят такие репорты у себя очень в приличном виде.
Кроме того мы можем вызывать несколько плагинов одновременно:
$ mvn test -Dcucumber.options="--plugin html:target/cucumber-report --plugin junit:target/junit.xml"

Неоценимый помощник в сохранении времени при выполнении тестов, плагин rerun
$ mvn test -Dcucumber.options="--plugin rerun:target/result-11:52.txt @target/result-11:50.txt"
- после имени плагина мы указываем в какой файл сгенерировать результат текущего запуска, в файл сливаются через пробел пути к фича-файлам с указанием номеров строк, на которых сценарии выполнились с ошибками.
- после амперсанда указивается путь к предыдущему результату рерана, в котором находятся ошибки, и кукумбер выполняет не все тесты, а только указанные в этом файле по номерам строк, так мы рано или поздно приходим к результату, когда файл будет пустой, а значит мы все пофиксили.(Тогда файл путой - выполняются все тесты).
И понятно что при первом запуске рерана мы просто не указываем файл с предыдущим результатом, а значит мы выолняем все тесты, чтобы получить свой первый файл с ошбками, если они есть:)

Когда мы меняем текста в фичах, было бы не плохо проверить ничего ли у нас не слетело, а вернее что именно у нас слетело:
$ mvn test -Dcucumber.options="--dry-run"
Все запустится, находя тесты кукумбер не будет их выполнять, просто отметит все, что осталось без реализации тестов, это бытрее чем реально выполнять все тесты.

Чтобы CI сервер не позволял комитить нереализаванные фичи, мы можем включить строгий режим, и тогда билд будет фейлиться:
$ mvn test -Dcucumber.options="--strict"
$ echo $?1

Сценарии можно писать на многих языках, на каких именно узанем список так:
$ mvn test -Dcucumber.options="--i18n help"
Узнать синтаксис для конкретного языка можно так:
$ mvn test -Dcucumber.options="--i18n ru"
...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running bakery.RunCukesTest
      | feature          | "Функция", "Функционал", "Свойство"  |
      | background       | "Предыстория", "Контекст"            |
      | scenario         | "Сценарий"                           |
      | scenario_outline | "Структура сценария"                 |
      | examples         | "Примеры"                            |
      | given            | "* ", "Допустим ", "Дано ", "Пусть " |
      | when             | "* ", "Если ", "Когда "              |
      | then             | "* ", "То ", "Тогда "                |
      | and              | "* ", "И ", "К тому же ", "Также "   |
      | but              | "* ", "Но ", "А "                    |
      | given (code)     | "Допустим", "Дано", "Пусть"          |
      | when (code)      | "Если", "Когда"                      |
      | then (code)      | "То", "Тогда"                        |
      | and (code)       | "И", "Ктомуже", "Также"              |
      | but (code)       | "Но", "А"                            |

...
Ну теперь нас не остановить:-)
# language: ru
Функционал: пример на русском

  Контекст:    
    Дано 2 яблока
    И 2 морковки
    К тому же 1 абрикос


  Сценарий: сьели все
    Допустим Вася взял 1 яблоко
    И Ваня - 1 яблоко
    Также пришел Петя и всзя 2 морковки и 1 абрикос
    Если они начали есть и мы решили проверить через 5 минут
    То фруктов не осталось
    Также не осталось овощей
Такой тест выглядит так:
package kitchen;
import cucumber.api.PendingException;
import cucumber.api.java.ru.Дано;
import cucumber.api.java.ru.Допустим;
import cucumber.api.java.ru.Если;
import cucumber.api.java.ru.То;

public class Stepdefs {

    @Дано("^(\\d+) яблока$")
    public void яблока(int arg1) throws Throwable {
        // Write code here that turns the phrase above into concrete actions
        throw new PendingException();    
    }

    @Дано("^(\\d+) морковки$")
    public void морковки(int arg1) throws Throwable {
        // Write code here that turns the phrase above into concrete actions
        throw new PendingException();
    }

Ахххх, красота............

Чтобы не писать все в командную строку, мы можем использовать либо пропертис файл, либо аннотации ранера кукумбера.

src/test/resources/cucumber.properties:
cucumber.options=--strict --plugin html:target/cucumber-report --plugin junit:target/junit.xml

Ну и через аннотации:
package shouty;
import cucumber.api.CucumberOptions;import cucumber.api.junit.Cucumber;import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(plugin = {"pretty"}, strict = true, tags = {"@smoke"})
public class RunCukesTest {
}

Комментариев нет:

Отправить комментарий