23/12/2015 - BEHAT
Varsayalım ki uygulamanız in_memory security providers seçeneği üzerine kurulu ve de malum, sadece Basic Auth ile authentication işlemi gerçekleştirebilir. API'ları test etmek için aslında Chrome Postman eklentisini kullanabilirsiniz ama biz behat kullanacağız.
studentROLE_STUDENT: ROLE_USERGET /api/student.lecturerROLE_LECTURER: ROLE_STUDENTGET /api/student, POST /api/student ve GET /api/lecturer.adminROLE_ADMIN: [ROLE_LECTURER, ROLE_ALLOWED_TO_SWITCH]GET /api/student, POST /api/student, GET /api/lecturer, POST /api/lecturer, GET /api/admin ve POST /api/admin.Guzzle 6.1.1 versiyon 4.2.3 versiyona göre çok daha yavaştır, o nedenle size 4.2.3 versiyonu kullanmanızı tavsiye ederim.
{
"require-dev": {
"behat/behat": "3.0.15",
"behat/symfony2-extension": "2.1.0",
"behat/mink": "1.7.0",
"behat/mink-extension": "2.1.0",
"behat/mink-browserkit-driver": "1.3.0",
"guzzlehttp/guzzle": "6.1.1"
},
}
default:
extensions:
Behat\Symfony2Extension: ~
Behat\MinkExtension:
base_url: http://webservice.local/app_test.php/
sessions:
symfony2:
symfony2: ~
suites:
api:
type: symfony_bundle
bundle: ApplicationApiBundle
mink_session: symfony2
contexts:
- Application\ApiBundle\Features\Context\FeatureContext:
baseUrl: http://webservice.local/app_test.php/
Chrome Postman kullanarak aşağıdaki şifreleri yaratabilirsiniz.
namespace Application\ApiBundle\Features\Context;
use Behat\Gherkin\Node\PyStringNode;
use Behat\MinkExtension\Context\MinkContext;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
class FeatureContext extends MinkContext
{
private $baseUrl;
private $client;
private $headers;
private $errorCode;
private $authorisation = [
'student' => 'Basic c3R1ZGVudDpzdHVkZW50',
'lecturer' => 'Basic bGVjdHVyZXI6bGVjdHVyZXI=',
'admin' => 'Basic YWRtaW46YWRtaW4=',
];
/** @var Response $response */
private $response;
public function __construct($baseUrl)
{
$this->baseUrl = $baseUrl;
$this->client = new Client();
}
/**
* @param string $user
*
* @Then /^I am authorised as "([^"]*)"$/
*/
public function iAmAuthorisedAs($user)
{
$this->headers['Authorization'] = $this->authorisation[$user];
}
/**
* @param string $key
* @param string $value
*
* @Then /^I set "([^"]*)" header as "([^"]*)"$/
*/
public function iSetHeaderAs($key, $value)
{
$this->headers[$key] = $value;
}
/**
* @param string $method
* @param string $uri
* @param null|PyStringNode $value
*
* @When /^I send a "([^"]*)" request to "([^"]*)"$/
* @When /^I send a "([^"]*)" request to "([^"]*)" containing:$/
*/
public function iSendRequestTo($method, $uri, PyStringNode $value = null)
{
try {
$this->response = $this->client->request(
$method,
$this->baseUrl.$uri,
[
'headers' => $this->headers,
'body' => $value
]
);
} catch (Exception $e) {
$this->errorCode = $e->getCode();
}
}
/**
* @param int $code
*
* @When /^the response status code should be "([^"]*)"$/
*
* @throws Exception
*/
public function theResponseStatusCodeShouldBe($code)
{
if ($this->errorCode && $this->errorCode != $code) {
throw new Exception(
sprintf('Expected status code %s but got %s', $code, $this->errorCode)
);
}
}
/**
* @param PyStringNode $value
*
* @When /^the response should contain:$/
*
* @throws Exception
*/
public function theResponseShouldContain(PyStringNode $value)
{
if ($value->getRaw() != json_decode($this->response->getBody())) {
throw new Exception(
sprintf('Response contains:'.PHP_EOL.'%s', json_decode($this->response->getBody()))
);
}
}
/**
* @param string $header
* @param string $value
*
* @When /^the response header "([^"]*)" should be "([^"]*)"$/
*
* @throws Exception
*/
public function theResponseHeaderShouldBe($header, $value)
{
$result = $this->response->getHeader($header);
if (!$this->response || !is_array($result) || !in_array($value, $result)) {
throw new Exception('Response header could not be found.');
}
}
}
Eğer Guzzle 4.2.3'i kullanmayı tercih ederseniz iSendRequestTo methodunu aşağıdaki gibi değiştirebilirsiniz.
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Stream\Stream;
$client = new Client();
$request = $client->createRequest('POST', 'http://www.whatever.com/api/student',);
$request->addHeader('Authorization', 'Basic 23erfgh678iED6tyuh);
$request->addHeader('Content-Type', 'application/json');
$request->setBody(Stream::factory($postData));
$result = $client->send($request);
Testler aşağıdaki komutlar ile çalıştırılabilir.
# Run all tests
bin/behat --suite=api
# Run only StudentControls.feature test scenarios
bin/behat --suite=api @ApplicationApiBundle/StudentControls.feature
# Run single StudentControls.feature test scenario which is on line 12
bin/behat --suite=api @ApplicationApiBundle/StudentControls.feature:12
# src/Application/ApiBundle/Features/StudentControls.feature
Feature: Testing Student account
In order to test Student account
As a Student user
I should be able to send requests
Scenario: I get error when sending invalid content headers
Given I am authorised as "student"
And I set "Content-Type" header as "text/plain"
When I send a "GET" request to "api/student"
Then the response status code should be "400"
Scenario: I cannot see lecturer
Given I am authorised as "student"
And I set "Content-Type" header as "application/json"
When I send a "GET" request to "api/lecturer"
Then the response status code should be "403"
Scenario: I can successfully see students
Given I am authorised as "student"
And I set "Content-Type" header as "application/json"
When I send a "GET" request to "api/student"
Then the response status code should be "200"
And the response header "Content-Type" should be "application/json"
And the response should contain:
"""
Hello ROLE_STUDENT user
"""
# src/Application/ApiBundle/Features/LecturerControls.feature
Feature: Testing Lecturer account
In order to test Lecturer account
As an Lecturer user
I should be able to send requests to carry out lecturer works
Scenario: I get error when sending invalid content headers
Given I am authorised as "lecturer"
And I set "Content-Type" header as "text/plain"
When I send a "GET" request to "api/student"
Then the response status code should be "400"
Scenario: I cannot see admins
Given I am authorised as "student"
And I set "Content-Type" header as "application/json"
When I send a "GET" request to "api/admin"
Then the response status code should be "403"
Scenario: I can successfully see lecturers
Given I am authorised as "lecturer"
And I set "Content-Type" header as "application/json"
When I send a "GET" request to "api/lecturer"
Then the response status code should be "200"
And the response header "Content-Type" should be "application/json"
And the response should contain:
"""
Hello ROLE_LECTURER user
"""
Scenario: I can successfully create a new student
Given I am authorised as "lecturer"
And I set "Content-Type" header as "application/json"
When I send a "POST" request to "api/student" containing:
"""
{
"name": "Hello",
"surname": "World"
}
"""
Then the response status code should be "200"
And the response header "Content-Type" should be "application/json"
And the response should contain:
"""
{
"name": "Hello",
"surname": "World"
}
"""
# src/Application/ApiBundle/Features/AdminControls.feature
Feature: Testing Admin account
In order to test Admin account
As an Admin user
I should be able to send requests to carry out admin works
Scenario: I get error when sending invalid content headers
Given I am authorised as "admin"
And I set "Content-Type" header as "text/plain"
When I send a "GET" request to "api/admin"
Then the response status code should be "400"
Scenario: I can successfully send a valid request
Given I am authorised as "lecturer"
And I set "Content-Type" header as "application/json"
When I send a "GET" request to "api/lecturer"
Then the response status code should be "200"
And the response header "Content-Type" should be "application/json"
And the response should contain:
"""
Hello ROLE_LECTURER user
"""
Scenario: I can successfully create a new student
Given I am authorised as "lecturer"
And I set "Content-Type" header as "application/json"
When I send a "POST" request to "api/student" containing:
"""
{
"name": "Hello",
"surname": "World"
}
"""
Then the response status code should be "200"
And the response header "Content-Type" should be "application/json"
And the response should contain:
"""
{
"name": "Hello",
"surname": "World"
}
"""
Scenario: I can successfully create a new lecturer
Given I am authorised as "admin"
And I set "Content-Type" header as "application/json"
When I send a "POST" request to "api/lecturer" containing:
"""
{
"name": "Hello",
"surname": "World"
}
"""
Then the response status code should be "200"
And the response header "Content-Type" should be "application/json"
And the response should contain:
"""
{
"name": "Hello",
"surname": "World"
}
"""
Scenario: I can successfully create a new admin
Given I am authorised as "admin"
And I set "Content-Type" header as "application/json"
When I send a "POST" request to "api/admin" containing:
"""
{
"name": "Hello",
"surname": "World"
}
"""
Then the response status code should be "200"
And the response header "Content-Type" should be "application/json"
And the response should contain:
"""
{
"name": "Hello",
"surname": "World"
}
"""