testing and fixtures

Setup Testing and Fixtures in Symfony2: The Easy Way

Setting up testing and fixtures in Symfony2 is vital if you plan on starting Test Driven Development or you simply want to start covering your code with properly written tests that can access mock data.

 

1. Install PHPUnit and php 5.6

The first thing you need to do is to install PHPUnit on your machine:

$ wget https://phar.phpunit.de/phpunit.phar
$ chmod +x phpunit.phar
$ sudo mv phpunit.phar /usr/local/bin/phpunit
$ phpunit --version

and then, if needed, also upgrade your PHP version to 5.6:

$ sudo apt-get install language-pack-en-base
$ export LC_CTYPE="en_US.UTF-8"
$ sudo add-apt-repository ppa:ondrej/php5-5.6
$ sudo apt-get update
$ sudo apt-get install php5

and make sure everything's ok by running: phpunit -c app/

Please note that this is not a testing tutorial so if you'd like to learn more about how to actually test your Symfony2 app, then please read their documentation.

 

2. Setup and create a test database

In order to be able to configure testing and fixtures in a Symfony2 app a separate, independent database is needed so that your dev environment is not affected.

In the config_test.yml file you simply need to add:

doctrine:
    dbal:
        host:     127.0.0.1
        dbname:   testdb
        user:     [YOUR_MYSQL_USERNAME]
        password:  [YOUR_MYSQL_PASSWORD]

then simply run php app/console doctrine:database:create --env=test

 

RelatedSend Emails in Symfony2: The Right Way

 

3. Build the BaseTestSetup class

Once our test database is ready we can start building our BaseTestSetup class, one which will serve as parent for all of our tests.

<?php
namespace AppBundle\Tests;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

abstract class BaseTestSetup extends WebTestCase
{
    protected $client;
    protected $container;
    protected $em;

    protected function setUp()
    {
        $this->client = static::createClient();
        $this->container = $this->client->getContainer();
        $this->em = static::$kernel->getContainer()
            ->get('doctrine')
            ->getManager();
    }
}

 

4. Install the LiipFunctionalTestBundle

Even though Symfony does have an out of the box solution to setup and test your app, the LiipFunctionalTestBundle provides base classes for functional tests to assist in setting up testing and fixtures and HTML5 validation.

After you install and configure the bundle, go back to your BaseTestSetup class and make the necessary modifications:

<?php
namespace AppBundle\Tests;
use Doctrine\ORM\Tools\SchemaTool;
use Liip\FunctionalTestBundle\Test\WebTestCase;

abstract class BaseTestSetup extends WebTestCase
{
    protected $client;
    protected $container;
    protected $em;

    protected function setUp()
    {
        $this->client = static::createClient();
        $this->container = $this->client->getContainer();
        $this->em = static::$kernel->getContainer()
            ->get('doctrine')
            ->getManager();
        
        if (!isset($metadatas)) {
            $metadatas = $this->em->getMetadataFactory()->getAllMetadata();
        }
        $schemaTool = new SchemaTool($this->em);
        $schemaTool->dropDatabase();
        if (!empty($metadatas)) {
            $schemaTool->createSchema($metadatas);
        }
        $this->postFixtureSetup();

        $this->loadFixtures(array(
            'AppBundle\DataFixtures\ORM\LoadUserData',
        ));

    }
}

The new code above simply drops and creates the database each them tests run. Then it loads the fixtures that you'll need. The LoadUserData class does not exist yet so we'll go right ahead and add it by following the handy tutorial found on Symfony's website.

 

5. Write the very first test

Now that have your fixtures ready, you can go ahead and write your first test. Create a new file in your AppBundle/Tests folder called UserTest.php, next to BaseTestSetup.php:

<?php
namespace AppBundle\Tests;

use AppBundle\Tests\BaseTestSetup;

class UserTest extends BaseTestSetup 
{   
    public function testSuggestImprovementEmail()
    {   
        // assuming that you named your user 'username' in your Fixtures
        $crawler = $this->client->request('GET', '/show/username');

        $this->assertGreaterThan(
            0,
            $crawler->filter('html:contains("Hello first user!")')->count()
        );
    }

}

 

And that's about it! You now have everything you need to properly test your awesome app.

 


send emails in symfony2

Send Emails in Symfony2: The Right Way

