behat 3 - Using constructor breaks output - behat

I followed the tutorial on http://docs.behat.org/en/latest/quick_intro_pt1.html.
But when I have implemented the feature and running behat it is said in the tutorial that I should get an error: "Fatal error: Class 'Shelf' not found."
I did not get that error. Only the output of the user story:
$ vendor/bin/behat
Feature: Product basket
In order to buy products
As a customer
I need to be able to put interesting products into a basket
Rules:
- VAT is 20%
- Delivery for basket under £10 is £3
- Delivery for basket over £10 is £2
class FeatureContext implements SnippetAcceptingContext
{
private $shelf;
private $basket;
public function __construct()
{
$this->shelf = new Shelf();
$this->basket = new Basket($this->shelf);
}
/**
* #Given there is a :product, which costs £:price
*/
public function thereIsAWhichCostsPs($product, $price)
{
$this->shelf->setProductPrice($product, floatval($price));
}
It looks like, when I am using a constructor this happening and the output of behat is just the user story but not the tests.
Even if I put an exit() in the function the exit() is not happening.
I have tried this with different projects in PHPStorm. It is always the same.
I am wondering how I could get the expectedt error: "Fatal error: Class 'Shelf' not found."
I am using behat 3.0.14: I have used composer to install it.

Related

Codeception's see() method with Yii2 does not display the entire contents of the page

I'm testing a PHP(7.2.1) system that uses the Yii2 framework, and for that, by default I'm using codeception.
When writing functional tests, several methods are not working as expected. Among them is the see() method that should fetch text passed as a parameter on the specified page. In my case the see() method searches only in the side menu of the application, not in the page as a whole.
I would like help to try to solve this error, I already researched the documentation of the framework but could not find anything related to my problem.
Here is the code for the functional tests I wrote and the error displayed.
Test class:
<?php
use app\models\Usuario;
class FirstTryLoginCest
{
public function _before(\FunctionalTester $I)
{
$I->amOnRoute('site/login');
}
public function submitFormSuccessfully(\FunctionalTester $I)
{
$I->submitForm('#login-form', [
'#usuario-username' => 'Fulano',
'#usuario-password' => '12345678'
]);
$I->see('Mural');
}
public function internalLoginByInstance(\FunctionalTester $I)
{
$admin = \app\models\Usuario::findOne(33);
$I->amLoggedInAs($admin);
$I->amOnPage('gestor/mural');
$I->see('Fulano');
}
}
Error displayed:
Codeception PHP Testing Framework v2.4.1
Powered by PHPUnit 7.1.5 by Sebastian Bergmann and contributors.
Functional Tests (2) --------------------------------------------------
✖ FirstTryLoginCest: Submit form successfully (0.14s)
✖ FirstTryLoginCest: Internal login by instance (0.07s)
-----------------------------------------------------------------------
Unit Tests (0) --------------------------------------------------------
-----------------------------------------------------------------------
Time: 464 ms, Memory: 16.00MB
There were 2 failures:
---------
1) FirstTryLoginCest: Submit form successfully
Test tests/functional/FirstTryLoginCest.php:submitFormSuccessfully
Step See "Mural"
Fail Failed asserting that on page /index-test.php?r=site%2Flogin
--> Username cannot be blank. Password cannot be blank. Lembrar no
próximo acesso Entrar Esqueci minha senha Copyright &COPY; 2018 Nome da
empresa
--> contains "Mural".
Scenario Steps:
3. $I->see("Mural") at tests/functional/FirstTryLoginCest.php:19
2. $I->submitForm("#login-form",{"#usuario-
username":"Fulano","#usuario-password":"12345678"}) at
tests/functional/FirstTryLoginCest.php:16
1. $I->amOnRoute("site/login") at
tests/functional/FirstTryLoginCest.php:10
---------
2) FirstTryLoginCest: Internal login by instance
Test tests/functional/FirstTryLoginCest.php:internalLoginByInstance
Step See "Fulano"
Fail Failed asserting that on page /gestor/mural
--> Toggle navigation Fulano Fulano Fulaninho Administrador
Perfil Sair Fulano Gii Debug Same tools Gii Debug Level One Level Two
Level Two Level Three Level Three Nome da empresa &COPY; 2018 Nome da
empresa Software Versão 9.0 β string(1) "0"
--> contains "Fulano".
Scenario Steps:
4. $I->see("Fulano") at tests/functional/FirstTryLoginCest.php:29
3. $I->amOnPage("gestor/mural") at
tests/functional/FirstTryLoginCest.php:28
Thanks in advance!

How to run multiple feature files using the cucumber runner class?

Using the below line of code, all scenarios mentioned in login.feature can be executed.
#CucumberOptions(features= "src/main/resources/publish/login.feature", format = {"pretty"} )
If I have to execute multiple feature files, how do I define? Assuming if I define as below, features mentioned in publish folder would be executed.
#CucumberOptions(features= "src/main/resources/publish", format = {"pretty"} )
If I have to run multiple features and scenarios inside it, how do I define? Do i have to create multile cucumberRunner classes or i can define in one class file.
You can do it by defining tags value in cucumber option(considering that you have already grouped those scenarios in feature files)
Eg:
features="src/test/resources/FeatureFiles",tags="#feature1scenariogroup1,#feature2cenariogroup2"
Defining Tags Inside Feature File:
Feature: My Feature File
#smoke
Scenario: Login
Given I open "FireFox" browser
When I navigate to Sectionone "Home" page
And i do something
Then I Validate Something
#regression
Scenario: Compose Email
Given I open "FireFox" browser
When I Do An Action
#OnlyOneTime
Scenario:Send Email
....
Try this, the below code works for multiple feature files (tags attribute only works when you want to run particular scenario), I tried the below for multiple feature files, it worked:
#CucumberOptions(features = {"src\\test\\resources\\cucumberfeaturefolder\\cucumber1.feature",
"src\\test\\resources\\cucumberfeaturefolder\\cucumber2.feature"},
glue= "StepDef")
You can either use selective feature file or selective scenarios in the feature using tags. Please try with this solution.
Lets consider the you have n number of feature files and you need to run only selective feature from that. Then name each feature file with #tag name.
eg.: Under this folder, if you are having n number of features - "src/main/resources/publish"
1st Feature file name:
Login.feature
//Inside the file start with feature tag name
#Login
Feature: To Login to Email
//Then feature name followed with scenario tag name
#User
//Scenario1:
Scenario Outline: Navigate and logon to gmail application
Given User launches gmail application
When User updates emailID <emailID>
And User updates pwd <pwd>
Then User clicks on Login Button
Examples:
| emailID | pwd |
| a#gmail.com| 123 |
2nd Feature File name:
CreateEmail.feature
#Createmail
Feature: Create email
Scenario: Blah blah blah...
//Write all Given when And Then
3rd Feature File name:
SendEmail.feature
#Sendemail
Feature: Send email
Scenario: Blah blah blah...
//Write all Given when And Then
So From the above Test files. Lets consider you want to test 1st and 3rd feature alone, Then you can use code as below:
eg.: # This is to run specific feature files, which is 1 and 3. Likewise you can use the tags for scenario as well if you have n number scenario in same feature file.
#CucumberOptions(features= "src/main/resources/publish", tags="#Login, #Sendemail", format = {"pretty"} )
Modified my code like to run all enabled features, scenarios. features is the point to note here for the runner class to consider the features
#RunWith(Cucumber.class)
#CucumberOptions(
features = {"classpath:features"},
plugin = {"html:target/site/cucumber-pretty","json:target/cucumber.json"},
tags = {"#currentTest"},
glue={"helpers","stepDefinitions"},
// dryRun = true,
monochrome = true
)
public class RunCukesTest{
}
You can simply write tags = {"#fileName1, #fileName2"}
We can add multiple files using #File1, #File2,..
#RunWith(Cucumber.class)
#CucumberOptions(
features = {"src/test/java/Features"},
tags= {"#FirstTimeLaunch, #SignUpPage"},
glue= {"testCode"},
plugin = { "pretty", "html:target/htmlreports" }
)
Here all *.feature files inside your Features folder (Package) will be executed in the Alphabetic order of the file name, when you execute as a Junit test ( runner class )
Following code working for me:
(1) BeerCans.feature
Feature: Beer Cans
Scenario: Counting Beer Cans
Given I have <opening balance> beer cans
And I have drunk processed beer cans
When I go to my fridge
Then I should have <in stock> beer cans
(2) multiplication.feature
Feature: Multiplication
I multiply two numbers
Scenario: multiple a and b
Given I have variable a
And I have variable b
When I multiply a and b
Then I display the Result
(3) MyStepdefs class
package org.example.njain51.steps; /**
* #author : Nitin Jain
* #mailto : official.nitinjain#gmail.com
* #created : 5/22/2022, Sunday
**/
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
/**
What this program snippet doing?
**/
public class MyStepdefs {
#Given("I have <opening balance> beer cans")
public void iHaveOpeningBalanceBeerCans() {
System.out.println("I have Opening Balance");
}
#And("I have drunk processed beer cans")
public void iHaveDrunkProcessedBeerCans() {
}
#When("I go to my fridge")
public void iGoToMyFridge() {
System.out.println("I go to my Fridge");
}
#Then("I should have <in stock> beer cans")
public void iShouldHaveInStockBeetCans() {
System.out.println("I should have in stock beer cans");
}
}
(4) MultiplicationStepDef class
package org.example.njain51.steps; /**
* #author : Nitin Jain
* #mailto : official.nitinjain#gmail.com
* #created : 5/22/2022, Sunday
**/
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
/**
What this program snippet doing?
**/
public class MultiplicationStepDef {
#Given("I have variable a")
public void iHaveVariableA() {
System.out.println("I have variable a");
}
#And("I have variable b")
public void iHaveVariableB() {
System.out.println("I have variable b");
}
#When("I multiply a and b")
public void iMultiplyAAndB() {
System.out.println("I Multiply a and b");
}
#Then("I display the Result")
public void iDispayTheResult() {
System.out.println("I Display the result");
}
}
(5) RunCucumberTest Class for multiple feature implementation
package org.example.njain51;/**
* #author : Nitin Jain
* #mailto : official.nitinjain#gmail.com
* #created : 5/22/2022, Sunday
**/
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(
features = {"src/test/resources/features/BeerCans.feature",
"src/test/resources/features/multiplication.feature"},
glue = {"org.example.njain51.steps"})
public class RunCucumberTest {
}
(6) Output when I run RunCucumberTest
C:\Users\offic\.jdks\corretto-1.8.0_292\bin\java.exe -ea -DnodeNamesHandler=org.jetbrains.plugins.cucumber.java.run.CucumberTestTreeNodeManager -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\lib\idea_rt.jar=49946:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\plugins\junit\lib\junit5-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\plugins\junit\lib\junit-rt.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\charsets.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\access-bridge-64.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\cldrdata.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\dnsns.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\jaccess.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\jfxrt.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\localedata.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\nashorn.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\sunec.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\sunjce_provider.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\sunmscapi.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\sunpkcs11.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\zipfs.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\jce.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\jfr.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\jfxswt.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\jsse.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\management-agent.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\resources.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\rt.jar;D:\mylearning\SAMPLE_PROJECTS\Testing\cucumber-demo\target\test-classes;C:\Users\offic\.m2\repository\io\cucumber\cucumber-java\6.1.1\cucumber-java-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-core\6.1.1\cucumber-core-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-gherkin\6.1.1\cucumber-gherkin-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-gherkin-messages\6.1.1\cucumber-gherkin-messages-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\messages\12.1.1\messages-12.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\tag-expressions\3.0.0\tag-expressions-3.0.0.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-expressions\10.2.0\cucumber-expressions-10.2.0.jar;C:\Users\offic\.m2\repository\io\cucumber\datatable\3.3.1\datatable-3.3.1.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-plugin\6.1.1\cucumber-plugin-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\docstring\6.1.1\docstring-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\html-formatter\6.0.3\html-formatter-6.0.3.jar;C:\Users\offic\.m2\repository\org\apiguardian\apiguardian-api\1.1.0\apiguardian-api-1.1.0.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-junit\6.1.1\cucumber-junit-6.1.1.jar;C:\Users\offic\.m2\repository\junit\junit\4.13\junit-4.13.jar;C:\Users\offic\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\plugins\cucumber-java\lib\cucumber-jvmFormatter.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 org.example.njain51.RunCucumberTest
I have Opening Balance
I go to my Fridge
I should have in stock beer cans
I have variable a
I have variable b
I Multiply a and b
I Display the result
Process finished with exit code 0

