Remote Behat Testing with Laravel

Posted: 2016-02-03 19:59:58

balloon_2_or_3

Listen Here

This document will cover how to use a Behat specific API to setup a site for testing. What this includes is setting up a Scenario so that it has the data you need to run a test. This makes it possible not to rely on Seed data for this. This will allow us to run behat tests from remote machines as well as run tests in parallel.

Why not seed data?

From experience seed data fails in two ways.

One a project gets large and there is a ton of seed data and one person adds to it or alters in a way that effects how someone else was expecting the data to be. It just becomes too much of it's own domain of knowledge outside of the test it applies to.

Second seed data assumes you can reset the state of the application at anytime. But if you want to run your tests in parallel you need to have a more precise system to set up the "World" for that particular Scenario.

The API

First we will setup an API in our app just for Behat and the behat user.

Example Route protected by Authentication as a particular user.

Route::get('/api/v1/behat/setup_campaign_eu',
    ['as' => 'behat.camp_eu', 'uses' => '\AlfredNutileInc\BehatAPI\BehatApiController@setupCampaignEU']);

Example Controller

    public function setEUCampaignToPushed()
    {
        $campaign = Campaign::find($this->campaign_id_eu);

        if($campaign)
        {
            $campaign->status = Campaign::PUSHED;
            $campaign->save();
        }
    }

So now our data is set.

Behat Steps

So when we run our Behat test we start by setting that state.

  Background: Login
    Given I setup campaigns
    Given I login as "admin"
    And I wait

We are setting up this state right before we run the Scenario(s). Of course we can move this one step into the needed Scenario if there are many in the test.

Example of the FeatureContext.php file that has this step.

    /**
     * @Given /^I setup campaigns$/
     */
    public function iSetupCampaigns()
    {
        $this->iLoginAs('behat');

        $this->visit('/api/v1/behat/setup_campaign_eu');
    }

You see we are using the already existing Behat steps and sessions to log in and finally hit the API path we created above.

Clean Up

And using the hooks that Behat has we can clean up after our steps even if there is a fail. Again leaving the system in the same stat it was when we first hit it with our tests.

The test file's scenario has a tag @1_1 as seen below

  @1_1
  Scenario: Campaign Misc
    Given I am on an EU Campaign
    And I wait

This tag is then called in our FeatureContext file using a Behat Hook AfterScenario

    /**
     * @AfterScenario @1_1
     */
    public function after_1_1($event)
    {
        $this->iLoginAs('behat');
        $this->visit('/api/v1/behat/1_1_cleanup');
    }

This allows us to hit the api at the end of the Scenario once again

    public function cleanUpCampaignEU()
    {
        try
        {
            $country = Country::find('test-country-eu');
            $country->active = 0;
            $country->save();

            $campaign_fixture = $this->loadCampaignFixtureForEu();

            $this->cleanOutRelatedMetaMaster($campaign_fixture);

            $this->cleanUpByID($campaign_fixture);

            $this->cleanUpByID_16Name();

            $this->misc_cleanup();
            return Response::json("Done cleaning Campaign EU", 200);
        }
        catch(\Exception $e)
        {
            return Response::json("Error cleaning Campaign EU " . $e->getMessage());
        }
    }

And that is it. We have tested and cleaned up after our selves with a precision that allows us to run tests in parallel, from remote machines and to even do smoke tests on any environment.


Tags:

behat laravel