No matter what your app is about, at one you point you will have to send emails in Symfony2. Even though this process might seem straightforward and easy to apply, it can actually get pretty tricky. Here's how you can send emails in Symfony2 by properly splitting your functionality and templates.

 

1. Mailer parameters

First off, you're going to need to add some email data into your parameters.yml file that will tell Swift Mailer which SMTP server to use. At this point, it would be advised to create an account at an email sending service. For this short tutorial, we're going to use SendGrid.

mailer_transport: smtp
mailer_host: smtp.sendgrid.net
mailer_user: your_sendgrid_username
mailer_password: 'your_sendgrid_password'
mailer_port: 587

contact_email: contact@yourapp.com
from_email: hello@yourapp.com
from_name: YourApp

As you can see, we've also added three parameters that will help us to send emails in Symfony2: contact email, from email and from name.

 

2. Send emails in Symfony2 using a MailManager

Having a MailManager is helpful because the code needed to send emails will only reside in a single place. Thus, it will be way easier to maintain. Here's how you should build the MailManager class:

<?php

namespace AppBundle\Lib;

class MailManager
{
    protected $mailer;
    protected $twig;

    public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig)
    {
        $this->mailer = $mailer;
        $this->twig = $twig;
    }

    /**
     * Send email
     *
     * @param   string   $template      email template
     * @param   mixed    $parameters    custom params for template
     * @param   string   $to            to email address or array of email addresses
     * @param   string   $from          from email address
     * @param   string   $fromName      from name
     *
     * @return  boolean                 send status
     */
    public function sendEmail($template, $parameters, $to, $from, $fromName = null)
    {
        $template = $this->twig->loadTemplate('AppBundle:Mail:' . $template . '.html.twig');

        $subject  = $template->renderBlock('subject', $parameters);
        $bodyHtml = $template->renderBlock('body_html', $parameters);
        $bodyText = $template->renderBlock('body_text', $parameters);

        try {
            $message = \Swift_Message::newInstance()
                ->setSubject($subject)
                ->setFrom($from, $fromName)
                ->setTo($to)
                ->setBody($bodyHtml, 'text/html')
                ->addPart($bodyText, 'text/plain')
            ;
            $response = $this->mailer->send($message);

        } catch (\Exception $ex) {
            return $ex->getMessage();
        }

        return $response;
    }
}

In the sendEmail function, you can easily define a $template variable which will hold whatever template you need, depending on the type of email. You'll see the MailManager in action in the 4th and last section of this short tutorial, where you'll use it to send a contact email.

Oh, and don't forget to register the service in services.yml:

mail_manager:
    class:     AppBundle\Lib\MailManager
    arguments: ["@mailer", "@twig"]

 

Related: Symfony2 Facebook and Google Login: The Easy Way

 

3. Define a simple template

In this section you'll be building the three main blocks any email should have (subject, html and text) and store them in a template which you'll extend as needed.

