How to write task specifications

Introduction

Effective communication is essential in every aspect of life, including software development where written specifications are the primary mode of communication between developers and other stakeholders. Writing a task specification can be intimidating and challenging for some, but with the right approach, it can be made easier and much more productive. In this article, we will provide tips and recommendations on how to write effective task specifications that lead to successful software development outcomes.

Writing specifications is crucial in bridging the gap between developers and business owners, as misunderstandings are unfortunately too common. If not done properly, it can lead to a chaotic and unproductive game of "guess the intention". 

There are several telltale signs of poorly written specifications. The first being the infamous situation where the code doesn't quite "get it", causing developers to blaze their own trail, leading to multiple rounds of fixing. 

If the specifications are very vague, it can cause developers to go on a wild goose chase, meaning tons of time wasted and minimal progress made.

PMs can add requirements mid-development due to lack of proper planning, causing developers to throw in the towel and start again from scratch.

Lastly, having overly cryptic specifications can be a nuisance, unless you're a specialist in that area, leading to more questions than answers. All in all, following these writing recommendations can save time, restore sanity, and leave everyone with a sense of accomplishment!

How to solve it

To effectively address the issues caused by poorly written specifications, the most successful approach is to adopt the Behaviour Driven Development (BDD) method. BDD involves creating user stories that outline the expected behavior of an application from the perspective of an everyday user.

Here's how it works:

Imagine you're a user without technical knowledge on how the app works. You want to access your music files stored on cloud services like Dropbox and Google Drive. You enter your login information and start browsing through your library of music, making playlists, and moving files around. Of course, you want to play your tunes too!

However, the problem arises when your internet connection is unstable or non-existent, and you can't play your music. Talk about a vibe killer! To prevent this from happening, we need an offline download function that allows the user to listen to their music files even when they don't have access to the internet. And so, we can start writing some behavior specifications for this new feature.

Looking at the working project (Given part)

To effectively implement the desired changes, it's important to understand the current functionality of the app. Here is a summary of the app's existing features:

First we should try to describe the current functionality we want to change:

As a user, I can log in to my account and access my music library stored on cloud services like Google Drive and Dropbox. When I access my library, I can see all of my stored songs. To listen to a song, all I have to do is click on it!

Assuming expected behaviour (Expectations part)

Let's use our imagination to fast-forward one month into the future and see how successful our project is with our new offline playback feature. Here's what I'd expect to see as "future me":

Upon opening the app, I see that I can now download files from my Google Drive or Dropbox to my device with a simple click of a button. This means I can save my favorite playlists and access them without any internet disruptions. 

In the app's settings, I can choose the default download folder and set a size limit for my downloads. And here's the best part - when I browse through my folders, all of the files that I've already downloaded to my device will be marked with a bright green color. So I know exactly which ones are accessible even with no internet connection. 

Also, I can easily remove downloaded files from my device to free up storage space without losing access to them on the cloud platform. Lastly, when I'm on-the-go and without internet connection, I can still listen to my music just like I normally would. 

I'm happy with the feature if... (Acceptance part)

As we strive to achieve our project goals, it's important to keep our focus and ensure everything is on track. To put it into perspective, let's imagine we are making a grocery list to ensure we grab everything we need:

1. I can specify the download folder location and set a size limit that's perfect for all tunes on my device. 

2. I can download folders and playlists

3. I'm always able to easily differentiate between your downloaded and non-downloaded folders and playlists. 

4. I can delete downloaded folders/playlists only from device

5. I can play downloaded tunes in the "offline" mode

This paragraph is essentially an answer to the question: "Is the task considered complete if all points have been checked?". 

We can describe behavior-driven specifications as a list of the following rules:

Rule 1: Describe a specific user behavior, rather than a set of requirements for how the system should function.

Specifications should not be abstract, especially not defined as a list of rules for how the system should work. Behavior specifications should not be expressed in language reminiscent of military orders, recipes, or requirements, and should avoid phrases such as "please implement," "solve," "make," "reorganize," "improve," and so on.

Good specifications should focus on putting the user at the center of attention, excluding the developer from the task. This is because general orders leave a lot of room for different interpretations by both developers and testers, who may lack a shared understanding. Instead, specifications should consider the user's perspective and anticipate their possible actions or problems.

Let’s see some examples:

The full text search feature is currently not working and requires urgent attention to fix it.

It's too abstract! Where can I find the full text search function? Also, can you specify what exactly is not working?

