Closed mfratczak closed 5 years ago
@mfratczak fastes just parallelize them: if you set header and/or cookie in the "standard" way (e.g.: for behat in a @BeforeScenario
) all should work as expected. I use fastest with behat and selenium and I don't have any kind of issue.
@DonCallisto can you please share your snippet of the BeforeScenario method and how you implement the different database names?
@mfratczak, @OskarStark we do something like
/**
* @BeforeScenario
*/
public function before(BeforeScenarioScope $scope)
{
[...]
if (getenv('ENV_TEST_CHANNEL_READABLE')) {
$this->getSession()->setCookie('ENV_TEST_CHANNEL_READABLE', getenv('ENV_TEST_CHANNEL_READABLE'));
[...]
}
Nice an are you using mysql or SQLite for test? And how do you replace the dB name then? Using sf 4 so have a DATABASE_URL which will be resolved
@liuggio did you think about a behat context which could be enabled and provide the cookie stuff by @DonCallisto ?
@OskarStark Right now we're using SQLite for tests and MySQL for real env. I know, it kinda sucks because we cannot reproduce the real stack but ATM we never had troubles with this. As our infrastructure is huge we never switched but we should sooner or later.
Talking about our solution, we create "statically" a db that we copy (as sqlite dbs are files) with right db name as fastest requires. This way we can get rid of that copy of db as soon as a new test starts.
In MySQL a suitable solution would be to create n
db in advance and use, for example, ORMPurger
: I have this solution for project where I don't use fastest and it simply works so I can't see why it shouldn't with multiple db as long as process are isolated (as it is in fastest).
BTW @liuggio don't follow this project anymore AFAIK and I really don't think this kind of Context should be something that fastest should care about. TBH all behat things should live into an extension but for the moment that's not a big deal for the project to keep them internal. Moreover that's just a basic configuration, I don't know if it's worth to create "ad hoc" context just for this.
WDYT?
Hey @DonCallisto thank your for your feedback.
I try something like this with Symfony 4.1:
// The check is to ensure we don't use .env in production
if (!isset($_SERVER['APP_ENV'])) {
if (!class_exists(Dotenv::class)) {
throw new \RuntimeException('APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.');
}
(new Dotenv())->load(__DIR__.'/../.env');
}
FastestEnvironment::setFromRequest();
$testDatabaseUrl = str_replace('luna', getenv('ENV_TEST_CHANNEL_READABLE'), getenv('DATABASE_URL'));
putenv("DATABASE_URL=$testDatabaseUrl");
but getenv('ENV_TEST_CHANNEL_READABLE')
is empty.
I execute it like this:
vendor/bin/behat --list-scenarios | ./vendor/liuggio/fastest/fastest "vendor/bin/behat {}
And added this to my FeatureContext:
/**
* @BeforeScenario
*/
public function addFastestChannelInformation()
{
if (getenv('ENV_TEST_CHANNEL_READABLE')) {
$this->minkContext->getSession()->setCookie('ENV_TEST_CHANNEL_READABLE', getenv('ENV_TEST_CHANNEL_READABLE'));
}
}
Regarding the context, I think we could make it quite simple for people to start by registering the context, of read this issue 😄
Creating n
MySQL db's shouldn't be a Problem but I need to select them anyway. Can you elaborate or show some more detail on your implementation? Maybe a gist or sth like this?
Well, I have a quite complex setup as we use doctrine sharding so this is little bit more complicated and right now I can't take a look and get rid in a safe way of all those concept and post something that surely work (as I should take time to get rid of all sharding concepts and then test that's fine).
BTW that's nothing complex here: before every scenario I retrieve the ENV_TEST_CHANEL_READABLE
var, and do a cp
(remember, I'm on sqlite
) of the "base" db (that I set in the script I use to launch the tests) into a new one with ENV_TEST_CHANEL_READABLE
appended in the name.
That's it as fastest will do the rest for me as db selection happens directly in fastest as described here
I suppose that
but I need to select them anyway
is resolved with the link I've provided to you
Ah i overlooked that, but link, thank you!
But now I got this error: [2018-06-21 06:12:35] php.DEBUG: Notice: Undefined index: master {"exception":"[object] (Symfony\Component\Debug\Exception\SilencedErrorContext: {\"severity\":8,\"file\":\"/var/www/vendor/liuggio/fastest/adapters/Doctrine/DBAL/ConnectionFactory.php\",\"line\":30,\"trace\":[{\"file\":\"/var/www/var/cache/test/ContainerF7lD3eR/getDoctrine_Dbal_DefaultConnectionService.php\",\"line\":12,\"function\":\"createConnection\",\"class\":\"Liuggio\\Fastest\\Doctrine\\DBAL\\ConnectionFactory\",\"type\":\"->\"},{\"file\":\"/var/www/var/cache/test/ContainerF7lD3eR/srcTestDebugProjectContainer.php\",\"line\":838,\"args\":[\"/var/www/var/cache/test/ContainerF7lD3eR/getDoctrine_Dbal_DefaultConnectionService.php\"],\"function\":\"require\"}],\"count\":1})"} []
are you sure this works with Sf4 ?
this is the failing code in ConnectionFactory
:
public function createConnection(array $params, Configuration $config = null, EventManager $eventManager = null, array $mappingTypes = [])
{
if (isset($params['dbname'])) {
$dbName = $this->getDbNameFromEnv($params['dbname']);
} else {
$dbName = $this->getDbNameFromEnv($params['master']['dbname']);
}
Not sure that's a symfony problem as those data should came from DBAL, as this connection is used by that layer.
I found an existing issue by @tarlepp : #101
However this project should have nothing to do with symfony (apart for direct deps used in the code), maybe we should write a kind of "normalizer" to be sure to accept those parameters in the same format regardless how they're declared inside config files.
@OskarStark I resolved this with custom bootstrap with phpunit and a small configuration change:
doctrine:
dbal:
url: '%env(DATABASE_URL)%'
# This is needed for 'fastest' see https://github.com/liuggio/fastest/issues/101
dbname: '%env(DATABASE_NAME)'
###> doctrine/doctrine-bundle ###
# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
# Set "serverVersion" to your server version to avoid edge-case exceptions and extra database calls
DATABASE_NAME=symfony
DATABASE_URL=mysql://root@127.0.0.1:3306/${DATABASE_NAME}?charset=utf8mb4&serverVersion=mariadb-10.2.14
###< doctrine/doctrine-bundle ###
@tarlepp thank your for your feedback, I got it almost working 🙏
An exception occurred in driver: SQLSTATE[HY000] [1049] Unknown database 'luna_test_6' (Doctrine\DBAL\Exception\ConnectionException)
the name is routed through the test scope, but the database is not created. How do you to this or should this be done automatically?
the name is routed through the test scope, but the database is not created. How do you to this or should this be done automatically?
Ah I found this in your repo: https://github.com/tarlepp/symfony-flex-backend/blob/master/tests/bootstrap.php
Is this everything I need todo?
@OskarStark that is how I got that working, there might be some parts you don't need though. One important thing is also in public/index.php
to make fastest environment working with those client tests.
I got it working and here are my behat contexts I use.
https://gist.github.com/OskarStark/5a3ce2bab27998a32a458377650abaa2
@tarlepp instead of executing the database commands via doctrine, fastest
supports:
-b, --before=BEFORE Execute a process before consuming the queue, it executes this command once per process, useful for init schema and load fixtures.
I will try to get it working, but not sure if this is executed in the bootsraped environment 🤔 Did you tried that already?
The funny thing is, that my suite takes 5:04 minutes
with fastest and 4:51 minutes
without fastest
84 scenarios (82 passed, 2 undefined)
619 steps (605 passed, 2 undefined, 12 skipped)
4m51.53s (99.44Mb)
How many process did you use for consumption?
- 84 shuffled test classes into the queue.
- Will be consumed by 8 parallel Processes.
I am on a MacBook Pro (15', 2016) using Docker-Compose:
That's weird ...
weird with that speed, in my case I get following;
without fastest Time: 2.54 minutes
and with fastest Time: 59 seconds 559 milliseconds
But in earlier I noticed that fastest will impact e2e
more than just simple pure unit tests.
@DonCallisto I'm getting the error
┌─ @BeforeScenario # FeatureContext::before()
│
│ test_1
│
╳ Exception: unable to set cookie
╳ (Session info: chrome=71.0.3578.80)
╳ (Driver info: chromedriver=2.44.609551 (5d576e9a44fe4c5b6a07e568f1ebc753f1214634),platform=Linux 4.15.0-43-generic x86_64) in vendor/instaclick/php-webdriver/lib/WebDriver/Exception.php:144
╳ Stack trace:
with the code
/**
* @BeforeScenario
*/
public function before()
{
if (getenv('ENV_TEST_CHANNEL_READABLE') && $this->getSession()->isStarted()) {
echo getenv('ENV_TEST_CHANNEL_READABLE');
$this->getSession()->setCookie('ENV_TEST_CHANNEL_READABLE', getenv('ENV_TEST_CHANNEL_READABLE'));
}
}
have no idea why. any suggestions?
also, I have tried to set header with the code
// if (getenv('ENV_TEST_CHANNEL_READABLE') && $this->getSession()->isStarted()) {
// $cookie = new Cookie('ENV_TEST_CHANNEL_READABLE', getenv('ENV_TEST_CHANNEL_READABLE'));
// $this->getSession()->setRequestHeader('Cookie', (string)$cookie);
// }
and it gives me error
┌─ @BeforeScenario # FeatureContext::before()
│
╳ Behat\Mink\Exception\UnsupportedDriverActionException: Request headers manipulation is not supported by Behat\Mink\Driver\Selenium2Driver in vendor/behat/mink/src/Driver/CoreDriver.php:281
Symfony 3.4. latest Behat and Mink.
Or any idea how to attach GET parameter to all requests with Symfony Behat Mink?
I know they have guzzle parameters
configurable...
@seyfer that's not a fastest issue, btw you can search for a solution on the web or open a issue at Selenium repository.
AFAIK, before setting a cookie you should start navigate at least one page of the domain. For example, before that set, we do something like
$this->visitPath('/?XDEBUG_SESSION_START=IDE-DEBUG-KEY');
That is not related to fastest but is useful when you need to set a debug key (and I suppose that consequently we are able to set the cookie).
@OskarStark
The funny thing is, that my suite takes 5:04 minutes with fastest and 4:51 minutes without fastest
Do you run Selenium in Hub mode with several browser instances? If not, it gives no benefit as processes wait for one browser instance to be available.
I'm closing it as it's not a fastest issue and the converstation seems to be over.
Hi,
I have use opensoure sylius ecommerce system, and i want use fastest. But we use selenium or local server to test (using behat). How i can put header or cookie on start to every test? i dont want change every test. I'm trying this more than 4 days, and still have problem :)