Load Testing With Behat

Posted: 2017-02-01 20:57:03

The team I am a part of write our tests using Behat for the most part as we try to practice BDD and take advantage of how writing in Gherkin can lead our code to be more inline with the language of the business.

In this case I wanted to replicate some file upload and processing that the system will be doing during a training that will happen next week as 4 users are uploading files and going through the entire process.

To do this I made an Artisan command to run these tests in parallel

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Process\Process;

class LoadTestingCommand extends Command
{
    public $processes;

    protected $signature = 'load:testing {number} {--profile=default}';

    protected $description = 'Run x number of load tests';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $this->processes = [];

        foreach(range(1, $this->argument('number')) as $index) {
            $this->info(sprintf("Start running process %d", $index + 1));

            $command = $this->getCommandToRun();

            $process = new Process($command);
            $process->setTimeout(12000);
            $process->start();
            $this->processes[] = $process;
        }

        while(count($this->processes) > 0) {
            /** @var Process $process */
            foreach($this->processes as $key => $process) {
                if(!$process->isRunning()) {
                    $this->info(sprintf("Done running process %d", $key));
                    $this->info($process->getOutput());
                    unset($this->processes[$key]);
                }

                $this->info(sprintf("Still running process %d", $key));
                sleep(2);
            }
        }
    }

    private function getCommandToRun()
    {
        $profile = $this->option('profile');
        $command = sprintf("vendor/bin/behat --profile=%s -se2e_load_test", $profile);
        return $command;
    }
}

Just very simple for now. It allows the user to pass the number of concurrent tests to run and the profile to use, eg Staging, Production etc.

Here is the behat.yml

load_testing_staging:
  extensions:
    Behat\MinkExtension:
      base_url: https://foo-staging.bar.com

load_testing_production:
  extensions:
    Behat\MinkExtension:
      base_url: https://foo.bar.com

Now when I run the command we get 4 windows starting up interacting with the site, and a terminal running top just to see if there are any obvious issues. I could take this a lot further by running other monitoring tools on the servers but in this case I wanted to just get a sense of how well it would work for there to be x users uploading files and what not at the same time.


Tags:

behat laravel