Implement a logic of adding static pages e.g. “About us”

What are static pages, and what content should be included on them?

On the page for adding new products, the picture upload function is not working. It is necessary to ensure that this function works correctly.

Where can this page be found, and what specific issue is occurring with the picture upload function?

Specifications must be specific, providing clear steps on how to reproduce a problem or implement a new feature. In all cases, the anticipated user behavior should be defined as if the new functionality already existed.

The task definitions should include the following sections:

Current state of the application (given)

This section outlines the preparation steps that should be completed prior to the emergence of a bug or implementation of new functionality.

Example 1

Given

I am on the main page and I enter any text into the search field located in the footer. After hitting the search button, the page with the search results does not appear.

Example 2

Given

As a logged-in user, when I go to the page someurl.com and click on the button 'Upload images', I am able to select five files. However, upon clicking the 'Save' button, nothing happens. I can see the progress bar and text field during the file upload process.

Example 3

Given

I am on the main page and I scroll down to the footer.

Expected state of the application (when-then)

In this section, we describe the expected behavior of the system from the user's perspective. This is a crucial text for both developers and testers as it provides a clear understanding of whether the task is complete or not. The behavior is described using concrete examples without abstract requirements. Continuing with the examples above:

Example 1

Given

I am on the main page and I enter any text into the search field located in the footer. After hitting the search button, the page with the search results does not appear.

Expected

As a user, when I search for any text in the search field, I should be able to see a page with up to 30 results that match the search criteria. The page should display products, reviews, and photos that contain the search text. If more than 30 results are found, I should be able to click on the 'Show more' button to see the next 30 results. This process can be repeated until all relevant search results are visible on the page. Please refer to the attached HTML markup file for an example page layout.

Example 2

Given

As a logged-in user, when I go to the page someurl.com and click on the button 'Upload images', I am able to select five files. However, upon clicking the 'Save' button, nothing happens. I can see the progress bar and text field during the file upload process.

Expected

When clicking on the "save" button, all uploaded pictures should be displayed under the product title on the product page. The newly uploaded pictures should be listed first, followed by any previously uploaded pictures.

Example 3

Given

I am on the main page and I scroll down to the footer.

Expected

In the footer, a new link called "About Us" should appear. Clicking on this link should redirect the user to the page located at http://someurl.com/about-us. The page's design should match the attachment included in the ticket. Once logged in as an administrator, navigate to the http://someurl.com/admin page. From there, access the "Static Pages" menu section and locate the "About Us" menu item, which should correspond to the http://someurl.com/about-us page. Upon editing the text in this section, the changes should reflect on the front page.

Acceptance criteria (the task is solved, when)

This section contains additional formal requirements for the previous text where we described the expected system behaviour. Here we can list the criteria for the task to be accepted. Here we can describe some hints for the tester who should make this decision. Acceptance criteria is a TODO list, where we chan tick the done points and stop working on the task if we reach its bottom.

This section outlines the additional formal requirements for the previously described expected system behavior. In this section, we can list the specific criteria that must be met for the task to be considered complete. Additionally, helpful information or points of guidance can be provided to the tester to aid in the decision-making process. The acceptance criteria can serve as a "to-do" list to ensure all of the necessary requirements are met before closing out the task.

Example 1

Given

I am on the main page and I enter any text into the search field located in the footer. After hitting the search button, the page with the search results does not appear.

Expected

As a user, when I search for any text in the search field, I should be able to see a page with up to 30 results that match the search criteria. The page should display products, reviews, and photos that contain the search text. If more than 30 results are found, I should be able to click on the 'Show more' button to see the next 30 results. This process can be repeated until all relevant search results are visible on the page. Please refer to the attached HTML markup file for an example page layout.

Acceptance criteria

  • The search results page must match the provided HTML file

  • All products, reviews, and photos associated with the provided search text should be displayed on the search results page

  • Pagination should be available for the search results, allowing the user to navigate through multiple pages of results.

Example 2

Given

As a logged-in user, when I go to the page someurl.com and click on the button 'Upload images', I am able to select five files. However, upon clicking the 'Save' button, nothing happens. I can see the progress bar and text field during the file upload process.

Expected

When clicking on the "save" button, all uploaded pictures should be displayed under the product title on the product page. The newly uploaded pictures should be listed first, followed by any previously uploaded pictures.

Acceptance criteria

  • Uploading images should result in their visibility on the product page

  • The newly uploaded images should be listed first, followed by any previously uploaded images.

