Software Testing

Software testing

Software testing is the process to evaluate a software item to detect differences between a given input and expected output. It should be started during development process as you will reduce the possibilities of returning to development phase due to unexpected errors/missing functionalities. It meets two steps:

  • Verification: Software has the expected behavior.

  • Validation: Meets client requirements.

This document will be focused on Drupal Back-end elements.


Types of testing

There are two basic types:

Blackbox Testing: See the output generated given an input, not taking into account the system internal mechanism. Associated with validation step, this type can be branched into:

  • Integration testing: Check a group of components interacting between them provides the expected output. Talking about blackbox testing, this can be added to functional testing.

  • Functional testing: Specified functionality works. This is the testing process we usually follow during development phase based on client's acceptance criteria. All possible combinations must be tested in order to ensure the quality of the system:

    • Fields: In case there's a form, types of values and max length must be tested here. For example, an email field must not accept integer values, strings without “@domain” suffix... Also length is important when displaying as front-end can be broken due to long/short texts in display mode (remember trimming!).

    • Exposed filters: If you are testing a view, exposed filters must be tested to confirm content is being selected correctly. In case of multiple filters, test complex filter combinations. This helps you to avoid duplicated content, errors on content access...

    • Contextual filters: This is important if you are developing Related content views or similar, as you need to ensure the correct content is being displayed. Remember to check if the current node is excluded and the rest is correctly tagged with the same taxonomies/related entities. There are other important examples like Articles tagged to an Event, domain access...

    • Multi-domain: Remember to test functionalities which can affect content in other domains so access, security and performance can be ensured.

    • Multi-language: Test display of content, views, forms, maps, etc in all languages. Try inserting language prefix in the URL directly and also changing it from the multi-language dropdown. Be specially careful with register/reset password forms and URL's containing generated tokens.

    • Workbench moderation: If WBM module installed, pay attention as the structure of entities can change between content in Draft or Published states, so you may need to get the data from other sources. Test everything is working at least in these two moderation states. Be specially careful with field collections and paragraphs as they have lots of compatibility problems with this module.

    • Permissions: Check with different user accounts, preferably with the account customers will test the functionality to ensure they will be able to use it.


  • System testing: Software works in different environments. Make sure sites are working in different servers (with their own PHP/MySQL versions, webservers), browsers and devices. Focusing on backend, it's really important to remember checking IDs. As content can be outdated and different depending on the environment (stager, sandbox, dev, beta, live...) we need to take care of it and manage them in code checking which environment we are on. Also, it's important to test functionalities in local recreating other environments. Although we must branch/sync live codebase/database to start developing process, before pushing to other environments we should test the new systems with the codebase/database we are going to push the changes to. E.g: we should test in our local the new system with stager branch/database before pushing to stager.

  • Stress testing: How system behaves under unfavorable conditions. This is basically testing all limits you can imagine, examples:

    • Big amount of content in views.

    • Big number of paragraphs in the same page.

    • Lots of users submitting the same webform.


  • Performance testing: Sometimes we can think something is working good but it's not having good performance (e.g: A paragraph with high preprocessing work added a few times in the same page). Some things we can do to test/ensure better performance:

    • Webserver configuration: We can decrease parameters in PHP, MySQL and Apache/NGINX (such as max_input_vars, max_allowed_packets) to see if the functionality requires too much resources and crashes.

    • Settings.php configuration: We can decrease memory_limit to see where it crashes.

    • Caching: Using cache both in CMS/code can speed up a lot page loading.

    • Networking: When you are inspecting code in browser, the Networking tab helps a lot as it logs how much time takes to load a component. This can guide you to functions that need to be optimized.

    • Logs: Checking the logs when testing and reducing the number of notices/warnings/errors improves a lot the performance. We have to pay attention to main functions (like preprocess_node) as they can be executed lots of times in a single page load. Some tips we can follow to optimize logs:

      • Try to set a value for new global variables to be used later always. This can avoid most “undefined variable” warnings.

      • Make sure the variables you are going to use are defined or not. Some of them are always defined. If not, use isset() or empty()functions depending on what you need. The emtpy() function contains an isset() check too, so sometimes you won't need to check both. This will avoid most “undefined index” warnings.

      • When preprocessing entities on hooks, use path_is_admin(current_path) to stop the function and return if the code you are developing can be executed also in admin pages. E.g: looping to find a specific paragraph in preprocess_page hook will be executed also in node edit forms.

      • Use break in loops and build correct conditional structures (if, elseif, else) so only needed code is executed.

      • Unset variables if the function will keep running and you don't need to store values there anymore.

      • Check unused parameters/variables and remove what you don't need.

      • Be careful with entity and global variable loads like node_load(), global $language, etc. Research a bit if you can find the value/variable you need without making calls to the DB.

    • Fields: Reuse existing fields when you can, this will reduce the number of tables in the DB. Less memory used, better performance.

    • Security: Security and performance goes together. If we are working on forms, creating new text formats, SQL queries... Check the configuration of the system to avoid future problems with spam content which will make load times higher.


  • Usability testing: Perform testing from client perspective. Usability must be in mind since the design phase. As we usually use Drupal UI the best we can do is to create guides for them unless we are creating a new whole web application.

  • Acceptance testing: Customers ensure the delivered product works as expected. They must specify their acceptance criteria before developing phase starts.

  • Regression testing: Test functionalities after modifications. Specially in sprints/big releases where we got dependant functionalities, it's important to check again old functionalities if they are related or can be affected.

  • Beta testing: End users test the functionalities to find unexpected errors in beta environments. This is the closest test process to live launch.


