What is a test case? Top tips to Write Test Cases in Software Testing.

What is a Test Case?

A test case is a set of detailed instructions or steps used to verify that certain software, module or specific software functionality works as expected. They are usually crafted specifically for testing scenarios to ensure that software meets its specific requirements. Within software companies this is typically done by a dedicated testing team or development team, but that is not limited to only those. Ineffective test cases could be a source for bug slippage through the cracks and eventually bugs appearing in production. Therefore, writing good quality test cases is crucial for application robustness and successful software development lifecycle (SDLC). This blog article covers types of test cases, test case structure, best practices and the importance of test case management.

How is it Different from Test Plan?

A test plan refers to a broader strategy and approach for testing a software system or application, including objective, scope, resources and timelines. Typical information that the test plan contains: number of tests, purpose of each test, required tools, etc. A test plan is a high-level document containing project's overall testing approach, whereas test case refers to detailed step-by-step instructions to execute specific test scenarios. In essence, while the test plan provides the overarching framework and objectives for testing, a test case provides the specific procedures and details necessary to execute individual tests.

Why Write Test Cases?

When you look at it from the outside, it might seem like testing is just using the software, but that's not the case. While the main goal of testing is to see if the software works, there are many benefits to writing detailed test cases:

  • Test cases bring structure and stability to the testing process. If test cases are written well, they can be executed by a wider portion of the team, allowing even those with no prior knowledge to perform testing.

  • Helps to think through details. When the author is writing a test it helps to think through software functionality very deeply, allowing to find areas of oversight before they become too costly to fix.

  • Documents how the system should work. They are a good source of truth for how a software or a specific feature should work.

  • Reduces software maintenance costs. Test cases bring predictable and repeatable layers to the testing process which helps to find bugs early, therefore reducing the costs associated with bug fixing and software support. Which also means that higher quality products result in more satisfied customers.

Types of Test Cases

Understanding types of test cases can help understand what kind of aspects should be touched in the test case. There are many different ways to categorize test cases. One way, is to categorize them by testing approach and style:

  • Positive testing. This is known as happy-path testing. In this type only a good set of values is checked. In other words, the application is tested against the valid input data. The purpose of this is to understand whether the software does what it is supposed to do. For example, if we have an input form with valid login credentials we should be logged in.

  • Negative testing. This is also known as error path testing. The purpose of this is to identify bugs where improper data sets were used. For example, in input form, if we are only allowed to enter letters and numbers, we should not be able to input special characters, or at least we should get a warning.

  • Destructive testing. This type of software testing is designed to identify software failures when a system is essentially broken or exposed to extreme conditions. The purpose of destructive testing is to identify potential system failures before they occur on the user side. For example, this would be trying to simulate a hacking attempt by trying to inject JavaScript with malicious intent into a login form.

Another way, is to set them apart by objective:

  • Functional testing. This check whether the software conforms to software requirements and specifications

  • Usability testing. This checks end-user experience and general ease of usage.

  • Performance testing. This checks how software handles higher workloads.

  • Regression testing. Check whether recent code changes did not introduce any side-effects in already existing software functionality.

  • UI testing. Checks whether the visuals are rendered correctly, the user interface functions correctly and that the appearance of the application is correct.

  • User acceptance testing. This verifies that an application satisfies its business requirements before users accept it. These determine whether users accept or reject the output produced by a particular system before release to production.

  • Security testing. Checks whether the data is protected and other security aspects are taken care of. Their primary focus is to identify weaknesses, vulnerabilities and security risks. Also, they verify that certain types of external attacks can be prevented or handled with minimal consequences.

When to Write Test Cases?

There are a few different approaches when test cases are written. This depends on the size of the team, product scope and development process.

  • Before development. With this approach test cases are written before any coding is done. Main advantage of this is that this helps to understand and identify key requirements before any development is made.

  • After development. Test cases are written after developing software or a feature. This makes writing test cases easier as the tested system might be already there. But the main disadvantage of this is that it is not very efficient time wise.

  • During development. With this approach test cases are written during development in parallel. Main advantage is more efficiency time wise and higher degree of collaboration between the team.

What is The Test Case Structure?

The test case documentation typically includes all the information required to run and analyze the test. Usually, test case structure will differ between organizations, but majority will include at least:

  • Test ID. The unique identifier can be expressed as a number, but will typically be combinations of letters and numbers. The main purpose of the test ID is to help track it more efficiently and to provide traceability. If a company is using some test management system this is typically assigned automatically.

  • Name. This is self-explanatory. But names should always convey key functionality that is being tested and modules names where the tested functionality appears in.

  • Preconditions. This section defines what the system initial state should look like before running the test. For example, this could indicate what kind of data should exist on the server, what kind of user access rights the tester should have and what kind of environment should the tester use and on what kind of system the test shall be run (for example Browser/Os). This section can be very important as an incorrect initial system state can be a precursor for an incorrectly executed test case.

  • Description. This section should provide more information about the test case to the tester.

  • Test Steps. This is the most important part of the test case. It contains the sequence of actions the tester must perform to achieve desired result. It is important to note that steps should be very clear, descriptive and easy to understand. They should contain the least amount of assumptions and uncertainties.

  • Expected Results. This section should convey information about what kind of output from the system is expected after the test step was executed. There can be two different approaches to writing this section. First, is to have one expected result for all previous steps. Another one, would be to have expected results for each corresponding test step.

  • Test Data. It can be required to input certain data into the system. Or the tester will need to modify the system in a certain way during the test. Therefore, the test case could have a specific section for that. But it is important to note, that this section may be combined with preconditions/description/test steps sections.

  • Pass/Fail determination. It is good for test cases to have a section for marking down the outcome of each step. Essentially, if the actual result matches the expected result, the test passes. If not, the test fails.

  • Postconditions. This section includes details and actions to perform after the test completes. It serves the purpose of putting the system in the initial state. Postconditions section can be very useful for automated testing as it can fill up the database with unnecessary data very quickly.

