Cleaning up after each Test Run


As it stands we have our Behat test suite up and running. We've defined our basic GET, POST, PUT, PATCH, and DELETE scenarios, and we've created a Background step to setup the database by dogfooding our own API.

I keep saying it, but it's worth repeating:

The way we are using Behat here is unusual.

We're trying to save ourselves the hassle of creating and maintaining multiple identical test suites. We will have a bunch of JSON API implementations that all follow the exact same spec. This is a non-typical circumstance.

As we've extracted and centralised our test suite, we hit on some unique challenges that typically would be trivial to solve.

Adding data is one.

Cleaning up after ourselves is another.

What I don't want to do is set up some weird /cleanup endpoint, or something of that nature, and when hit this would truncate our database tables. Nasty.

Instead, I'm going to go hardcore and smash a SQL command in via PDO.

// features/bootstrap/FeatureContext.php

    /**
     * @BeforeScenario
     */
    public function cleanUpDatabase()
    {
        $host = '0.0.0.0';
        $db   = 'basic_api';
        $port = 3306;
        $user = 'dbuser';
        $pass = 'dbpassword';
        $charset = 'utf8mb4';

        $dsn = "mysql:host=$host;port=$port;dbname=$db;charset=$charset";
        $opt = [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ];
        $pdo = new PDO($dsn, $user, $pass, $opt);

        $pdo->query('TRUNCATE album');
    }

Even if you don't understand how this works, the code itself should hopefully explain what's happening.

This is an awesome tutorial on PDO that tells you more about the topic than I ever could.

We're telling Behat that before any scenario (via the @BeforeScenario annotation) to run this cleanUpDatabase method.

This method uses the given parameters to directly connect to our database server / container.

Once connected all we are doing is a TRUNCATE which deletes all the data in the album table, and crucially resets the auto incrementing ID field back to 0.

This will be important for our GET tests, which will expect to start at ID 1.

Hardcode Mode

The downside to this approach is that when we switch projects we will need to swap out our configuration. This should be as simple as updating the variables, or changing the $dsn to connect to Postgres.

This may seem a bit nasty to you.

I'm open to suggestions on a better implementation given the limitations described in sharing the test suite.

I appreciate at this point in the course we haven't even got to setting up and configuring a database. So let's get on to that very topic in the next video.

Episodes

# Title Duration
1 What will our JSON API actually do? 08:46
2 What needs to be in our Database for our Tests to work? 12:32
3 Cleaning up after each Test Run 02:40
4 Docker makes for Easy Databases 09:01
5 Healthcheck [Raw Symfony 4] 07:53
6 Send in JSON data using POST [Raw Symfony 4] 05:33
7 Keep your data nice and tidy using Symfony's Form [Raw Symfony 4] 10:48
8 Validating incoming JSON [Raw Symfony 4] 08:26
9 Nicer error messages [Raw Symfony 4] 06:23
10 GET'ting data from our Symfony 4 API [Raw Symfony 4] 08:11
11 GET'ting a collection of Albums [Raw Symfony 4] 01:50
12 Update existing Albums with PUT [Raw Symfony 4] 05:00
13 Upsetting Purists with PATCH [Raw Symfony 4] 02:39
14 Hitting DELETE [Raw Symfony 4] 02:11
15 How to open your API to the outside world with CORS [Raw Symfony 4] 07:48
16 Getting Setup with Symfony 4 and FOSRESTBundle [FOSRESTBundle] 09:11
17 Healthcheck [FOSRESTBundle] 06:14
18 Handling POST requests [FOSRESTBundle] 08:31
19 Saving POST data to the database [FOSRESTBundle] 09:44
20 Work with XML, or JSON, or Both [FOSRESTBundle] 04:31
21 Going far, then Too Far with the ViewResponseListener [FOSRESTBundle] 03:19
22 GET'ting data from your Symfony 4 API [FOSRESTBundle] 05:58
23 GET'ting a Collection of data from your Symfony 4 API [FOSRESTBundle] 01:27
24 Updating with PUT [FOSRESTBundle] 02:58
25 Partially Updating with PATCH [FOSRESTBundle] 02:15
26 DELETE'ing Albums [FOSRESTBundle] 01:27
27 Handling Errors [FOSRESTBundle] 08:58
28 Introducing the API Platform [API Platform] 08:19
29 The Entry Point [API Platform] 04:30
30 The Context [API Platform] 05:52
31 Healthcheck - Custom Endpoint [API Platform] 05:17
32 Starting with POST [API Platform] 07:08
33 Creating Entities with the Schema Generator [API Platform] 07:38
34 Defining A Custom POST Route [API Platform] 07:31
35 Finishing POST [API Platform] 06:29
36 GET'ting One Resource [API Platform] 02:50
37 GET'ting Multiple Resources [API Platform] 02:59
38 PUT to Update Existing Data [API Platform] 02:19
39 DELETE to Remove Data [API Platform] 01:15
40 No One Likes Errors [API Platform] 03:28