How we made friends with Codeception and Drupal

14.07.2017

Taking into consideration the fact that most of our products are based on Drupal, the tests should also naturally work best with such projects. This is why we decided to complement the standard functionality of Codeception with some new modules dedicated for Drupal.
As in our previous article, all examples listed below will be based on a project based on docker-console, which is why we encourage everybody to read the previous articles first if you didn’t do so yet. If you already have your Codeception project and just want to slightly modify it so that it works better with Drupal, this article is also for you.
When we first took a shot at expanding the functionality of our tests, we had some requirements that did not fully line up with existing modules, which is why the majority of solutions listed below was created by us. They are all based on other, previously available solutions, but we hope you will like the way Droptica expanded them and made them a cohesive whole, available in a blink of an eye in your Codeception project config.

Example

Its use is obvious for anybody working with Drupal. In a recent article, we showed you an example of checking whether a given module is operational using Drupal commands. In this note, we are going to show you another helpful test to check whether features of your website is not overwritten. If you want this example to work with our project, you have to add the features module to your project and export some features You can also fetch files from codeception-drupal branch, where we did that for you already.

codeception-drupal-users

Another module presented in this article is codeception-drupal-users, which can be found at: https://github.com/droptica/codeception-drupal-users . This is a modified drupal-user-registry module – https://github.com/ixis/codeception-module-drupal-user-registry , used for automatic creation of test users while launching a test suite. Using the module, you can quickly create and use test users with specified roles during your tests. By default, all test users will be removed after completing all tests from a given suite (unless specified otherwise).
The original module uses drush for creating users; however, this method did not allow for filling custom profile fields, which is why our module uses Drupal functions instead of drush for creating new users. Because of that, it is possible for us not only to fill in standard user details but also custom profile fields.

Configuration

The configuration is simple and is all done in a configuration file of a given suite. However, it is necessary to remember about several things. First of all, in order for this module to work, you have to enable codeception-drupal-bootstrap module in a given suite. Additionally, the Entity API (https://www.drupal.org/project/entity) module should be also enabled in the project.

Examples

It is always best to discuss configuration using an example, which is why we added two additional fields and three new roles for users. (If you don’t know how to do this in your project, you can fetch the changes from docker-drupal branch). After enabling the module, we have to specify what kinds of users we want to create. In order to do so, we have to first declare the roles of our users (you can do this the way it is in the example presented below or declare, e.g. roles custom, where the user will have several roles defined in the system). After describing the roles in the project, I also specify the data that will be used to fill our new fields (I could specify them for each user separately). After doing that, we can move on to specifying the exact users we want codeception to create before executing our tests. At the end, we should have a “true” value in “create” if we want our users to be created before executing a given suite. The same applies to “delete” – this deletes our users after executing a test suite. In my case, the users are not deleted so that we can check in the system whether they were created in the first place. If we execute the test twice, the new users will not be duplicated, we will get an error message saying that the user already exists in the system.

For Drupal 8, the configuration of the module looks almost identical. The only difference is enabling the module using:

- \Codeception\Module\Drupal8\ManageUsers:

instead of ManageUsers.
Of course, you can use the functions from this module while writing the test case. Among the most useful ones are those that allow us to refer to a test user or a group of users:

After doing this, the execution of tests should generate contentTypes.yml file, listing the structure of nodes available in the project. An example of such a file can be seen in the image below.

If one of the content types has defined fields such as field collection or others, which comprise nested fields (e.g. location), the contentTypes.yml file will include just the main fields, without nested ones. In order to fill in the nested fields, such as in field collection, you have to include them in contentTypesOverrides.yml file. All people who initiated the project using docker-console unit-tests or merged the code from our example repository should already have this file in their projects. It should contain tips on how to overwrite the given configuration and look like the one below.

Example

In our example, we will show you how to create an article type node using this module.

codeception-drupal-content-types + NodeSteps

In order to make our work with the module even easier, we added some additional supporting functions, which allow us to specify which user we want to use in order to add or remove a given node. The NodeSteps file contains functions that log us in as a given user before adding/removing a node. An example of using these functions can be found below, here we are adding a “page” node as admin_user.

codeception-drupal-storage

The final module presented in today’s article is codeception-drupal-storage, which can be found at: https://github.com/droptica/codeception-drupal-storage
It is used for storing variables and the test nodes we create globally in the entire test suite until we finish executing tests from a given suite.
In this module, you can take advantage of the following methods:

setVariableToStorage($name, $value)

getVariablesFromStorage($names = array())

getVariableFromStorage($name)

deleteVariableFromStorage($name)

appendNodeToStorage($nid)

getAllNodesFromStorage()

getNodeFromStorage($nid)

deleteNodeFromStorage($nid)

Configuration

The module does not require any complicated configuration, simply enable it by adding the following line to the config file of a given suite.

- SuiteVariablesStorage

Example

As in every case, it is always best to see what the module can do with an example. In our example, presented below, we split creating a node, checking whether it has proper content and removing it altogether into three separate tests, which allowed us to show how we are able to move a given value from one test to another. Of course, the tests don’t have to be in a single file; however, it is vital that they all belong to a single suite because after the suite is executed, all values created during the tests are removed. (Additionally, you can remove a given value at any time using the appropriate method.)

Helper functions:

Apart from adding modules, we will add special functions to every project, allowing us to better test the website. We already demonstrated these functions when we presented NodeSteps with codeception-drupal-content-types module. (These are some special classes, you can read more about them here: http://codeception.com/docs/06-ReusingTestCode#StepObjects

We will also discuss them in detail in one of our upcoming articles.) You can also write helper functions in files added to every test suite, for example, the “Acceptance” file in _support/Helper or create a new file and write helper functions there, just like in our example with the DrupalHelper file found in the same folder. Regardless of which variant you choose, you should remember to unlock the access to these functions in a given suite in a yaml file, like in the example listed below.

If you don’t do it, you will have to import it in every file where you will want to use a given function by adding e.g.

use Step\Acceptance\UserSteps;
use Step\Acceptance\NodeSteps;

Conclusion

We hope that you like our small improvements for Drupal. If you are using a solution that is dedicated for Drupal and we haven’t written anything about it yet, let us know – we will gladly expand our configuration with new and cool modules. If you're just starting your adventure with Codeception, we encourage you to experiment and write as many tests as you can on your own, because as you probably already know, “practice makes perfect”. Additionally, we encourage everybody to keep visiting our blog – you can be sure that we will write more about this tool in the future.

Get blog updates in your inbox!

Sign up for out newsletter and get e-mails of stories like this.

Your name

Your e-mail address

By Subscribing to our newsletter you agree for terms and conditions

By sending the form You consent to process Your personal data by DROPTICA Sp. z o.o. based in Wrocław ul. Duńska 9 and to entrust data to subjects cooperating with DROPTICA Sp. z o.o. for processing purposes. Submission of data is voluntary, however, lack of consent for personal data processing makes it impossible to answer your question. You have the right to access your personal data and correct it.