# Behat

* What is Behat
* Why Behat versus others?
* Behat Components
* How Behat Works
* Where used in Acquia (Behat with BLT and Lightning)

### **What is Behat**

* Behat is an open source Behavior Driven Development framework for PHP.
* It is a tool to test the behavior of your application, described in a special language called Gherkin.
* Behat integrates well with [BLT](https://github.com/acquia/blt). Blt uses Behat for Functional testing. Behat comes baked in when you install a drupal site with BLT
* Lightning, a very popular Drupal distribution by Acquia, uses Behat for all its functional testing. Both BLT and Lightning are primarily used together for client projects in Professional Services.

### **Why Behat versus Others?**

* Behat helps you to start developing project from “how it must behave” and not from “what concrete components it must include in particular”.
* Clients can sign off on the tests as “acceptance criteria” for completing the project.
* The tests are written in a human-readable text files, which can be easily extended by writing additional PHP methods
* Non-coders can read and understand test and can help write tests.
* It can be integrated with [Selenium](https://en.wikipedia.org/wiki/Selenium_\(software\)) and other browser emulators to generate screenshots of failures.

### **Gherkin**

Gherkin is the language that Cucumber uses to define test cases.\
It is designed to be non-technical and human readable, and collectively describes use cases relating to a software system.\
Gherkin serves two purposes: serving as your project’s documentation and automated tests.

**Gherkin Example**

```
Feature: Listing command
   In order to change the structure of the folder I am currently in
   As a UNIX user
   I need to be able see the currently available files and folders there
Scenario: List 2 files in a directory
  Given I am in a directory "test"
  And I have a file named "foo"
  And I have a file named "bar"
  When I run "ls"
  Then I should get.
"""
bar
foo
"""
```

### Gherkin Syntax

* Gherkin is a line-oriented language that uses indentation to define structure.
* Line endings terminate statements (called steps) and either spaces or tabs may be used for indentation.
* Finally, most lines in Gherkin start with a special keyword ( Feature,  Scenario.. etc)
* The parser divides the input into features, scenarios and steps

In Gherkin, each line that isn't blank has to start with a Gherkin keyword, followed by any text you like. The main keywords are:

* Feature
* Scenario
* Given, When, Then, And, But (Steps)
* Background
* Scenario Outline
* Examples

There are a few extra keywords as well:

* """ (Doc Strings)
* \| (Data Tables)
* @ (Tags)
* \# (Comments)

### **Features**

A feature is a Use Case that describes a specific function of the application being tested. There are three parts to a Feature:

* The Feature: keyword
* The Feature name (on the same line as the keyword)
* An optional description on the following lines

`Feature: Withdraw Money from ATM`\
&#x20;   `A user with an account at a bank would like to withdraw money from an ATM.`\
&#x20;   `Scenario: Scenario 1`\
&#x20;       `Given preconditions`\
&#x20;       `When actions`\
&#x20;       `Then results`\
\
&#x20;   `Scenario: Scenario 2`\
&#x20;       `...`

\
**Scenario**\
**Scenario** is defined by a sequence of Steps outlining the preconditions and flow of events that will take place. \
Every scenario starts with the **Scenario**: keyword (or localized keyword), followed by an optional scenario title.\
Each Feature is made of a collection of scenarios and every scenario consists of one or more [Steps](http://behat.org/en/latest/user_guide/writing_scenarios.html#user-guide-writing-scenarios-steps).\\

```
Scenario: John wants to withdraw money from his bank account at an ATM
    Given John has a valid Credit or Debit card
    And his account balance is $100
    When he inserts his card
    And withdraws $45
    Then the ATM should return $45
    And his account balance is $55
    
Background:
Given John has an account with ABC Bank
And his account is in working state

Scenario: John wants to withdraw money from his bank account at an ATM
    Given John has a valid Credit or Debit card
    And his account balance is $100
    When he inserts his card
    And withdraws $45
    Then the ATM should return $45
    And his account balance is $55
```

### **Scenario Outline**

```php
Scenario Outline: A user withdraws money from an ATM
    Given <Name> has a valid Credit or Debit card
    And their account balance is <OriginalBalance>
    When they insert their card
    And withdraw <WithdrawalAmount>
    Then the ATM should return <WithdrawalAmount>
    And their account balance is <NewBalance>

    Examples:
      | Name   | OriginalBalance | WithdrawalAmount | NewBalance |
      | John   | 100             | 45               | 55         |
      | Greg   | 100             | 40               | 60         |
      | Ed     | 1000            | 200              | 800        |
```

### Steps

A step typically starts with Given, When or Then. If there are multiple Given or When steps underneath each other, you can use And or But.

* **Given** - The purpose is to put the system in a known state before the user starts interacting with system.
* **When** - Describes the **key action** the user performs.
* **Then** - Describes the outcome resulting from actions taken
* **And** - Logical and
* **But** - Logically the same as And, but used in the negative form

`Scenario: John wants to withdraw money from his bank account at an ATM`\
&#x20;   `Given John has a valid Credit or Debit card`\
&#x20;   `And his account balance is $100`\
&#x20;   `When he inserts his card`\
&#x20;   `And withdraws $45`\
&#x20;   `Then the ATM should return $45`\
&#x20;   `And his account balance is $55`\
\\

As set of features will grow, there’s a good chance that the amount of different steps that you’ll have at your disposal to describe new scenarios will also grow.

Behat provides a command line option --definitions or simply -d to easily browse definitions in order to reuse them or adapt them. Existing Behat Steps can be discovered from the CLI.

`$ #just list definition expressions`\
`$ behat -dl`\
`$ #show definitions with extended info$ behat -di`

```
./vendor/bin/behat -dl -c tests/behat/local.yml -p local
```

### **Tags**

Tags are a great way to organize your features and scenarios. These can be placed before:

* Feature
* Scenario
* Scenario Outline
* Examples

A Scenario or Feature can have as many tags as you like, just separate them with spaces.\
\
@billing\
Feature: Verify billing\
&#x20;  @important @product\
Scenario: Missing product description

### Hooks

Behat hooks are a simple way to execute your custom code just before or just after each of Behat events/action occurs.

Behat allows you to use the following hooks:

* BeforeSuite\
  This hook is run before any feature in the suite runs. For example, you could use this to set up the project database you are testing.\\

* AfterSuite\
  This hook is run after all features in the suite have run. This hooks is useful to dump or print some kind of statistics or tear down your application after testing.\\

* BeforeFeature\
  This hook is run before a feature runs.

```php
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Behat\Behat\Hook\Scope\AfterScenarioScope;

/** @BeforeScenario */
public function before(BeforeScenarioScope $scope){
  $this->getSession()->resizeWindow(1200, 786);  
}

/** @AfterScenario */
public function after(AfterScenarioScope $scope){
}
```

### **Tagged Hooks**&#x20;

Sometimes you may want a certain hook to run only for certain scenarios, features or steps. This can be achieved by associating a @BeforeFeature, @AfterFeature, @BeforeScenario or @AfterScenario hook with one or more tags. You can also use OR(||) and AND (&&) tags:

```php
/**
 * @BeforeScenario @database&&@fixtures
 */
public function cleanDatabaseFixtures()
{
    // clean database fixtures
    // before @database @fixtures
    // scenarios
}
```

**Context**

Context classes are a keystone of testing environment in Behat

The context class is a simple POPO (Plain Old PHP Object) that tells Behat how to test your features.Feature tells how your application behaves, then the context class is all about how to test it.

**Feature Context**

```php
/**
 * @When I do something with :argument xyz
 */
public function iDoSomethingWith($argument){
    // do something with $argument
}

Then I do something with user xyz
```

### Multiple Context&#x20;

```yaml
# behat.yml
default:
    suites:
        default:
            contexts:
                - FeatureContext
                - SecondContext
                - ThirdContext
```

\
**RawDrupalContext**\
A context that provides no step definitions, but all of the necessary functionality for interacting with Drupal, and with the browser via Mink sessions.

**DrupalContext**\
Provides step-definitions for creating users, terms, and nodes.

**Mink**\
Mink is an open source browser controller/emulator for web applications, written in PHP 5.3.\
\
**PhantomJS**\
PhantomJS is a scripted, [headless browser](https://en.wikipedia.org/wiki/Headless_browser) used for automating web page interaction. PhantomJS provides a [JavaScript](https://en.wikipedia.org/wiki/JavaScript) API enabling automated navigation

### &#x20;Other Resources&#x20;

* [**“What’s in a Story?” by Dan North’s**](https://dannorth.net/whats-in-a-story/)
* [**Behat.org**](http://behat.org/en/latest/index.html)
* [**Mink.behat.org**](https://mink.behat.org/en/latest/)
* [**Behat Cheat Sheet**](http://blog.lepine.pro/images/2012-03-behat-cheat-sheet-en.pdf)
* [**Drupal Behat Extension**](http://behat-drupal-extension.readthedocs.io/en/3.1/intro.html)
* [**Automation Testing & BLT**](http://blt.readthedocs.io/en/stable/readme/testing/)
