Upgrading Sylius the TDD Way: Exploring Behat

Last time, we developed some new features on top of Sylius’ core to indicate which products and their variants are low on stock and need replenishing. Now, we move on to seeing our changes in the UI, which means we will need to do a bit of StoryBDD testing.

When browsing the list of products, we want to see a new column called Inventory which will hold a sum of all available tracked variants’ stock amounts.

Sylius logo

Writing StoryBDD tests

Behat is the tool we want to use here. After making sure Behat is working well by running any feature from the Sylius package, we create a new features/product/managing_products/browsing_products_with_inventory.feature file with the following definition:

Feature: Browsing products with inventory
    In order to manage my shop merchandise
    As an Administrator
    I want to be able to browse products

        Given the store operates on a single channel in "United States"
        And the store has a product "Kubus"
        And it comes in the following variations:
            | name          | price     |
            | Kubus Banana  | $2.00     |
            | Kubus Carrot  | $2.00     |
        And there are 3 units of "Kubus Banana" variant of product "Kubus" available in the inventory
        And there are 5 units of "Kubus Carrot" variant of product "Kubus" available in the inventory
        And I am logged in as an administrator

    Scenario: Browsing defined products with inventory
        Given the "Kubus Banana" product variant is tracked by the inventory
        And the "Kubus Carrot" product variant is tracked by the inventory
        When I want to browse products
        Then I should see that the product "Kubus" has 8 on hand quantity

Again, we describe the make-up of our test product, stating the name, price and available stock of the two variants. If we run this feature, we see a list of paths for available contexts. We aren’t interested in any of them, but we also get a hint, so we select None.

php bin/behat features/product/managing_products/browsing_products_with_inventory.feature
--- Use --snippets-for CLI option to generate snippets for following ui_managing_inventory suite steps:

    When I want to browse products
    Then I should see that the product "Kubus" has 18 on hand quantity

We create our context in src/Sylius/Behat/Context/Ui/Admin/ManagingProductsInventoryContext.php and add this:


// src/Sylius/Behat/Context/Ui/Admin/ManagingProductsInventoryContext.php

namespace SyliusBehatContextUiAdmin;

use BehatBehatContextContext;

class ManagingProductsInventoryContext implements Context

Running the feature again doesn’t seem to help as we get the same list of contexts as before. That’s because Sylius doesn’t know anything about our class. We need to configure a service for our context together with what Sylius has in src/Sylius/Behat/Resources/config/services/contexts/ui.xml. We now search for managing_products and add this below it:

<service id="sylius.behat.context.ui.admin.managing_products_inventory" class="SyliusBehatContextUiAdminManagingProductsInventoryContext">
    <argument type="service" id="sylius.behat.page.admin.product.index" />
    <tag name="fob.context_service" />

Let’s add our sylius.behat.context.ui.admin.managing_products_inventory service (that’s the id in ui.xml) to the context services for ui_managing_inventory suites in src/Sylius/Behat/Resources/config/suites/ui/inventory/managing_inventory.yml.

We may need to clear the cache. If we run the feature, we now get an option to select SyliusBehatContextUiAdminManagingProductsInventoryContext. We then get:

--- SyliusBehatContextUiAdminManagingProductsInventoryContext has missing steps. Define them with these snippets:

     * @When I want to browse products
    public function iWantToBrowseProducts()
        throw new PendingException();

     * @Then I should see that the product :arg1 has :arg2 on hand quantity
    public function iShouldSeeThatTheProductHasOnHandQuantity($arg1, $arg2)
        throw new PendingException();

We can just copy and paste the snippets into the context class we created. Out of curiosity we may import PendingException just to see the output. Let’s add use BehatBehatTesterExceptionPendingException; to the top of the class and re-run the feature.

We get an error:

An exception occured in driver: SQLSTATE[HY000] [1049] Unknown database 'xxxx_test' (DoctrineDBALExceptionConnectionException)

That’s because we haven’t created the test database. These two commands will do that for us now.

Continue reading %Upgrading Sylius the TDD Way: Exploring Behat%

Source: Sitepoint