Class 'Behat\Behat\Context\BehatContext' not found in PHP with Behat - php

I am trying to learn Behat using the tutorial on the website.
The first step goes OK, no errors appear.
But when I am changing the ls_project/features/bootstrap/FeatureContext.php, as shown in the tutorial second step, I am getting the following error: 'Behat\Behat\Context\BehatContext' not found.
The tutorial code, to which the change is applied:
# features/bootstrap/FeatureContext.php
<?php
use Behat\Behat\Context\BehatContext,
Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode,
Behat\Gherkin\Node\TableNode;
class FeatureContext extends BehatContext
{
/**
* #Given /^I am in a directory "([^"]*)"$/
*/
public function iAmInADirectory($dir)
{
if (!file_exists($dir)) {
mkdir($dir);
}
chdir($dir);
}
}
The full error log:
11:51:33 / ME : /var/www/test-driven/behat/ls_project
$ behat
# features/bootstrap/FeatureContext.php
PHP Fatal error: Class 'Behat\Behat\Context\BehatContext' not found in /var/www/test-driven/behat/ls_project/features/bootstrap/FeatureContext.php on line 10
PHP Stack trace:
PHP 1. {main}() /opt/Behat/bin/behat:0
PHP 2. Symfony\Component\Console\Application->run() /opt/Behat/bin/behat:31
PHP 3. Behat\Testwork\Cli\Application->doRun() /opt/Behat/vendor/symfony/console/Symfony/Component/Console/Application.php:121
PHP 4. Symfony\Component\Console\Application->doRun() /opt/Behat/src/Behat/Testwork/Cli/Application.php:90
PHP 5. Symfony\Component\Console\Application->doRunCommand() /opt/Behat/vendor/symfony/console/Symfony/Component/Console/Application.php:191
PHP 6. Symfony\Component\Console\Command\Command->run() /opt/Behat/vendor/symfony/console/Symfony/Component/Console/Application.php:892
PHP 7. Behat\Testwork\Cli\Command->execute() /opt/Behat/vendor/symfony/console/Symfony/Component/Console/Command/Command.php:241
PHP 8. Behat\Testwork\Tester\Cli\ExerciseController->execute() /opt/Behat/src/Behat/Testwork/Cli/Command.php:63
PHP 9. Behat\Testwork\Tester\Cli\ExerciseController->testSpecifications() /opt/Behat/src/Behat/Testwork/Tester/Cli/ExerciseController.php:106
PHP 10. Behat\Testwork\EventDispatcher\Tester\EventDispatchingExercise->test() /opt/Behat/src/Behat/Testwork/Tester/Cli/ExerciseController.php:137
PHP 11. Behat\Testwork\Tester\Runtime\RuntimeExercise->test() /opt/Behat/src/Behat/Testwork/EventDispatcher/Tester/EventDispatchingExercise.php:65
PHP 12. Behat\Testwork\Environment\EnvironmentManager->buildEnvironment() /opt/Behat/src/Behat/Testwork/Tester/Runtime/RuntimeExercise.php:67
PHP 13. Behat\Behat\Context\Environment\Handler\ContextEnvironmentHandler->buildEnvironment() /opt/Behat/src/Behat/Testwork/Environment/EnvironmentManager.php:69
PHP 14. Behat\Behat\Context\Environment\UninitializedContextEnvironment->registerContextClass() /opt/Behat/src/Behat/Behat/Context/Environment/Handler/ContextEnvironmentHandler.php:75
Could anyone please help me resolving this issue?

It appears you've installed Behat v3, but you're following Behat 2 docs.
Behat 3
Behat 3 doesn't have the Behat\Behat\Context\BehatContext class. It's got a Behat\Behat\Context\Context interface:
use Behat\Behat\Context\Context;
class FeatureContext implements Context
{
// ...
}
In composer.json:
{
"require-dev": {
"behat/behat": "~3.1"
},
"config": {
"bin-dir": "bin/"
}
}
Behat 2
Behat 2 uses the Behat\Behat\Context\BehatContext base class:
use Behat\Behat\Context\BehatContext;
class FeatureContext extends BehatContext
{
// ...
}
In composer.json:
{
"require-dev": {
"behat/behat": "~2.5"
},
"config": {
"bin-dir": "bin/"
}
}

