BDD API Tests with
Gherkin and Behat
Mark Niebergall
https://i.pinimg.com/originals/81/c6/a2/81c6a285adb6c984f14329516f4eca13.gif
https://pbs.twimg.com/media/EI7j7OIWkAA-hsY.png
Objective
• How to use Behat framework

• How to write tests in Gherkin

• Understand benefits of BDD 

• BDD API development

- Live code BDD tests and APIs
Setup
• PHP 7 installed

• git clone https://github.com/mbniebergall/bdd.git

• composer install

• Run PHP locally

- php -S 0.0.0.0:8088 -t bdd/public/
Agenda
• 1:00-1:30 Behat and Gherkin

• 1:30-2:00 Code Examples

• 2:00-2:25 Writing Tests

• 2:25-2:35 Break

• 2:35-3:00 Writing Tests

• 3:00-3:30 Group Tests

• 3:30-4:00 Test Results, Recap
Behat and Gherkin
Behat and Gherkin
• TDD

• API

• BDD

• Behat

• Gherkin

• TDD and BDD
TDD
• Write a test - Fail

• Write some code - Pass

• Repeat
TDD
• Test Drive Development

- PHPUnit

- Target application logic
API
• Expose functionality to requests
API
• Application Programming Interface

• Inbound requests

• Outbound response

• Frameworks for that

- Slim

- Zend/Laminas

- Laravel

- Others
API
• Middleware!
BDD
• Behavioral Driven Development

• Test code behaviors

• Test API behaviors
https://i.pinimg.com/originals/69/eb/29/69eb293ffb2d1166cbaed9be4dd3d348.gif
BDD
• Write a test - Fail

• Write some code - Pass

• Repeat
Behat
• BDD testing framework

• Tests written in Gherkin

• Translate to associated PHP code
Behat
• composer development-enable

composer require --dev behat/behat

composer require --dev fzaninotto/faker

composer require --dev guzzlehttp/guzzle



[optional]

composer require illuminate/support

composer require zfcampus/zf-api-problem 



vendor/bin/behat --init

vendor/bin/behat features/some_api.feature

vendor/bin/behat --tags=@test features/some/other_code.feature

vendor/bin/behat -s QA features/great_tests.feature
Behat
• /features/ with some_test.feature files

- Written in Gherkin

• /features/bootstrap/ with FeatureContext.php

- PHP that Gherkin maps to
Gherkin
• Human readable

• Describes use cases
Gherkin
• Feature: Use case description

- Scenario: What is expected behavior

‣ Given …

And …

When …

Then …

And …
Gherkin
• Feature: Use case description

- Scenario: What is expected behavior

‣ Given …

And …

When …

Then …

And …



# optionally more tests

Given …

…
Gherkin
• Translates to functions written in a programming language

- Given Something is in a state

When I request “GET /api/some/path/123”

Then I should get a “200” response

And The field “someData” should be “some value”
Gherkin
• Given Something is in a state “Pending”

• /**

* @Given Something is in a state :state

*/

• /**

* @Given /^Something is in a state “([^”]*)”$/

*/

• public function somethingIsInAState(string $state)

{

$this->state = $state;

}
Gherkin
Feature:
As a welcoming person
I want to say hello to someone by name
So that they feel welcomed
@test
Scenario: Simple Test
Given I request "GET /api/helloworld/SunshinePHP”
Then I should get a "200" response
/**
* @Then I should get a :httpStatusCode response
*/
public function iShouldGetAResponse(string $httpStatusCode)
{
$code = $this->response->getStatusCode();
Assert::assertEquals(
$httpStatusCode,
$code,
"Unexpected response code: $codenn" . $this->getResponse()
);
}
Gherkin
@failure
Scenario: I should get an error with too short of a name
Given I request "GET /api/helloworld/H"
Then I should get a 422 response
And The "title" field should be "Unprocessable Entity"
Gherkin
Scenario: I should say Hello to anyone's name
Given I store a fake "firstName" in the variable %firstName%
When I request "GET /api/helloworld/%firstName%"
Then I should get a 200 response
And The "greeting" field should be "Hello %firstName%”
/**
* @Given /^I store a fake "(.*)" in the variable %(.*)%$/
*/
public function iStoreAFakeValueInTheVariable($fakeName, $variable)
{
$this->storedValues[$variable] = [
'search' => $variable,
'replace' => $this->faker->$fakeName,
];
}
TDD and BDD
TDD and BDD
• Co-exist

