I'm trying to get into using codeception for my acceptance testing.
I have the following for one of my tests:
<?php
use Codeception\Util\Stub;
class SomeTest extends \Codeception\TestCase\Test
{
protected $webGuy;
/**
* #test
*/
public function incorrect_login_should_redirect_back()
{
$I = $this->webGuy;
$I->wantTo('fail at logging in');
$I->amOnPage('/'); // <-- This is the line that is failing
$I->fillField('email','info#tntstudio.hr');
$I->fillField('password','pass');
$I->click('Login');
$I->see('email', 'input');
$I->seeCurrentUrlEquals('/login');
}
}
Initially the tests ran OK, however after adding Laravel4 to the acceptance.suite.yml file and running build, the test now fails with the following:
1) SomeTest::incorrect_login_should_redirect_back
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
#1 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1021
#2 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Routing/Router.php:989
#3 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Routing/Router.php:968
#4 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:738
#5 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:708
#6 /Applications/MAMP/htdocs/hired/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
#7 /Applications/MAMP/htdocs/hired/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:325
#8 /Applications/MAMP/htdocs/hired/app/tests/acceptance/WebGuy.php:476
#9 /Applications/MAMP/htdocs/hired/app/tests/acceptance/SomeTest.php:16
I'm running my app in a virtual environment using vagrant, at http://localhost:3030/
I have set this to the url for the PhpBrowser config in acceptance.suite.yml as below:
class_name: WebGuy
modules:
enabled:
- PhpBrowser
- WebHelper
- Laravel4
config:
PhpBrowser:
url: 'http://localhost:3030/'
I'm wondering if anybody else has come across this, or has any ideas on how to get around this, I've been tearing my hair out for hours on this.
Laravel4 module will cause Codeception to use the "testing" environment in Laravel.
Laravel will disable all route filters in "testing" environment - so your filters are not working correctly and its probably calling the wrong route, causing your app to die and your test to fail.
I dont think using the Laravel4 module with "acceptance" tests is correct - it should only be for functional tests? Edit: I just found that the Codeception Laravel4 module docs actually say "This module allows you to run functional tests for Laravel 4" - so I guess it was not actually designed for Acceptance tests?
But with all the changes in Codeception 2.x - you are better off using PhpBrowser module for your acceptance tests, and Laravel4 module for your functional tests.
If you are using Homestead, I do this in my start.php file to detect if Codeception is running, and specifically put it into a 'codeception' environment, otherwise I let it run my environment detection normally
if ((gethostname() === 'homestead') && (isset($_SERVER['REMOTE_ADDR'])) && ($_SERVER['REMOTE_ADDR'] === '127.0.0.1'))
{
$env = $app->detectEnvironment(['codeception' => ['homestead']]);
}
else
{
$env = $app->detectEnvironment(['dev' => ['homestead']]);
}
Then in my 'codeception' environment, I setup a SQLite file database, and run acceptance tests against that (which is faster than mySQL testing).
You don't even have to change your start.php. You can set the environment for codecption in the laravel4 Module config. So in your acceptance.suite.yml it will look like this:
modules:
enabled: [PhpBrowser, WebHelper, Laravel4]
config:
Laravel4:
environment : 'codeception'
filters : true
Now, when you execute php codecept run acceptance in your terminal, the Laravel4 Module will use the configuration files from app/config/codeception.
Was not able to find a solution to this, so for now am going to just go without the Laravel4 module, sadly.
Related
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
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.
So, I followed the Codeception Quick Start instructions faithfully. I run the first example test using the PhpBrowser...
# Codeception Test Suite Configuration
#
# [further comments omitted]
#
actor: AcceptanceTester
modules:
enabled:
- PhpBrowser:
url: 'http://office.localhost/'
browser: 'firefox'
- \Helper\Acceptance
and the test:
<?php
class FirstCest
{
public function frontpageWorks(AcceptanceTester $I)
{
$I->amOnPage('/');
$I->see('We hope you enjoy it');
}
}
and all is well.
Then I change the configuration to this:
actor: AcceptanceTester
modules:
enabled:
- WebDriver:
url: 'http://office.localhost/'
browser: 'firefox'
- \Helper\Acceptance
per the instructions, and I have Selenium installed and up and running, and away we go...
1) FirstCest: Frontpage works
Test tests/acceptance/FirstCest.php:frontpageWorks
[PHPUnit\Framework\Exception] Undefined index: ELEMENT
Scenario Steps:
2. $I->see("InterpretersOffice") at tests/acceptance/FirstCest.php:22
1. $I->amOnPage("/") at tests/acceptance/FirstCest.php:21
#1 /opt/www/court-interpreters-office/vendor/facebook/webdriver/lib/Remote/RemoteWebDriver.php:198
#2 Codeception\Module\WebDriver->see
#3 /opt/www/court-interpreters-office/tests/_support/_generated/AcceptanceTesterActions.php:363
#4 /opt/www/court-interpreters-office/tests/acceptance/FirstCest.php:22
#5 FirstCest->frontpageWorks
Selenium is driving Firefox, the page is loaded, the content that $I want to see() is there, so that ain't the problem. I have poked around in the source a bit, but haven't figured this out. I have tried changing $I->see() to $I->seeInSource() and found that does work, FWIW.
Any thoughts?
The problem is apparently that Facebook's php-webdriver isn't compatible with current Firefox.
These threads discuss the issue in more detail, and php-webdriver issue #469 tracks adding full W3C WebDriver support (which will fix the incompatibility).
A workaround is to add the -enablePassthrough false argument when launching Selenium. For example:
java -Dwebdriver.gecko.driver=./geckodriver -jar selenium-server-standalone-3.8.1.jar -enablePassThrough false
Unfortunately, Selenium removed support for pass through mode in 3.9, so you'll have to use an older version.
Another workaround is to switch to Chrome.
In my case the only solution was:
Install chromedriver in a path that is in $PATH (/usr/bin or /bin)
and using in your test class:
$capabilities = DesiredCapabilities::chrome()
It works with executing Selenium standard way:
java -jar selenium-server-standalone-3.14.0.jar
There are different situations on my Ubuntu ver. 18.x:
The vendor files has been for years, I have to rm the vendor fold and rebuild it with php composer.phar require facebook/webdriver for my PHP library.
The version of selenium-server-standalone-x.jar and chromedriver doesn't match. So download more version and try, finally you will get one pair to work.
I have a number of tests written for a Laravel 5.1 application, and I'm currently using PHPUnit to run the tests. I'm attempting to investigate codeception as we have other applications that aren't built on Laravel, so codeception looks like the easiest way to get a similar interface for testing.
We have a reasonably large team, so I would prefer to use a single consistent command for testing across all projects instead of some using codecept and some using phpunit.
Here's what I've tried as my codeception.yml:
actor: Tester
paths:
tests: tests
log: storage/codeception/_output
data: storage/codeception/_data
support: storage/codeception/_support
envs: storage/codeception/_envs
modules:
enabled:
- Laravel5:
environment_file: .env
But I get this response:
$ codecept run
Codeception PHP Testing Framework v2.1.4
Powered by PHPUnit 4.8.18 by Sebastian Bergmann and contributors.
[RuntimeException]
Suite '' could not be found
So my question is this:
How do I convince codeception to run my existing PHPUnit tests with as little modification as possible?
After a lot of time, I found out that it's possible, but you have to make some modifications to how your tests are laid out. The bonus, though, is that it doesn't stop you from just running PHPUnit itself.
For posterity, here's how to do it:
Move your unit tests and TestCase.php into a folder named unit under the tests folder.
It should look like this:
tests/
tests/unit/
tests/unit/MyUnitTest.php
tests/unit/TestCase.php
Add the unit.suite.yml file in the tests/ folder.
The contents should look something like this:
modules:
enabled:
- Laravel5:
environment_file: .env.testing
Update your composer.json to with the correct folder for the testing classmap
In your autoload-dev section:
"classmap": [
"tests/unit/TestCase.php"
]
Update your TestCase.php to load bootstrap.php from the correct folder.
This should be in the createApplication() method at the top of TestCase.php
public function createApplication()
{
// $app = require __DIR__ . '/../bootstrap/app.php';
$app = require __DIR__ . '/../../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
return $app;
}
Finally, run composer dump-autoload, and codeception should run. As a bonus, phpunit should also still run.
I'm running the latest version of Codeception on a vagrant box and I can't get either the acceptance or functional testing working.
Here's acceptance.suite.yml:
class_name: AcceptanceTester
modules:
enabled:
- PhpBrowser
- AcceptanceHelper
config:
PhpBrowser:
url: 'http://test.dev'
and my acceptance test:
$I = new AcceptanceTester($scenario);
$I->wantTo('check Codeception');
$I->amOnPage('/');
$I->see('hello');
The index page is a simple html output with 'hello world'
The error I'm getting is as follows:
1) Failed to check codeception in testTestCept (/vagrant/test/tests/acceptance/testTestCept.php)
Sorry, I couldn't am on page "http://test.dev/":
GuzzleHttp\Exception\RequestException: cURL error 6: Couldn't resolve host 'test.dev'
Scenario Steps:
1. I am on page "http://test.dev/"
#1 /vagrant/fmx/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlAdapter.php:91
#2 /vagrant/fmx/vendor/guzzlehttp/guzzle/src/Adapter/StreamingProxyAdapter.php:34
#3 /vagrant/fmx/vendor/guzzlehttp/guzzle/src/Client.php:186
#4 /vagrant/fmx/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:332
#5 /vagrant/fmx/tests/acceptance/AcceptanceTester.php:128
#6 /vagrant/fmx/tests/acceptance/testTestCept.php:5
#1 /vagrant/fmx/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlAdapter.php:91
#2 /vagrant/fmx/vendor/guzzlehttp/guzzle/src/Adapter/StreamingProxyAdapter.php:34
#3 /vagrant/fmx/vendor/guzzlehttp/guzzle/src/Client.php:186
#4 /vagrant/fmx/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:332
#5 /vagrant/fmx/tests/acceptance/AcceptanceTester.php:128
#6 /vagrant/fmx/tests/acceptance/testTestCept.php:5
My functional test is just as simple:
$I = new FunctionalTester($scenario);
$I->wantTo('check Codeception');
$I->amOnPage('/');
$I->see('hello');
With this one I get the following error:
There was 1 error:
---------
1) Failed to check codeception in testTestCept (/vagrant/test/tests/functional/testTestCept.php)
#1 /vagrant/test/tests/functional/testTestCept.php:5
#2 /vagrant/test/tests/functional/testTestCept.php:5
Line 5 is specifically: $I->amOnPage('/');
I'm new to vagrant so I'm not sure if I've missed something in the setup or if I've done something else wrong. I'm running codeception through vagrant ssh.
UPDATE:
We've got the Acceptance testing working. Now just focusing on the Functional testing. As requested, below is the complete functional.suite.yml content. As I'm setting up in stages, I've not actually modified this:
# Codeception Test Suite Configuration
# suite for functional (integration) tests.
# emulate web requests and make application process them.
# Include one of framework modules (Symfony2, Yii2, Laravel4) to use it.
class_name: FunctionalTester
modules:
enabled: [Filesystem, FunctionalHelper]
I had the same problem and this helped me:
unable to run codeception in virtual machine -Mink could not be found and loaded
I needed to add an entry in my /etc/hosts file for my site inside of my vm.