Functional testing and continuous integration with GitLab - php

I usually use GitLab to host my repositories and to use their CI/CD.
I made a Symfony project (PHP) with some code. I know how to configure my .gitlab-ci.yml to execute my unit tests through PHPUnit.
But I don't really understand how to execute my functional test. For example this code is just testing that the route /login is reachable and not return a 500.
class SecurityControllerTest extends WebTestCase
{
public function testLogin()
{
$client = static::createClient();
$client->request('GET', '/login');
$this->assertEquals(200, $client->getResponse()->getStatusCode());
}
}
So I assume that apache/nginx is needed to interpret PHP. So do I have to make a real docker-compose with a complete LAMP stack or is there a better way?

Functional tests are executed directly in phpunit. You only need to install browser-kit and dom-crawler symfony components.
If you use an ORM, you have to declare a database image as a service and initialize your database in your CI script.

Related

Integration testing in Symfony

I'm writing a reusable bundle and want to carry out an integration testing of this bundle with the hosting app. The problem is that Symfony doesn't call neither the DependencyInjection\Extension::load nor DependencyInjection\Configuration::getConfigTreeBuilder method of my bundle, therefore the bundle's service configuration is not loaded and the services are not constructed properly. How can I get Symfony to load everything in tests, as if it was a real request?
Here is my test:
namespace Tests\AclAgentBundle;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class IntegrationTest extends KernelTestCase
{
public function testAgentExistence()
{
$container = static::bootKernel()->getContainer();
$service = $container->get('test.Foo\Bar\Baz');
//...assertions...
}
test.Foo\Bar\Baz is an alias of a service, declared in the hosting app's config like
services:
test.Foo\Bar\Baz: '#Foo\Bar\Baz'
used to fetch the service via the container's get method in tests.
I figured out where the problem was. An older cached version of the container was used in the tests, therefore the changes in the configuration of the bundle were not reflected. The command php bin/console cache:clear --env=test helped to rebuild the cache. The methods I mentioned in the original question are not supposed to be called when booting the kernel (at least when the cache already exists).

Laravel 5.3 Build unit testing using php unit testing

I have a application developed by laravel 5.3 . Before deploying script i would like test unit test my whole application build using php unit .. Is any package or addons available to test my application build.Else how could i use the unit testing in Laravel 5.3 ..
I'm new to this .. Please any one help
Laravel comes with a TestCase class which you should extend and write your own tests from:
class FooTest extends TestCase {
public function testSomethingIsTrue()
{
$this->assertTrue(true);
}
}
From the Laravel Docs:
You may then define test methods as you normally would using PHPUnit. To run your tests, simply execute the phpunit command from your terminal

How to switch interfaces in Laravel whilst developing

I am building a Laravel 5.2 App that will connect to a database that I don't have available to me whilst developing (it is a legacy database that I cannot install locally).
What is the cleanest way in Laravel to build my application so that I can develop using one interface, and then switch over to another when I push my project to the live environment?
In the past, I've had 2 classes, both of which have the same functions, and then in a configuration file, I would say which class it uses. Just wandering if there is a better way using Laravel? Or if there is a way of doing this already baked in?
One way I can think of achieving this is to switch the instance of the dependency injection when you're on local and production environment.
class ControllerExample
{
public function index( SomeInterface $data )
{
//...
}
}
So in this example the controller index method needs SomeInterface which would be injected automatically. For local development you can resolve this interface to your stub class and for production you can switch to the real class. You can do this by registering the binding of the interface in the app / Providers / AppServiceProvider.php in the register() method:
if ($this->app->environment() == 'local') {
$this->app->when('App\Your\ControllerExample')
->needs('App\SomeInterface')
->give('App\YourStubbedClass');
} else {
$this->app->when('App\Your\ControllerExample')
->needs('App\SomeInterface')
->give('App\YourRealClassWorkingWithTheRealDatabase');
}
What this basically does is when your env is local the dependency in your controller will be resolved with the stub class, otherwise on other envs it will be the real class.

Symfony console application: dependency injection [duplicate]

This question already has an answer here:
How to use DependencyInjection from symfony in stand alone application with commands?
(1 answer)
Closed last year.
A Symfony novice here. After reading some of the Symfony documentation and some answers here at SO, I am now almost completely confused.
I am trying to use the console application component and create a small db-aware console application.
Many people state that in order to use Symfony's DI features it would be enough to inherit my command class not from Symfony\Component\Console\Command\Command but from ContainerAwareCommand.
However when I try this I get a Method Not Found error on an application::getKernel() call.
I have a feeling that DI features are in fact not available in a console application based on the console component. Is there another kind of Symfony console application, for example, based on the full-blown framework?
I very much like the simple framework provided by the console component Symfony\Component\Console\Application. But the question is then - what to do for dependency injection and DBAL? All examples that I find seem to refer to the full Symfony framework and get me just all the more stuck.
Just a quick update on my progress if anybody stumbles upon the same problems.
I incorporated into my project the PHP-DI dependency injection framework, which seems to be working fairly well with no configuration (so far) - it figures out quite a lot by reflection, actually.
The same way, Doctrine\DBAL is included as a standalone library (I opted against the O/RM part of it, as it is really a tiny project and I'm on a much firmer ground with SQL than anything else) and the connection is simply returned by a connection provider which is injected wherever needed by the DI.
One thing I couldn't figure out is how to have the command classes instantiated by the DI library without my help, so I actually had to inject the container itself into my overridden application class and override the getDefaultCommands() where I then pull the instances out of the container manually. Not ideal but will have to do for now.
If your command extends ContainerAwareCommand
...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
...
class MyCommand extends ContainerAwareCommand
{
The DI container is available with the getContainer() method. (like in a standard controller), ex:
$this->validator = $this->getContainer()->get('validator');
I don't know if your question is still relevant, but I have an answer as I stumbled across the same problem here.
You just have to create the kernel yourself and give it to the \Symfony\Bundle\FrameworkBundle\Console\Application that extends the basic \Symfony\Component\Console\Application.
<?php
// CronRun.php
require __DIR__.'/../../../../vendor/autoload.php';
require_once __DIR__.'/../../../../app/AppKernel.php';
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
$application->add(new \KingdomHall\TaskBundle\Command\CronCommand());
$input = new \Symfony\Component\Console\Input\StringInput('k:c:r');
$application->run($input);
You could use a solution I just pushed it to packagist.org. Includes full working symfony/dependency-injection. You're welcome to give it a shot. use composer to create your own project composer create-project coral-media/crune project_dir or just clone the repository.
https://packagist.org/packages/coral-media/crune
You only need to install DBAL dependencies (I don't suggest ORM if you don't really need it). Configure connection parameters in .env and just define a service to handle connection. That service can be injected in your Commands using public setMyService($myService) method with #required annotation. Also you could create a Connection class and bind is as parameter in your command constructor.The crune boilerplate also supports autowire and autoconfiguring features.

Dependency injection in a symfony console command? Not full Symfony application

I've seen this How can i inject dependencies to Symfony Console commands? but that answer doesn't really give enough information and is already explained here http://symfony.com/doc/current/cookbook/console/console_command.html
The problem is a containerAwareCommand doesn't work with the setup here http://symfony.com/doc/current/components/console/introduction.html
In order to use containerAwareCommand from what I can tell, I need my application to use
Symfony\Bundle\FrameworkBundle\Console\Application
instead of
Symfony\Component\Console\Application
But using the frameworkBundle Application class requires an instance of KernelInterface and won't allow me to pass in a name and version to my application.
Here is what I have that won't work with containerAwareCommands
#!/usr/bin/env php
<?php
require __DIR__.'/../src/vendor/autoload.php';
$app = new Symfony\Component\Console\Application('spud', '0.0.1');
$app->add(new Isimmons\Spudster\Console\Commands\SayHelloCommand);
$app->run();
The command it's self runs but I get an error when trying to use getContainer
Call to undefined method Symfony\Component\Console\Application::getKernel()
On a related topic which will probably come up next, The documentation for registering a class in the container shows using a app/config/config.php file. But I don't have an app directory since this is not a full symfony application. My base directory in which all of the app except for the file above is located, is src/lib. If I can figure out the first part above, will symfony be able to find the config file at src/lib/config/config.php?
You can use Consolefull application.
Consolefull is a simple library to work with Symfony Console Component and Symfony Dependency Injection Component

Categories