test driven development with behat and silex

Post on 15-Apr-2017

434 Views

Category:

Software

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Test Driven Development with Behat and Silex

Dionysios Tsoumas Developer at Zoottle

Our requirements

- A lightweight framework - Test driven development

What we went with

- Silex - Behat

Silex

A PHP micro-framework based on Symfony components

Behat

Behat

Test driven development (TDD)

“Test-driven development is a programming technique that requires you to write actual code and automated test code simultaneously.

This ensures that you test your code—and enables you to retest your code quickly and easily, since it's automated.”

— Sane programmer who tests his programs

Behaviour driven development (BDD)

With BDD, you write human-readable stories that describe the behaviour of your application

That sounds cool!

Behaviour driven development (BDD)

Step 1 : Write an automated test Step 2 : Test fail :(

Step 3 : Write code that passes the test Step 4 : Refactor code

Repeat

Behat

Uses gherkin syntax to make Behaviour driven possible Feature: Multiple site support

Background: Given a global administrator named "Greg" And a blog named "Greg's anti-tax rants" And a customer named "Wilson" And a blog named "Expensive Therapy" owned by "Wilson"

Scenario: Wilson posts to his own blog Given I am logged in as Wilson When I try to post to "Expensive Therapy" Then I should see "Your article was published."

Scenario: Greg posts to a client's blog Given I am logged in as Greg When I try to post to "Expensive Therapy" Then I should see "Your article was published."

Step 1: Planning

entities and mapping controllers and routes

but also

• authentication • permissions • response format

Step 2: Functionality to tests

Scenario: Get the campaigns When I request "GET" "/campaign/" with parameters: """ { "api_key": "1" } """ Then the response status code should be "200" Then JSON response key "success" should have the boolean value "true" Then JSON response should contain a key "data" And that key should have a value of type "array" And that array should contain an element with the field value of "id" to be "1" And that array should contain an element with the field value of "name" to be "My existing campaign"

When run

Scenario: Get the campaigns When I request "GET" "/campaign/" with parameters: """ { "api_key": "1" } """ Then the response status code should be "200" Then JSON response key "success" should have the boolean value "true" Then JSON response should contain a key "data" And that key should have a value of type "array" And that array should contain an element with the field value of "id" to be "1" And that array should contain an element with the field value of "name" to be "My existing campaign" Scenario: Get the campaigns When I request "GET" "/campaign/" with parameters: """ { "api_key": "1" } """ Then the response status code should be "200" Then JSON response key "success" should have the boolean value "true" Then JSON response should contain a key "data" And that key should have a value of type "array" And that array should contain an element with the field value of "id" to be "1" And that array should contain an element with the field value of "name" to be "My existing campaign”

1 scenario (1 undefined) 7 steps (7 undefined)

Step 3: Gherkin syntax to unit tests

/** * @When /^I request "([^"]*)" "([^"]*)" with parameters:$/ */ public function iRequestWithParameters($requestMethod, $pageUrl, PyStringNode $postParametersStringNode) { $pageUrl = "http://" . self::$recommendUsApp["url"] . $pageUrl; $parameters = \json_decode($postParametersStringNode->getRaw(), true); if ($requestMethod === "GET") { $response = self::$client->get($pageUrl . "?" . \http_build_query($parameters)); } else if ($requestMethod === "POST") { $response = self::$client->post($pageUrl, array("body" => $parameters)); } else if ($requestMethod === "PUT") { $response = self::$client->put($pageUrl, array("body" => $parameters)); }

$this->response = $response; }

Example 1

Step 3: Gherkin syntax to unit tests

/** * @Then /^the response status code should be "([^"]*)"$/ */ public function responseStatusIs($statusCode) { assertEquals($statusCode, $this->response->getStatusCode()); }

Example 2

Step 4 : Write actual code

..finally

The good

- Good for prototyping - Less things break - Only way for your project manager to write some code

The bad

- We had to rewrite core asserts

The ugly

- We forgot to test every case - Too time consuming - Is it much better than what we currently had?

So how was it?

- Testing with Selenium would be exactly the same - Possibly better suited for bigger teams

top related