Example 3

Given

I am on the main page and I scroll down to the footer.

Expected

In the footer, a new link called "About Us" should appear. Clicking on this link should redirect the user to the page located at http://someurl.com/about-us. The page's design should match the attachment included in the ticket. Once logged in as an administrator, navigate to the http://someurl.com/admin page. From there, access the "Static Pages" menu section and locate the "About Us" menu item, which should correspond to the http://someurl.com/about-us page. Upon editing the text in this section, the changes should reflect on the front page.

Acceptance criteria

  • The design of the About Us page should match the attachment provided

  • The text on the About Us page should be editable in the admin section of the website.

Rule 2: All specifications should include relevant page addresses and screenshots.

We should always specify the URLs of pages where we want to implement new behavior or fix a bug. To ensure clarity, it is recommended that for each step in a user's behavior, the URL of the corresponding page be specified. 

For example: 

Unclear: "I go to the page for adding photos"

Clear: "I go to the URL somepage.com/add/photo to access the page for adding photos"

Providing the exact URL of a specific page ensures that the developer understands which page to implement new behavior on or fix a bug. This is especially important in cases where an application has multiple pages with similar functionalities.

If you want to describe a bug, it is crucial to always include a screenshot that clearly displays the issue and the page URL. This will assist developers and testers in quickly identifying and resolving the problem. 

When clicking the 'Preview' button on the 'Add New Post' page, there is no response. The expected behavior is to display a non-editable version of the text.

When describing a problem or bug, it is imperative to provide the URL of the page and, if possible, a screenshot that clearly shows the issue. This will ensure that the developer knows exactly where to locate the problem block and will allow for quicker resolution as "A picture is worth a thousand words".

For example: 

When clicking on the 'Preview' button on the 'Add New Post' page URL somepage.com/add/post, nothing happens. I expect to see the non-editable version of the typed text. Please see the attached screenshot with a red arrow pointing to the non-functional 'Preview' button. 

Rule 3: Describing hidden elements without distinct URL

Sometimes, it is necessary to describe the behavior of dropdown menus or animations that change their view, position or behavior after some user interactions, without changing the page's URL. In such cases, you can provide specifications as a clear list of steps from the user's perspective that lead to the expected behavior. Screenshots are also essential in such situations.

For instance, let's say we want to view the latest notifications in the expandable menu of the user profile. Initially, the description might be vague as follows:

I see a side menu and scroll the page down. In the lower block, I see the notifications list for my logged-in user. When I open the profile menu, I see the same list of notifications.

However, the above description lacks clarity and raises several questions such as where is the side menu displayed? What is the lower block, and how does one open the profile menu?

To fix this, we can provide a more detailed and refined description as follows:

I visit and log into the main page and click the arrow, as shown in the screenshot, to expand the right-side menu. Then I scroll the page down and locate the 'notifications' section, where I can view the latest notifications

Additionally, on the same page, I can see the profile menu located in the top-right corner as displayed in the screenshot. I click on the user avatar link, and I can access the notification list.

Notifications refer to text messages that may be sent by admins to all logged-in users.

Rule 4: Behaviors versus Technical Descriptions

It is important to avoid giving concrete technical instructions when writing specifications. Such instructions could be challenging for non-tech specialists who also work with specifications. Additionally, the developer might not find an optimal solution if the suggested method is not optimal. 

Consider the following highly technical specifications:

Add an “is_hidden” flag to the “photos” table to hide them on the main page when activated.

Apply “/[0-9]+/” regex to extract the page id from the link.

Use pagination with 20 limit and 10 offset.

Integrate the fancy.js library which allows uploading photos to the website.

Now, let's compare the above statements to their corresponding behaviors:

As an admin user, I can visit the oursite.com/photos/1 page and edit photo 1. On the edit page, there will be an "is visible" checkbox. When the checkbox is checked, the corresponding picture is visible on the "oursite.com" main page; if it's unchecked, it's hidden.

I can input a link in the form of "/photos/x333" or "/photos/abc3-45-3". By clicking the link, I expect to get the extracted page ID, which should only include numbers or 0

On the "/products" page, I see a list of products. If there are more than 20 products, I only see the first 20, ordered by name. The pagination block is visible, and I can navigate to the next 20 products.

.As an admin, I visit the "/admin/files" page where I can select the "upload" button. Upon clicking, I can select multiple photos from my local machine, and those files will appear in the main list on the "/files" page

