Codeception. Actor classes loaded twice - php

I try to configure unit-tests suite in Codeception. When I run suite Codeception fail with error Fatal error: Cannot re-declare class rest\tests\UnitTester. With debugger I located places where it loads class first and second time.
First time Codeception load Actor in Codeception\Test\Loader\Gherkin during adding steps to loader.
Second time it initialize Actor instance for class with tests. In second place this class must be already included, but again loader is triggered. Here error appear.
Class is loaded with Codeception loader. At first I think that it was caused by namespace, but UnitTester is only one class in namespace. My .yml files a listed below. I would be very grateful for help.
codeception.yml:
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
settings:
bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M
modules:
config:
Yii2:
configFile: 'config/test-local.php'
unit.suite.yml:
class_name: UnitTester
modules:
enabled:
- Yii2
- Asserts

I found a reason of this problem. My codeception.yml for this tests missing namespace param when classes in test folder was under namespace. This caused my problem.

Related

Codeception's Autoload class doesn't autoload

I'm trying to autoload a bunch of helpers into a test suite. The helpers are located in a folder outside of the test suite in the hopes that I can reuse them across multiple projects if needed.
This is pretty much what I have:
- helpers
- TestHelper.php
- tests
- _data
- _output
- _support
- _generated
- Helper
- Integration.php
- IntegrationTester.php
- integration
- bootstrap.php
- integration.suite.yml
- vendor
- codeception.yml
This is the bootstrap file
// bootstrap.php
<?php
\Codeception\Util\Autoload::addNamespace( "awesome\helpers", __DIR__ . "../helpers" );
This is the global config file:
// codeception.yml
bootstrap: bootstrap.php
namespace: main
paths:
tests: tests
output: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
actor_suffix: Tester
extensions:
enabled:
- Codeception\Extension\RunFailed
This is the integration suite's config file:
// integration.suite.yml
actor: IntegrationTester
modules:
enabled:
- \awesome\helpers\TestHelper
- \main\Helper\Integration
This is the TestHelper:
<?php
namespace awesome\helpers;
class TestHelper extends \Codeception\Module{
public function sayHello() {
return "Hello";
}
}
As soon as I do codecept run, I get the following error:
Module \awesome\helpers\TestHelper could not be found and loaded
I'm not posting any tests because it's irrelevant, the error is raised before any test is performed as it's a config issue.
From what I understand, the global config file should run the bootstrap file before the tests are run, and the Autoload class in the bootstrap file should load the helpers in the awesome\helpers namespace, but that's clearly not happening. What am I doing wrong?
I think that you made a classical mistake and missed / before .. so you set the path to tests../helpers.
Change
\Codeception\Util\Autoload::addNamespace( "awesome\helpers", __DIR__ . "../helpers" );
to
\Codeception\Util\Autoload::addNamespace( "awesome\helpers", __DIR__ . "/../helpers" );

Run suites of included files in codeception