• Both working together

• Testing different things
TDD and BDD
• Unit tests are much faster

• Unit tests are more granular

• Behavioral tests are focused on APIs

• Behavioral tests run the code without mocks
TDD and BDD
• Behat uses assertion tools (PHPUnit)
Time to Code
Time to Code
• Review a HelloWorld API

• Choose a new API

• Write Gherkin to describe API

• Run tests - fail

• Write PHP API code

• Run tests - pass
Time to Code
• Adding Machine

• Password strength

• Alphabetize

• Randomizer

• Time

• Triangle Solver

• Farenheit to Celcius

• Race pace calculator
Break
https://i.redd.it/uomspd8crlc41.jpg
Time to Code
• Review Previous API

• Choose a new API

• Write Gherkin to describe API

• Run tests - fail

• Write PHP API code

• Run tests - pass
Time to Code
• Adding Machine

• Password strength

• Alphabetize

• Randomizer

• Time

• Triangle Solver

• Farenheit to Celcius

• Race pace calculator
Group Coding Activity
• Create an API

- Use bdd repo

- New API

- Gherkin tests

- PHP for API

- Push changes up, create a PR
Group Coding Activity
• Show and Tell
Review
• Concepts

• Benefits

• Cons

• Continuous Integration

• Authentication

• Environments

• Test data
Review
• Discussion

• Anything PHP related
Review
• Questions?

• https://joind.in/talk/dd8d3
Mark Niebergall
• PHP since 2005

• Masters degree in MIS

• Senior Software Engineer

• Drug screening project

• Utah PHP Co-Organizer

• CSSLP, SSCP Certified and SME

• Father, long distance running, fishing, skiing