By adhering to the sections outlined above, organizations can stick to the standard of writing their software tests. This is not an exhaustive list, as there are other ways to structure a test case. Therefore, any organization employing any structure should regularly review and maintain their testing processes and standards used. A well defined test case reduces time needed for testing and reduces the probability of undetected bugs slipping through.

Test Case Writing: Tips

Good quality test cases are crucial for all software development life cycle (SDLC). As test cases are essential for verification of functionality of the software application and its compliance with requirements and specifications. A few essential steps are important to understand before writing a test case:

  1. Use a descriptive clear title. It is a good practice to name the test case along the same lines as the software component or functionality that is being tested.

  2. Include a description. It is important that the person who will be performing the tests – will understand them.

  3. Include Preconditions. When executing tests, correct initial conditions can prevent false-negatives. If the system is in the wrong state before the test starts it can lead to unexpected and unpredictable results. Therefore, the tested system should always be put into a known state.

  4. Make sure test steps are clear and precise. The test case steps should include necessary data and actions on how to execute the test. It should not contain any ambiguity. Ambiguity in the test case can lead a person executing the test into an unknown path which would make test case execution almost worthless. Another important point here, is that the test case should be written in such a way that anyone without great deal of experience of using the software could be able to execute it.

  5. Make sure the expected result is clear. This section should tell exactly what kind of output should the tester expect from the system. It is a good practice to include screenshots here and allow quick verification of software functionality.

  6. Make it repeatable and reusable. It is always a good practice to make test cases reusable as this provides long-term value to the whole project team. For example, if the test case needs to verify a changing dataset, the test case author could write some steps as if they were an interpolated string, such that the test step does not change, but the test data changes.

By following principles outlined above a test case author can have a good start for their test case writing.

Test Case Writing: An Example

This section of the blog article provides a simple example of writing a test case. Let's imagine we have a basic calculator application. And we are tasked to write a couple of test case for the functionality of it: one for subtraction by zero, and another for division by zero. Then the first test case could look like as follows:

Title: Operations with Zero (Subtraction)

Description: Test case verifies that subtraction by zero works correctly. This is a functional test case – it verifies that features work as expected.

Precondition: Have no input present in the calculator

Test Steps:

  1. Enter 1

  2. Click subtraction operator –

  3. Enter 0

  4. Click evaluation operator =

Expected Result: Verify that result is 1

Another example would be a test case for calculator division by zero. From the requirement we know that once division by zero is performed, it should display ‘Error!’, therefore let’s write another test case for this:

Title: Operations with Zero (Division)

Description: Test case verifies that division by zero work correctly. This is a functional test case – it verifies that features work as expected.

Precondition: Have no input present in the calculator

Test Steps:

  1. Enter 1 / 0

  2. Click evaluation operator =

Expected Result:

  1. Verify that screen does not show Infinity

  2. Verify that screen indicates Error!

Test Case Management

As the scope of a software increases, so does the scale of its test cases. The more software functionality is added, the more it will have to be tested. Moreover, not only new functionality will have to be tested, but there will also be a need for regression testing. Which can make testing the whole software development process bottleneck. For small companies with small test suites using spreadsheets and text files can work at first, but eventually this can result in the boiling frog phenomenon.

Test management tools can help organizations track and update their tests as needed. There are many options for test management tools. Ultimately, the best option is one that fits the process, workflows and has multiple integrations. Test case creation and management tools can significantly improve the quality of testing. When everything is organized, easy to build on, the efficiency of the testing process increases.

A good tool for creating and managing test scenarios and test cases should include:

  • Convenient and extensive text editing capabilities

  • Attachment support

  • Ability to organize test cases according to different categories of testing

  • Good integration support with task management systems

  • Automatic ability to include testing results to reports

  • Good data visualization via different testing dashboards.

  • Integration with automation scripts

One of the tools that provide all of the above is MatrixALM. It provides a robust, multi-layered platform to manage both verification and validation testing. It integrates seamlessly with Jira Clouds, making it easy to add and link Jira tickets to executed test cases. Also, our Agile Sync module provides the ability to keep some sources of truth outside of Matrix Requirements that can be synchronized. MatrixSDK provides ability to integrate various testing automation frameworks and allows teams to create their own dashboards.

Conclusion

Writing good and effective test cases is both an art and a science. It requires a keen eye for detail and a good understanding of the product. As mentioned earlier, a good test case is descriptive, clear, concise and without much ambiguity. MatrixALM with its numerous integrations provides a convenient platform for writing, organizing and managing your test cases. If you would like to learn more, please do not hesitate to book a demo!

About the Author
Ignas Žakaitis
Software Testing Engineer