In behat 3 there is different structure so you need to use new path to behat context which is in Behat/Behat/Context/Context
<?php
use Behat\Behat\Context\Context;
use Behat\MinkExtension\Context\RawMinkContext;
use Behat\Behat\Context\CustomSnippetAcceptingContext;
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
class FeatureContext extends RawMinkContext implements Context {
}
So use this for example :-)

Related

Autoloading class files for PHPUnit

So, I am just playing around with PHPUnit, I don't really need it but I want to learn how it works so I am trying it out on a random class in a plugin of mine.
The issue I have rn is that whenever I run phpunit I says the Plot class in my test was not found. In my composer.json file I have
{
"require": {
"phpunit/phpunit": "^8.5"
},
"autoload":{
"psr-4" : { "\\mohagames\\PlotArea\\utils\\" : "src/mohagames/PlotArea/utils/"}
}
}
And my Plot.php file is in the C:\Users\moham\Documents\GitHub\PlotArea\src\mohagames\PlotArea\utils\ directory and has the mohagames\PlotArea\utils namespace
But for some reason it still says
C:\Users\moham\Documents\GitHub\PlotArea>C:\Users\moham\Documents\Github\PlotArea\vendor\bin\phpunit --debug
PHPUnit 8.5.0 by Sebastian Bergmann and contributors.
Runtime: PHP 7.3.4
Configuration: C:\Users\moham\Documents\GitHub\PlotArea\phpunit.xml
Test 'SampleTest::testPlot' started
Test 'SampleTest::testPlot' ended
Time: 95 ms, Memory: 4.00 MB
There was 1 error:
1) SampleTest::testPlot
Error: Class 'Plot' not found
C:\Users\moham\Documents\GitHub\PlotArea\tests\unit\SampleTest.php:8
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
And the SampleTest test class:
<?php
use PHPUnit\Framework\TestCase;
class SampleTest extends TestCase{
public function testPlot(){
$plot = new Plot();
}
}
I've tried all sort of solutions on the internet but none of them worked
Like Alister pointed out importing the class first works otherwise, PHP doesn't know what class the code is referring to.
<?php
use PHPUnit\Framework\TestCase;
use mohagames\PlotArea\utils\Plot;
class SampleTest extends TestCase{
public function testPlot(){
$plot = new Plot();
}
}

How to set proper namespace for external class (FPDF)