{# src/AppBundle/Mail/template.html.twig #}

{% block subject %}
    default subject
{% endblock %}

{% block body_text %}
    default text    
{% endblock %}

{% block body_html %}
    <p>default body</p>
{% endblock %}

 

4. A sample email sending action

Now that you have everything set, you can go ahead and build your first mail sending action. As an example, here's how a contact action should look like. It will send emails to the email address defined in parameters.yml.

public function contactAction(Request $request)
    {
        $form = $this->createForm(new ContactType());

        $form->handleRequest($request);

        //this is where we define which template to use
        $template = 'contact';

        if($form->isValid()){
            //Get data from the submitted form
            $data = $form->getData();
            $mail_params = array(
                'firstName' => $data["firstName"],
                'lastName'  => $data["lastName"],
                'message'   => $data["message"],
                'phoneNumber' => $data["phoneNumber"],
                'email'     => $data["email"]
            );

            //grab the addresses defined in parameters.yml
            $to = $this->container->getParameter('contact_email');
            $from =  $this->container->getParameter('from_email');
            $fromName = $this->container->getParameter('from_name');

            //use the MailManager service to send emails
            $message = $this->container->get('mail_manager');
            $message->sendEmail($template, $mail_params, $to, $from, $fromName);

            return $this->redirectToRoute('contact');
        }

        return $this->render('AppBundle:StaticPages:contact.html.twig',array(
            'form' => $form->createView()
        ));
    }

Since you'll be using the contact email body, you will need to build it by extending the template defined at step #3:

{% extends "AppBundle:Mail:template.html.twig" %}

{% block subject %}
    YourApp Contact Message
{% endblock %}

{% block body_text %}
    {% autoescape false %}
        Name: {{ firstName }} {{ lastName }}
        Message: {{ message }}
        Phone Number: {{ phoneNumber }}
        Email address: {{ email }}
    {% endautoescape %}
{% endblock %}

{% block body_html %}
    {% autoescape false %}
        <p>Name: {{ firstName }} {{ lastName }}</p>
        <p>Message: {{ message }}</p>
        <p>Phone Number: {{ phoneNumber }}</p>
        <p>Email address: {{ email }}</p>
    {% endautoescape %}
{% endblock %}

 

And there you have it - an easy way to build and maintain your emails. If you know of any other easier system used to send emails in Symfony2, please let me know in the comment section below.


What Nobody Tells You When You're a Junior Developer

Hooray! You've landed your dream job and you can now proudly call yourself a Junior Developer. The future looks nothing but bright and your awesome life story is underway. But now the hard part actually begins. Here's how you can stay on top of things with some useful tips I wish I knew when I was in your shoes as a junior developer.

Read more


An Introduction to Artificial Intelligence: Facts and Fallacies

One way or another, we all heard of Artificial Intelligence. It's been there since we were born and it will surely outlive us. It’s a promise of a Utopian future and could be a harbinger of our own demise. It could help us end poverty, disease and pollution or it could see us a threat and decide to take us out. Whatever the future might hold, one thing's certain: Artificial Intelligence is (or will be) the Pyramids of a generation and most likely mankind's greatest creation.

Read more


How to Show the Full Path in the OS X Terminal

Working and constantly switching between multiple projects in the OS X Terminal or iTerm (whatever you prefer) can be hassle since, by default, you cannot see the full path of the directory you're working in. Here's how to change that.

 

But first, in the spirit of full disclosure, I'd like to mention that I only found out how to display the full path after I accidentally destroyed the virtual machine of the wrong project and I had to install the whole damn thing all over again.

 

As you might have noticed, the Terminal only displays the current folder in which you're working so it can be pretty easy to make a mistake when your projects have a similar folder structure or are built with the same framework.

 

This first thing you need to do to address that is to fire up your Terminal and open your .bash_profile file:

sudo nano ~/.bash_profile

Then head over to a new line and add:

PS1="\w$ "

Save and close the file, then restart your Terminal. You should now notice that when you browse through your directories, the path should look something like this:

~/Development/hpm/vagrant$

The \w symbol you noticed stands for "Current working directory, full path (ie: /Users/Admin/Desktop)" while the $ mark followed by a space is simply a separator between the working path and the input area.

 

If you want to make the Terminal look even more awesome, here are some other options you can add to PS1:

\W – Current working directory (ie: Desktop/)

\d – Current date

\t – Current time

\h – Host name

\# – Command number

\u – User name

So for, example, using PS1="\u@\w$ " will output "Sebi@~/Development$ ".

I really hope this small tutorial helped. Have fun!

 


Who Really Invented the Internet?

While some see it as one of the greatest evolutionary steps in the history of mankind, most of us still use it for cat videos and annoying status updates. Nonetheless, the Internet has clearly taken over our lives, being directly present in our homes, our pockets, our workplace and soon enough, even in our brains. But who actually built the damn thing?

Read more


Should You Do Scrum?

"It is not the strongest of the species teams that survives, nor the most intelligent. It is the one that is most adaptable to change."

That should be a good enough reason for all teams out there to adopt Scrum, from wedding planners to construction companies. But that isn't always the case and if you stick around, you're going to find out why.

Read more


iOS vs. Android - Which One Should You Choose?

 

Six users, six questions. After a (very) long  research about which mobile OS is better between the two, I realized that the simplest way to find that out is by actually talking to people that use them. As you might expect, everyone has its own requirements and tastes, but in the end, one of the two OSs clearly stands out.

Read more


What Are Transactional Emails?

Every now and then, you might come across a technical term that's not that self-explanatory. One such term is a 'transactional email'. Although few people outside of the email business actually know what that stands for, it's one of the most important aspects of every business that generates its revenue on the Internet.

Read more