Whitebox Testing ↔ Structural testing: Debugging, see the internal mechanism of a system. Associated with verification step, this type can be branched into:

  • Unit testing: Involves testing individual units. E.g: Function to remove a content item from user bookmarks, which also decreases a counter. Unit testing is important and we should plan/specify some cases to cover all possible outputs given different inputs. Also we should test using the same function a few times before reloading the page, in small intervals of time, trying to find unexpected errors we must solve with timeouts/new checks.

  • Integration testing: As said above in blackbox testing, integration testing can be covered by both basic types. Talking about whitebox testing, we can understand this one as a group of unit testings. We can set some inputs to be processed by a group of functions to get an expected output. Debugging inside units and check the values they are passing through ensures they are running correctly.


User guide for testing

As we said in the introduction, testing is a process we must start during developing phase. In our opinion this is really important as we can start planning testing processes even before developing phase. If the task is pretty simple and will take just a couple of hours we can be more permissive, but harder tasks needs a really deep research of the site components, configuration options and code.

What I recommend to do before start developing:

1. If you don't know the site, take a look at the code/CMS for:

  • Installed modules.

  • Installed/used themes and templates.

  • Entities (content types, taxonomies...) and understand the relationships between them.

  • Views

  • Features?

  • Workbench moderation?

  • Domains?

  • Multilingual?

This will help you to understand what things you must pay attention when developing code and creating new fields.

2. Understand fully what the task asks navigating through the site and it's acceptance criteria.

3. For each point in acceptance criteria, see:

  • Which steps you must follow in CMS (new/modify content type, fields, install required modules...)

  • Which code you've got to write (new/modify templates, preprocesses, single functions...). If you want to go further and everything is clear for you, specify the lines of code where you have to insert the new content.

4. If features installed, which features you've got to update/revert.

5. Think about which functionalities can be affected by this new changes.


An example of what it's said above:

User story:

  1. As an user, I must be able to see all Articles related to an event.Features: Update views feature.

Acceptance criteria:

  1. A new item in the Event sidebar menu called Articles - New list item in node--event.tpl.php line 95

  2. When I click on Articles, I must see a list of articles related to that event. - Create a new block view in articles view. Use views_embed_view in template.php below line 573 and then create a div to print it in node--event.tpl.php line 287

Notes: Check AJAX is working for Articles.


Load more not working in Articles view tab.

Event header used in articles if clicked from event articles

Features: Update views feature.


Writing this notes doesn't take too much time and decreases enormously developing time as you know exactly where to go and what to do. Also it allows you to have a bigger perspective on which elements you have to test event before start developing. In case the task it's too hard or big, I recommend to do a small prototype. This helps you to understand better the functionality you have to implement reducing the risks of delivering the product out of date.

User story:

As an user, I must be able to see all Articles related to an event.

Acceptance criteria:

A new item in the Event sidebar menu called Articles - New list item in node--event.tpl.php line 95

When I click on Articles, I must see a list of articles related to that event. - Create a new block view in articles view. Use views_embed_view in template.php below line 573 and then create a div to print it in node--event.tpl.php line 287

Notes: Check AJAX is working for Articles.


Load more not working in Articles view tab.

Event header used in articles if clicked from event articles

Talking about testing types specified above, the testings we can perform as back-enders ordered by priority on developing phase are:

1. Unit testing – when individual functions are created.

2. Integration testing – how the individual functions work together as we create new ones.

3. Functional testing – the system works with all possibilities.

4. Stress testing – test limits.

5. Performance testing – test speed on page load.

6. System testing – it works in other environments?

7. Regression testing – re-check all functionalities developed in this system if you have to make modifications.



We can conclude that testing must be planned with details and it should come along with the other phases since Estimation. I think it's really important to know how something will be developed since we estimate the task. This will improve not only our estimation skills but we will reduce the time we will use developing (which will give us more time to test) and also the quantity of feedback we will get from clients, which can make us not delivering the products in time.



Autor: Santiago Martínez Gómez -Developer and back-end of Zoocha >>