Surely we want sometimes to describe technical details with useful hints, but why not using comments for that case to leave specs as "naive" as possible?

It is understandable that we sometimes need to describe technical details with useful hints. However, it is advisable to leave specifications as "naive" as possible. Technical details can be included in comments for those who need them.

Rule 5: Extensive and Precise Descriptions of All Possible User Interactions

When writing specifications, it is crucial to consider all possible user interactions instead of describing just one use case. Failing to do so can lead to misinterpretations and code rewrites. Here is an example to illustrate this point:

Lets imagine following specs:

I am a logged-in user and go to the page for adding a new article at somesite.com/articles/add. I see a form with a title, date, publication checkbox, text field, and save button (see the attached markup). When I click on the save button, I should see the published article on the main page in the news list.

While the above description is clear, the following use cases are missing:

  • What happens if the user doesn't fill in all field values or none, but hits the "save" button?
  • What happens if a non-logged-in user visits this page?
  • What if the user used too short a text (like 1 letter)?
  • What if the user didn't enable the "publication" checkbox?
  • What if the user used an incorrect date format or a future/past date?

To avoid such omissions, it is essential to think about both "happy" and "unhappy" cases when writing specifications. For example, consider the following tips:

  • Describe the behavior when unexpected data is entered into a form field, such as too large/short text, too big/small file, no value at all, or nothing selected in the dropdown.
  • Specify the behavior that occurs after pushing the "save" button, such as going to a success page and viewing the article.

  • Consider the case when a guest user visits a page that is intended for a logged-in user, and describe how to handle a situation where a guest user attempts to perform the same actions.

  • Clearly describe the differences in behavior between normal and advanced users, if it is important to the use case.

  • Specify how content is added to a new page, as it is typically added on an admin page. Describe the admin actions from the perspective of an admin user.

  • Ensure that users or admins can update and delete data, as this is often necessary. Consider using soft deletion to mark something as deleted instead of physically deleting it.

  • Consider whether posted data should appear immediately or after moderation from an admin. Determine whether admins should be notified about posted data or not.

Rule 6: Don't "Poison" Specifications with Unnecessary Information.

The specifications should be concrete and pragmatic. We describe only one feature/bug rather than giving as much “world” context as possible. Let’s have examples of wrong texts:

The specifications should be clear and concise, focusing on one feature or bug at a time. Avoid providing excessive background information.

For example, refrain from describing future intentions in the acceptance criteria, as it may not be relevant to the current task. Instead, provide a comment specifying a related task if necessary.

I see the list of uploaded images. Later this list will be moved to a separate page

Do not repeat requirements that have already been established in a previous task. For instance, if the images are cropped to a specific size, there's no need to mention it again unless it's directly related to the current task:

... I see the list of uploaded images. The images are cropped to the size 300x300 px by a media library (see task A for this)

Avoid mentioning features that are not yet implemented as if they already exist. For example

... I go the product page /product/1 and see the following data of product with id 1: title, image, description, price

Below I see the list of similar products which are recommended to the current one

instead of indicating a list of similar products as a part of the current task, phrase it as a static list of products that will eventually become a list of recommended products in the future.

Rule 7: Consider the testability of the requirements when drafting them

Rule 7 emphasizes the importance of writing requirements that can be tested not only by developers but also by testers. To achieve this, we have included an "Acceptance Criteria" section with a list of expectations. However, it's crucial to ensure that the expectations are testable

Let's examine some examples of non-testable requirements:

When I click on the "Save" button, nothing happens (The bug is reproducible sometimes, but I am not sure how)

This requirement is not testable since the tester cannot replicate the bug if they don't know the exact steps that cause it. In this case, it's important to add more information or find a way to reproduce the bug consistently.

When Google bot scans product pages, it should not find any missing pages

This requirement is not testable since the tester cannot trigger the Google bot. Instead, we should focus on the specific action that the tester can take, such as identifying a specific page that should not be missing

For example:

When I go to /old-product/1 and /old-product/2 (see the full list in the attached file), I should be redirected to /new-product/1 and /new-product/2 with the code 301.

By writing testable requirements, we increase the efficiency of testing and reduce the risk of overlooking critical issues."

Summary

Quality specifications are a crucial element of successful IT projects. A behavior-driven approach provides clear requirements for all project participants, including project managers, business owners, testers, and developers. This method reduces the time needed for clarifying specifications, minimizes the need for code adjustments, and streamlines the QA process.