I have an application with different modules. For each module, there are separate tests written which are divided in different suites.
For example in tests/Custom/codeception.yml
namespace: Test\Custom
paths:
tests: .
data: _data
support: _support
log: _output
coverage:
enabled: true
remote: false
whitelist: { include: ['../../../../src/*'] }
suites:
Business:
path: Business
...
View:
path: View
....
So every module has its own codeception.yml.
To have one "master config" there is a codeception.yml in the first level of the test folder which is including all the subfolder module yml with
namespace: Test
actor: Tester
include:
- tests/*
...
When running a build caused by a branch update in the repository we usually don't want to run other tests than business because they are slow and fragile.
For this i try to run codecept run Business and expect, that just the Business suites from the included files will be executed.
But this will not work, instead i get the error message
Suite 'Business' could not be found
But when i run one module explicit with Business suite
codecept run -c tests/Custom Business
it works.
My first assumption was, that the files get not proper included to the master yml so i tried the general call
codecept run
and it works! But this unfortunately runs all suites.
So, why the suites cant be seen by the master codeception.yml? How can i run all tests Business suites without pointing explicit to the module path?
Thanks

Codeception RuntimeException Call to undefined method FunctionalTester::amOnPage

I have set up a functional test following the tutorials at:
http://codeception.com/docs/04-FunctionalTests
http://codeception.com/docs/modules/Symfony
http://codeception.com/09-04-2015/using-codeception-for-symfony-projects.html
The main difference is that I've set up Codeception the traditional way because I don't want to mix test code with project code.
This is my functional test (I know it's not actually testing anything):
<?php
class MyFirstCest {
public function _before(FunctionalTester $I) {
}
public function _after(FunctionalTester $I) {
}
// tests
public function tryToTest(FunctionalTester $I) {
$I->amOnPage('/app/login/');
}
}
When I run the functional test I get:
[RuntimeException] Call to undefined method FunctionalTester::amOnPage
When I rebuild Codeception, I get:
Building Actor classes for suites: acceptance, functional, unit
-> AcceptanceTesterActions.php generated successfully. 0 methods added
\AcceptanceTester includes modules: PhpBrowser, \Helper\Acceptance
-> FunctionalTesterActions.php generated successfully. 0 methods added
\FunctionalTester includes modules:
-> UnitTesterActions.php generated successfully. 0 methods added
\UnitTester includes modules: Asserts, \Helper\Unit
The critical part seems to be \FunctionalTester includes modules: which is empty.
My functional.suite.yml file looks like this:
actor: FunctionalTester
modules:
- Symfony:
app_path: 'app'
environment: 'local_test'
class_name: FunctionalTester
modules:
enabled:
- Symfony2:
app_path: 'path/to/app'
var_path: 'path/to/app'
- Doctrine2:
depends: Symfony2
- \Helper\Functional
- PhpBrowser:
url: dev.hmr-app
- \AcmeBundle\Helper\Functional
where the Symfony app lives in path/to/app. I know there's a lot of junk in there, but that's because I've been experimenting, trying to get it to work.
What am I doing wrong?
I think that your problem is that you have
modules:
- Symfony:
app_path: 'app'
environment: 'local_test'
in the config.
That section is completely misplaced and it probably is causing you issues.
Please remove it and rename Symfony2 with Symfony in enabled section.
Also make sure that you are using the latest version of Codeception.

Codeception with Yii1 enabled module

I am using codeception 2.2.5 aand Yii 1.1.4
I have the issue with the Yii1 module. I have it configured for functional and unit tests
Here is the functional.suite.yml
class_name: FunctionalTester
modules:
enabled:
- Yii1:
appPath: 'www/test.php'
url: 'http://localhost/test.php'
part: init
- PhpBrowser:
url: 'http://localhost/index-test.php'
- \Helper\Functional
coverage:
enabled: true
remote: false
Here is the unit.suite.yml
class_name: UnitTester
modules:
enabled:
- Asserts
- Yii1:
appPath: 'www/test.php'
url: 'http://localhost/test.php'
- \Helper\Unit
When I run the tests separately everything works great. e.g.
php codecept.phar run functional --xml --html
php codecept.phar run unit --xml --html
When I run all together
php codecept.phar run --xml --html
It runs the functional without the issue connected with the Yii1 module. And on the unit it brings
[Codeception\Exception\ModuleConfigException]
Yii1 module is not configured!
Couldn't load application config file www/test.php
Please provide application bootstrap file configured for testing
The main goal to run all together is the code coverage.
Here is the answer to my problem:
I created a separate module Yii1Ext(Yii1Ext.php) which extends to Yii1 module:
namespace Helper;
use Codeception\Module\Yii1;
class Yii1Ext extends Yii1
{
public function _initialize()
{
$this->config['appPath'] = FRONTEND.'/'.$this->config['appPath'];
parent::_initialize();
}
}
And in configuration files have the Yii1Ext module enabled instead of Yii1 module
class_name: FunctionalTester
modules:
enabled:
- \Helper\Yii1Ext:
appPath: 'www/test.php'
url: 'http://localhost/test.php'
part: init
- PhpBrowser:
url: 'http://localhost/'
Note: Make sure all defined variables in Yii are defined by the statement
defined('ROOT_DIR') or define('ROOT_DIR', realpath(__DIR__ . '/../'));

Are some Codeception modules incompatible?

I am using Codeception to make acceptance tests for Symfony project. I need to test everything, this means testing pages (html content) as well as the ajax calls they perform (JSON content).
I have enabled the Symfony2 module in my suite settings but I find few methods in it to check JSON strings, so I guess I'm supposed to enable the REST module as well. However, if I do so, other previously existing tests fail.
For instance, this simple test:
public function privateExtranetHome(AcceptanceTester $I)
{
$I->wantTo('test something');
$I->amOnRoute('acme_site_home.es');
$I->assertEquals(
'container',
$I->grabAttributeFrom('#container-slider', 'class')
);
}
This is not a JSON testing test, just an already existing test in my Cest class, that passed when I only had the Symfony2 module enabled, and fails now that I added the REST module. The error message is :
Scenario:
* I am on route "acme_site_home.es"
[Page] http://localhost/es
[User] anon. []
* I grab attribute from "#container-slider","class"
Fatal error: Call to a member function hasAttribute() on null in [...]\Codeception\Module\REST.php on line 993
Maybe the amOnRoute() method is incompatible with the REST module, because when the latter is enabled, I get an empty response. But therefore my question is: is there some documentation, somewhere which states which modules are incompatible and should not be enabled together? Or should I take as a rule of thumb to use a separate suite for each module?
Just in case, my acceptance suite settings are as follows:
class_name: AcceptanceTester
modules:
enabled:
- Asserts
- Db
- Symfony2
- Doctrine2
- \Tests\Helper\Acceptance
And my Codeception settings:
namespace: Tests
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
settings:
bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M
extensions:
enabled: [ Codeception\Extension\RunFailed ]
modules:
config:
Db:
dsn: 'mysql:host=localhost;dbname=acme_test'
user: 'root'
password: 'blahblah'
dump: 'tests/_data/dump.sql'
populate: false
cleanup: false
Doctrine2:
depends: Symfony2
cleanup: false
PhpBrowser:
url: http://acme.com
WebDriver:
browser: firefox
url: http://acme.com
REST:
depends: Symfony2
url: http://acme.com
REST module is compatible with and relies on framework modules to process requests.
However you discovered an unreported incompatibility - grabAttributeFrom method is defined both modules - Symfony2 and REST. I will raise an issue for that.
There is one workaround you could use - grabAttributeFrom is defined in XML part of REST module, so if your REST requests return only JSON, you could enable JSON functionality only.
REST:
depends: Symfony2
part: JSON

Categories