I set up a simple test scenario to learn behat, but I'm running into some problems. I'm following THIS tutorial.
Here is my feature show:
Feature: show
This is a behat feature to test the article pages.
##TODO
Scenario: I want to view a detailed article page
Given I am logged in
And I'm on "/articles"
When I press an article Image
Then I should see a title
And I should see an Image
And I should see some text
and here is my FeatureContext.php file
<?php
use Behat\MinkExtension\Context\MinkContext;
/**
* Features context.
*/
class FeatureContext extends MinkContext
{
/**
* Initializes context.
* Every scenario gets its own context object.
*/
public function __construct()
{
}
/**
* #Given /^I am on "([^"]*)"$/
*/
public function iAmOn($arg1)
{
throw new PendingException();
}
/**
* #Given /^I press "([^"]*)"$/
*/
public function iPress($arg1)
{
throw new PendingException();
}
/**
* #When /^I fill in "([^"]*)" with "([^"]*)"$/
*/
public function iFillInWith($arg1, $arg2)
{
throw new PendingException();
}
/**
* #Then /^I should see "([^"]*)" in the "([^"]*)" element$/
*/
public function iShouldSeeInTheElement($arg1, $arg2)
{
throw new PendingException();
}
}
However everytime I try to run the feature I get the same result, which looks like this:
Feature: show
This is a behat feature to test the article pages.
Scenario: I want to view a detailed article page # features\show.feature:5
Given I am logged in
And I'm on "/articles"
When I press an article Image
Then I should see a title
And I should see an Image
And I should see some text
1 scenario (1 undefined)
6 steps (6 undefined)
0m0.32s (4.78Mb)
I'm not sure what's causing this problem. I've been looking for a solution but I can't find it. I hope one of you can help me out!
thanks in advance
Your steps do not match your step definitions.
You can let Behat create stubs of your step definitions by implementing SnippetAcceptingContext in your FeatureContext and running Behat with the --append-snippets argument as described here:
http://behat.org/en/latest/quick_start.html#defining-steps
Related
I am wondering how to register custom method within:
Illuminate/Foundation/Application.php
Like:
/**
* Get the current application name.
*
* #return string
*/
public function getName()
{
return $this['config']->get('app.name');
}
Taken from:
/**
* Get the current application locale.
*
* #return string
*/
public function getLocale()
{
return $this['config']->get('app.locale');
}
Where should I put this, instead of vendor file ofc?
Thanks
You maybe able to extend the Illuminate/Foundation/Application.php
example:
<?php
namespace app\Custom;
class Application extends \Illuminate\Foundation\Application
{
}
for more details, please refer this click here .
Note: Adding your code under vendor files, may lost during the composer update command. So its not advisable to actually add your custom codes there.
I am trying to write some Behat tests for an application and I need to separate the Contexts so I can use some core elements in different other contexts for example the logged in user step.
behat.yml
suites:
common:
type: symfony_bundle
bundle: CommonBundle
mink_session: symfony2
mink_javascript_session: selenium2
autoload:
'CommonContext': %paths.base%/src/xxx/CommonBundle/Features/Context
contexts: [ xxx\CommonBundle\Features\Context\CoreContext ]
user:
type: symfony_bundle
bundle: UserBundle
mink_session: symfony2
mink_javascript_session: selenium2
autoload:
'UserContext': %paths.base%/src/xxx/UserBundle/Features/Context
contexts:
- Behat\MinkExtension\Context\MinkContext
- xxx\CommonBundle\Features\Context\CoreContext
- xxx\UserBundle\Features\Context\UserContext
DefaultContext.php
namespace XXX\CommonBundle\Features\Context;
use ...
/**
* Class DefaultContext
*/
class DefaultContext extends MinkContext implements Context, KernelAwareContext
{
/**
* #param AbstractEntity $oEntity
*
* #return object
*/
protected function getRepository(AbstractEntity $oEntity)
{
return $this->getService($oEntity);
}
/**
* #return mixed
*/
protected function getEntityManager()
{
return $this->getService('doctrine')->getManager();
}
/**
* #param $id
*
* #return object
*/
protected function getService($id)
{
return $this->getContainer()->get($id);
}
CoreContext.php
namespace XXX\CommonBundle\Features\Context;
use ...
/**
* Class SubContext
*/
class CoreContext extends DefaultContext implements Context, SnippetAcceptingContext
{
/**
* #Given I visit the homepage
* #When I visit the homepage
*/
public function iVisitHomepage()
{
$this->visitPath('/');
}
/**
* #And /^I am logged in as "([^"]*)"$/
* #Then /^I am logged in as "([^"]*)"$/
*/
public function iAmLoggedInAs($username)
{
$user = $this->getContainer()->get('fos_user.user_manager')->findUserByUsername($username);
$this->visit('/login');
$this->fillField('_username', $user->getEmailCanonical());
$this->fillField('_password', self::USER_PASSWORD);
$this->pressButton('_submit');
}
UserContext.php
namespace xxx\UserBundle\Features\Context;
use ...
/**
* Defines application features from the specific context.
*/
class UserContext extends CoreContext implements Context, SnippetAcceptingContext
{
/**
* Initializes context.
*
* Every scenario gets its own context instance.
* You can also pass arbitrary arguments to the
* context constructor through behat.yml.
*/
public function __construct()
{
}
}
register_user.feature
Feature: Register user
#javascript
Scenario: Register user
Given I am on homepage
And I go to "/register/"
And I am logged in as "foo#bar.com"
Then I should see "Terms and Conditions"
So when I run the test I get an error saying this:
Given I am on homepage
Step "I visit the homepage" is already defined in xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
And I go to "/register/"
Step "I visit the homepage" is already defined in xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
Do i understood this completely wrong or I am missing some settings here?
Do not extend contexts that provide step definitions. There's no way around this.
Good extensions provide contexts with handy methods but no step definitions. In case of the Mink extension, next to the MinkContext you also have RawMinkContext. First provides step definitions and should not be extended. The other one provides helper methods you might be interested in. The RawMinkContext is the one you should extend. Alternatively you can also use the MinkAwareTrait.
There has been a shift on what Contexts where in Behat2 and what they are now in Behat3. Contexts in Behat3 are more about "situations" in which your tests might occur. For instance:
Logged in
Anonymous visitor
Public API call
Authenticated API call
Disabled javascript browser
Enabled javascript browser
And so on.
So I'm afraid that the problem is in your configuration of the CoreContext being used in two suites. You can try to avoid this by running your suites separately so it does not load both configurations (and it does not autoload twice the same Context) or to change the Context strategy to not use the autoload, but something different like encapsulating common step logics into their own classes that are then being used from different Contexts.
Hope it helps
I'm doing my firsts acceptance tests for a Laravel 5 application using Behat 3 and Mink.
The application runs under a Homestead VM.
The test is straightforward and is located in the features/example.feature file. This is the test:
Feature: Sample
In order to learn Behat
As a programmer
I need a simple url testing
Scenario: Registration
Given I am not logged in
When I go to the registration form
Then I will be automatically logged in
The FeatureContext.php has this class:
<?php
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext;
/**
* Defines application features from the specific context.
*/
class FeatureContext extends MinkContext implements Context, SnippetAcceptingContext
{
/**
* Initializes context.
*
* Every scenario gets its own context instance.
* You can also pass arbitrary arguments to the
* context constructor through behat.yml.
*/
public function __construct()
{
}
/**
* #Given I am not logged in
*/
public function iAmNotLoggedIn()
{
Auth::guest();
}
/**
* #When I go to the registration form
*/
public function iGoToTheRegistrationForm()
{
$this->visit(url('my/url'));
}
/**
* #Then I will be automatically logged in
*/
public function iWillBeAutomaticallyLoggedIn()
{
Auth::check();
}
}
Then, when I run behat from the command line, I expect the test to fail because there is no my/url route (the routes.php file only has a route for /).
However, the test returns green, and this is what I see:
Feature: Sample
In order to learn Behat
As a programmer
I need a simple url testing
Scenario: Registration # features/example.feature:7
Given I am not logged in # FeatureContext::iAmNotLoggedIn()
When I go to the registration form # FeatureContext::iGoToTheRegistrationForm()
Then I will be automatically logged in # FeatureContext::iWillBeAutomaticallyLoggedIn()
1 scenario (1 passed)
3 steps (3 passed)
0m0.45s (22.82Mb)
Of course, I'm using the laracasts/behat-laravel-extension package and this is the content of the beat.yml file:
default:
extensions:
Laracasts\Behat: ~
Behat\MinkExtension:
default_session: laravel
laravel: ~
Thank you very much for any help!
Behat is very simple. It treats a step as failed if an exception is thrown while executing it. It treats a step as successful otherwise.
As far as I can tell from the docs, Auth::check() does not throw an exception if user is not authenticated. It simply returns a boolean value.
Your step should be rather implemented more like the following:
/**
* #Then I will be automatically logged in
*/
public function iWillBeAutomaticallyLoggedIn()
{
if (!Auth::check()) {
throw new \LogicException('User was not logged in');
}
}
Your "I go to the registration form" step succeeds since you don't really verify if the page you visited is the one you expected to load. Again, you should throw an exception if a page you visited is not the right one.
I'm trying to create a #link from one method to another method in a different class. Example:
class Bar extends Foo
{
/**
* This link works: {#link barFunction()}
* This link also works: {#link fooFunction()}
* This link doesn't work: {#link Foo::fooFunction()}
*/
public function fooFunction()
{
}
/**
* Bar function is another function
*/
public function barFunction()
{
}
}
The inline #link within the same class works OK. But the inline link to another class does not generate a link to the documentation. Instead, it generates:
Foo::fooFunction()
Am I doing something wrong or am I simply trying to achieve what is not possible? I looked over Apigen documentation and their forums (both at GitHub and Google Groups) but without any success. Thanks for your help.
I'm looking for a way to make PHPStorm hide some methods from code completion. I've tried to annotate the DocBlocks with #access private but that does not hide them from view.
Is there any way to hide private API, short of writing/generating a stub file with a limited interface and referencing that in my project?
for example:
Lets say the library has this in it:
<?php
interface IDoABunchOfStuff
{
/**
* My library users use this
*/
public function doFoo();
/**
* My Library needs this but requires that my users don't see it.
*
* #access private
* #visibility none
* #package mylib
* #internal
*/
public function doBar();
}
class Foo extends Something implements IDoABunchOfStuff
{
/**
* does foo
*/
public function doFoo()
{
// ...
}
/**
* does bar. for internal use only
*
* #access private
* #visibility none
* #package mylib
* #internal
*/
public function _doBar()
{
// ...
}
}
And my library user is typing:
<?php
myAwesomeFunction(IDoABunchOfStuff $aFoo)
{
if($->$oFoo->[CTRL+SPACE] // invoking code completion...
Is it possible to (and if it is how do I) make it so that my user never sees _doBar?
Neither of the different annotations i've tried seem to have the desired effect.
P.S. I'm using PHPStorm 4.0.3
additional:
In this case I am implementing ArrayAccess and I don't want offsetGet, offsetSet, offsetExists and offsetUnset cluttering up my code completion window but I've had similar problems elsewhere enough to warrant asking a more generalized question.
Nope -- you cannot do such thing in current version of PhpStorm.
There is a ticket on Issue Tracker that suggests using #access tag for this purpose, but currently it is not scheduled to be implemented for any particular version: http://youtrack.jetbrains.com/issue/WI-5788
Feel free to vote/comment/etc and maybe it will be implemented sooner.