Using SpecFlow, Selenium and FluentAutomation causing problems

I am currently using Specflow with Selenium and FluentAutomation, and am running into significant problems with maintaining state between steps in specflow.
See my example code below:
[Binding]
public class RegistrationSteps : FluentTest
{
[Given(#"I create an account")]
public void GivenICreateAnAccount()
{
new HomePage(this)
.Go()
.StartRegistration()
.EnterDetailsAndClickSubmit(); // takes me to deposit page
}
[When(#"Deposit '(.*)' dollars in my account")]
public void GivenDepositMoneyInMyAccount(int amount)
{
new DepositPage(this)
.EnterDetailsAndClickSubmit(amount);
}
}
My problem is:
In the first step the page is loaded using Go() and everything happens fine
In the second step my tests continue, here I expect I am on a different page, based in the Submit in the previous
Because I am no on a different PageObject it gets confused, I don't use Go because the previous step shouldve brought me here, and at this stage it wont find the expected elements
So my question is, how can I use one browser session and several PageObjects across multiple Specflow tests?
According to the FluentAutomation doc, you should do something like this:
[Binding]
public class RegistrationSteps : FluentTest
{
private PageObject _currentPage;
[Given(#"I create an account")]
public void GivenICreateAnAccount()
{
_currentPage = new HomePage(this)
.Go()
.StartRegistration()
.EnterDetailsAndClickSubmit(); // takes me to deposit page
}
[When(#"Deposit '(.*)' dollars in my account")]
public void GivenDepositMoneyInMyAccount(int amount)
{
_currentPage = _currentPage
.EnterDetailsAndClickSubmit(amount);
}
}
Provided that you return the page object that is switched to in the EnterDetailsAndClickSubmit method of your concrete page object like:
Public PageObject EnterDetailsAndClickSubmit() {
// [.. enter details here and click submit ..]
return this.Switch();
}

How to create unit test for the function "beforeControllerAction" extended from yii framework

I need some idea, to create unit test for the action 'beforeControllerAction', which is extended from yii framework.
beforeControllerAction is parent method from any 'mycontroller' app controller, coming from framework core. You don't need to test specific core framework code (is already tested). You need to test your own code.
One way to test your controller is to extend/inherit your own 'mycontroller' controller first and build a test for it. Taken from this excellent article:
Create your unit test class under the protected/tests/unit
folder and name it the same as your class name you want to test,
adding a Test word after it.
In my case, I will create a file named ApiControllerTest.php that
contains all tests for ApiController.php class.
<?php
// You can use Yii import or PHP require_once to refer your original file
Yii::import('application.controllers.ApiController');
class ApiControllerTest extends ApiController
{
}
Open your ApiControllerTest.php unit test class in step #1
above and make it something similar like this (based on your
requirement and structure):
class ApiControllerTest extends CTestCase
{
public function setUp()
{
$this->api = new ApiController(rand());
}
public function tearDown()
{
unset($this->api);
}
}
Let’s try to test one single method in my ApiController.php, that is
formatResponseHeader. This is what it is doing.
public function formatResponseHeader($code)
{
if (!array_key_exists($code, $this->response_code))
{
$code = '400';
}
return 'HTTP/1.1 ' . $code . ' ' . $this->response_code[$code];
}
Now, to test this method, I’ll open ApiControllerTest.php and add this
code below after setUp() and before tearDown() methods:
public function testFormatResponseHeader()
{
$this->assertEquals('HTTP/1.1 400 Bad Request',$this->api->formatResponseHeader('400'));
$this->assertEquals('HTTP/1.1 200 OK',$this->api->formatResponseHeader('200'));
$this->assertEquals('HTTP/1.1 400 Bad Request',$this->api->formatResponseHeader('500'));
$this->assertNotEquals('HTTP/1.1 304 Not Modified',$this->api->formatResponseHeader('204'));
}
Save the change in ApiControllerTest.php and then try to run this in
protected/tests directory:
phpunit .

How to access methods from a class based wordpress plugin?

I have a plugin which registers a post type, taxonomy and handles some business logic.
I went ahead and made my perfectly working plugin OO based and now it only works some of the time.
Its set-up like the following:
class Fruit {
public function __construct() {
add_action('init', array(&$this, 'init'));
}
public function init() {
$this->the_apple();
}
public function the_apple() {
return print $apple = 'my apple';
}
}
$fruit = new Fruit();
Then in taxonomy.php, withing the loop the following works:
$fruit->the_apple();
But once I use get_template_part with loop.php, this no longer works
$fruit->the_apple();
I get the following notice:
Notice: Undefined variable the_apple();
My fix was to use:
global $fruit;
and now it works all the time, just fyi about globals they get a bad rep. and there's namespacing issues, along with dumping everything into globals vs. using a registry.
In production i would never use the name $fruit, instead i would call it,
global $skylar_fruit;