BDD API Tests with Gherkin and Behat

  • 1.
    BDD API Testswith Gherkin and Behat Mark Niebergall
  • 2.
  • 3.
  • 4.
    Objective • How touse Behat framework • How to write tests in Gherkin • Understand benefits of BDD • BDD API development - Live code BDD tests and APIs
  • 5.
    Setup • PHP 7installed • git clone https://github.com/mbniebergall/bdd.git • composer install • Run PHP locally - php -S 0.0.0.0:8088 -t bdd/public/
  • 6.
    Agenda • 1:00-1:30 Behatand Gherkin • 1:30-2:00 Code Examples • 2:00-2:25 Writing Tests • 2:25-2:35 Break • 2:35-3:00 Writing Tests • 3:00-3:30 Group Tests • 3:30-4:00 Test Results, Recap
  • 7.
  • 8.
    Behat and Gherkin •TDD • API • BDD • Behat • Gherkin • TDD and BDD
  • 9.
    TDD • Write atest - Fail • Write some code - Pass • Repeat
  • 10.
    TDD • Test DriveDevelopment - PHPUnit - Target application logic
  • 11.
  • 12.
    API • Application ProgrammingInterface • Inbound requests • Outbound response • Frameworks for that - Slim - Zend/Laminas - Laravel - Others
  • 13.
  • 14.
    BDD • Behavioral DrivenDevelopment • Test code behaviors • Test API behaviors
  • 15.
  • 16.
    BDD • Write atest - Fail • Write some code - Pass • Repeat
  • 17.
    Behat • BDD testingframework • Tests written in Gherkin • Translate to associated PHP code
  • 18.
    Behat • composer development-enable
 composerrequire --dev behat/behat
 composer require --dev fzaninotto/faker
 composer require --dev guzzlehttp/guzzle
 
 [optional]
 composer require illuminate/support
 composer require zfcampus/zf-api-problem 
 
 vendor/bin/behat --init
 vendor/bin/behat features/some_api.feature
 vendor/bin/behat --tags=@test features/some/other_code.feature
 vendor/bin/behat -s QA features/great_tests.feature
  • 19.
    Behat • /features/ withsome_test.feature files - Written in Gherkin • /features/bootstrap/ with FeatureContext.php - PHP that Gherkin maps to
  • 20.
    Gherkin • Human readable •Describes use cases
  • 21.
    Gherkin • Feature: Usecase description - Scenario: What is expected behavior ‣ Given …
 And …
 When …
 Then …
 And …
  • 22.
    Gherkin • Feature: Usecase description - Scenario: What is expected behavior ‣ Given …
 And …
 When …
 Then …
 And …
 
 # optionally more tests
 Given …
 …
  • 23.
    Gherkin • Translates tofunctions written in a programming language - Given Something is in a state
 When I request “GET /api/some/path/123”
 Then I should get a “200” response
 And The field “someData” should be “some value”
  • 24.
    Gherkin • Given Somethingis in a state “Pending” • /**
 * @Given Something is in a state :state
 */
 • /**
 * @Given /^Something is in a state “([^”]*)”$/
 */
 • public function somethingIsInAState(string $state)
 {
 $this->state = $state;
 }
  • 25.
    Gherkin Feature: As a welcomingperson I want to say hello to someone by name So that they feel welcomed @test Scenario: Simple Test Given I request "GET /api/helloworld/SunshinePHP” Then I should get a "200" response /** * @Then I should get a :httpStatusCode response */ public function iShouldGetAResponse(string $httpStatusCode) { $code = $this->response->getStatusCode(); Assert::assertEquals( $httpStatusCode, $code, "Unexpected response code: $codenn" . $this->getResponse() ); }
  • 26.
    Gherkin @failure Scenario: I shouldget an error with too short of a name Given I request "GET /api/helloworld/H" Then I should get a 422 response And The "title" field should be "Unprocessable Entity"
  • 27.
    Gherkin Scenario: I shouldsay Hello to anyone's name Given I store a fake "firstName" in the variable %firstName% When I request "GET /api/helloworld/%firstName%" Then I should get a 200 response And The "greeting" field should be "Hello %firstName%” /** * @Given /^I store a fake "(.*)" in the variable %(.*)%$/ */ public function iStoreAFakeValueInTheVariable($fakeName, $variable) { $this->storedValues[$variable] = [ 'search' => $variable, 'replace' => $this->faker->$fakeName, ]; }
  • 28.
  • 29.
    TDD and BDD •Co-exist • Both working together • Testing different things
  • 30.
    TDD and BDD •Unit tests are much faster • Unit tests are more granular • Behavioral tests are focused on APIs • Behavioral tests run the code without mocks
  • 31.
    TDD and BDD •Behat uses assertion tools (PHPUnit)
  • 32.
  • 33.
    Time to Code •Review a HelloWorld API • Choose a new API • Write Gherkin to describe API • Run tests - fail • Write PHP API code • Run tests - pass
  • 34.
    Time to Code •Adding Machine • Password strength • Alphabetize • Randomizer • Time • Triangle Solver • Farenheit to Celcius • Race pace calculator
  • 35.
  • 36.
  • 37.
    Time to Code •Review Previous API • Choose a new API • Write Gherkin to describe API • Run tests - fail • Write PHP API code • Run tests - pass
  • 38.
    Time to Code •Adding Machine • Password strength • Alphabetize • Randomizer • Time • Triangle Solver • Farenheit to Celcius • Race pace calculator
  • 39.
    Group Coding Activity •Create an API - Use bdd repo - New API - Gherkin tests - PHP for API - Push changes up, create a PR
  • 40.
  • 41.
    Review • Concepts • Benefits •Cons • Continuous Integration • Authentication • Environments • Test data
  • 42.
  • 43.
  • 44.
    Mark Niebergall • PHPsince 2005 • Masters degree in MIS • Senior Software Engineer • Drug screening project • Utah PHP Co-Organizer • CSSLP, SSCP Certified and SME • Father, long distance running, fishing, skiing