So I'm really lost at the moment, trying to find a way to use FPDF library that I got with composer. It's confused in my head so I hope I will be clear enough.
I have this composer file :
{
"require": {
"phpmailer/phpmailer": "^6.0",
"stripe/stripe-php": "^6.16",
"setasign/fpdf": "1.8.1"
},
"autoload": {
"psr-4": {
"PsyQuimper\\":"src/calendrier/php/"
}
}
}
And an php file to require once all my classes from composer :
require_once $_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php';
I want to create bills with FPDF library. Here's the bill.php file start :
<?php
use \setasign\fpdf\FPDF;
class Bill extends FPDF {
private $billString;
private $billDate;
function __construct($date) {
$this->billDate = $date;
parent::__construct();
}
Yet when I create a new Bill('2015-05-05') I have an error message :
Class 'setasign\fpdf\FPDF' not found
I don't understand what I am doing wrong. Anyone willing to enlight me here ?
EDIT :
I replaced use \setasign\fpdf\FPDF;
with use FPDF
simple as that. Thanks
setasign/fpdf does not use any namespaces: https://github.com/Setasign/FPDF/blob/1.8.1/fpdf.php.
You should pretend class name with \ to indicate that class from global namespace should be used:
class Bill extends \FPDF
or import this class:
use FPDF;
However in your case your Bill class is not namespaced, so you can just remove use \setasign\fpdf\FPDF; and everything will use global namespace by default.
It is not strict convention to use than same namespace as package name - you need to look into documentation/code/composer.json to find actual namespace for dependencies.

Codeception can't find class when running single test

I'm writing the API test suite for a project I'm currently working on.
I can successfully run the suite using
codecept run api
and all the tests are passing successfully, but whenever I try running a single test using
codecept run api Tests\Users\Get
the following error is thrown:
PHP Fatal error: Class 'Tests\ApiCest' not found in /Users/Username/Programming/PHP/Project/tests/api/Tests/Users/GetCest.php on line 12
This is the folder structure I'm using:
The ApiCest.php is only used to quickly bootstrap the other tests. Here is its content:
namespace Tests;
/*
* This class is extended by the API tests.
*/
use ApiTester;
class ApiCest
{
public function _before(ApiTester $I)
{
$I->prepareRequest();
}
public function _after(ApiTester $I)
{
// All API responses must be in a JSON format.
$I->seeResponseIsJson();
}
}
And this is how it's used in the GetCest.php:
namespace Tests\Users;
use ApiTester;
use Codeception\Util\HttpCode;
use Tests\ApiCest;
/*
* Tests for the GET /users API endpoint.
*/
class GetCest extends ApiCest
{
// Tests methods are here but omitted
}
It happens because Tests\Users\GetCest class extends Tests\ApiCest class, but autoloading is not set-up for test classes.
Add this block to your composer.json file:
"autoload":{
"psr-4":{
"Tests\\": "tests/api/Tests"
}
}
If you already have autoload psr-4 block, add just "Tests\\": "tests/api/Tests" line to it.

Behat 3 - Behat\Behat\Context\Step\Given not found

I'm testing Behat/Mink for the first time with a simple example.
When I launch behat I have this error :
PHP Fatal error: Class 'Behat\Behat\Context\Step\Given' not found in /var/www/behat-test/features/bootstrap/FeatureContext.php on line 31
features/bootstrap/FeatureContext.php :
<?php
require_once './vendor/autoload.php';
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\MinkExtension\Context\MinkContext;
use Behat\Behat\Context\Step;
class FeatureContext extends MinkContext implements Context, SnippetAcceptingContext
{
// ......
/**
* #Given I am logged in as :username
*/
public function iAmLoggedInAs($username)
{
return array(
new Step\Given('I go to "login.php"'), // line 31
new Step\When('I fill in "My name" with '.$username),
new Step\When('I press "Login"')
);
}
}
In Behat2, Given/When/Then classes were used for step chaining. Since this technique brought more problems (with maintenance) then benefits, they're no longer supported in Behat3 (which you apparently use). It's also not recommended to follow this practice.
See https://github.com/Behat/Behat/issues/546.

Class not found issue (Composer, PHPUnit)

Getting the following error form PHPUnit:
Fatal error: Class 'FoobarTest\Money\Money'
not found in /www/foobar/tests/FoobarTest/Money/MoneyTest.php on line 11
My structure is like:
/src/Foobar/Money/Money.php (class Money, namespace Foobar\Money)
/tests/FoobarTest/Money/Money.php (class Money, namespace FoobarTest\Money)
Autoloading done through composer:
"autoload": {
"psr-4": {
"Foobar\\": "src/"
},
"psr-0": {
"FoobarTest\\": "tests/"
}
},
Tried with PSR0, PSR2, PSR4, ...
MoneyTest class:
<?php
namespace FoobarTest\Money;
class MoneyTest extends \PHPUnit_Framework_TestCase
{
// ...
Money class:
<?php
namespace Foobar\Money;
class Money
{
// ...
Why is it trying to load FoobarTest\Money\Money instead of Foobar\Money\Money ?
To help php autoloader (and composer) you must import the target class using
use Foobar\Money\Money;
in your test file.
Also you probably want to give your test file a MoneyTest.php name to match the corresponding class name.

Categories