Featured Webinar: Unveiling Parasoft C/C++test CT for Continuous Testing & Compliance Excellence | Watch Now

How to Write Test Cases for Software: Examples & Tutorial

Headshot of William McMullin, Solution Architect at Parasoft
May 27, 2021
10 min read

Writing test cases is paramount to software development. Test cases help software testers understand their test's requirements and scope. Read on to learn how to write proper test cases with automated testing tools from Parasoft.

How to write test cases might not seem like such an important part of development. But for a software tester to best perform their job, they need a crystal clear set of steps to follow and a clear definition of what is being tested.

Everyone from NASA and GE to enterprise-level corporations can benefit from teams operating at their best. Writing excellent test cases is just one more way to enhance team efficiency and efficacy and Parasoft is all about empowering teams to do just that.

In this blog, we cover the following topics related to how to write a test case:

  1. What is a test case?
  2. Test script vs. test case
  3. Different test case types
  4. How to write software test cases
  5. Standard test case format
  6. Test case writing best practices
  7. Test suite vs. test plan
  8. Test case writing tools

See how to create useful, reusable test cases with AI-enhanced test automation for easier API functional testing.

What Is a Test Case in Software?

A test case is exactly what it sounds like: a test scenario measuring functionality across a set of actions or conditions to verify the expected result. They apply to any software application, can use manual testing or an automated test, and can make use of test case management tools.

A key thing to remember when it comes to writing test cases is that they are intended to test a basic variable or task such as whether or not a discount code applies to the right product on an e-commerce web page. This allows a software tester more flexibility in how to test code and features.

Optimizing Unit and Regression Testing for Embedded Systems

Test Script vs. Test Case

The difference between test cases vs. test scripts should also be clarified. A test script is a short program meant to test certain functionality. A test case is a document with steps to be completed as planned out ahead of time.

Consider test cases as a meticulously planned trip and test scripts to be more like a quick trip to the grocery store.

Chart listing different types of test case purposes: left column shows functionality, unit, performance, database; right column shows user interface, integration, security, usability

Different Types of Test Cases

Test cases can measure many different aspects of code. The steps involved may also be intended to induce a Fail result as opposed to a positive expected result such as when a user inputs the wrong password on a login screen.

Some common test case examples would be the following:

Table showing common test case examples for functionality, security and usability

Test cases can be applied to any number of features found in any given software. Some of the most popular include:

A Popular Test Case Example

Test cases come in handy in a variety of software scenarios. Everything from banking to personal software requires a test case application. For example, if the goal is to have encrypted, sensitive data, the software needs to have features that work as intended.

But functional testing is just one aspect of writing a test case. Software testing should robustly challenge every aspect of the code from performance to compatibility to security. That’s why personal encryption software needs to be tested so thoroughly — especially when it comes to things like Web APIs.

infographic showing two people writing a test case amid code and computer related images

How to Write Software Test Cases

Writing test cases varies depending on what the test case is measuring or testing. This is also a situation where sharing test assets across dev and test teams can accelerate software testing. But it all starts with knowing how to write a test case effectively and efficiently.

Test cases have a few integral parts that should always be present in fields. However, every test case can be broken down into 8 basic steps.

Step 1: Test Case ID

Test cases should all bear unique IDs to represent them. In most cases, following a convention for this naming ID helps with organization, clarity, and understanding.

Step 2: Test Description

This description should detail what unit, feature, or function is being tested or what is being verified.

Step 3: Assumptions and Pre-Conditions

This entails any conditions to be met before test case execution. One example would be requiring a valid Outlook account for a login.

Step 4: Test Data

This relates to the variables and their values in the test case. In the example of an email login, it would be the username and password for the account.

Step 5: Steps to be Executed

These should be easily repeatable steps as executed from the end user’s perspective. For instance, a test case for logging into an email server might include these steps:

  1. Open email server web page.
  2. Enter username.
  3. Enter password.
  4. Click “Enter” or “Login” button.

Step 6: Expected Result

This indicates the result expected after the test case step execution. Upon entering the right login information, the expected result would be a successful login.

Step 7: Actual Result and Post-Conditions

As compared to the expected result, we can determine the status of the test case. In the case of the email login, the user would either be successfully logged in or not. The post-condition is what happens as a result of the step execution such as being redirected to the email inbox.

Step 8: Pass/Fail

Determining the pass/fail status depends on how the expected result and the actual result compare to each other.

Same result = Pass
Different results = Fail

Accelerate Software Testing by Sharing Test Assets Across Dev & Test Teams

Standard Unit Test Case Format

Each part of a well-written unit test will define several core aspects including:

  1. Functions performed by the test
  2. Data used in the test
  3. Expected result from the test execution
  4. Ensuring the test was executed in isolation from other parts of the codebase

It’s important to know that the standard format of well-written tests is composed of the following parts:

  • Meaningful test method name
  • Controlled data or mocks to be used for testing
  • Method or unit under test (the part of code we are testing)
  • Applying an assertion
  • Executing the unit test in isolation

screen capture of code for a well-written unit test case

Is There a Test Case Template?

As mentioned, there is a standard test case format. However, the test case template would likely vary from company to company and even from team to team. Instead, a test case template is the document with a list of test scenarios and subsequent test cases.

Quality Test Case Example

Though test cases will vary based on the type of testing and overall field of testing, building a quality test case comes down to those few reliable items above. Remember: the name of the test method must include the method or unit under test and what is the expected outcome.

It should also be noted that each unit should be tested in isolation. In this case, “isolation” means keeping tests focused as much as possible in order to execute only the piece of the application we are testing for.

This example comes from a banking-related test case:

Screen capture of code for a banking-related test case

With this method name, we know that this is a unit test that is:

  • Testing the method ‘isOverDrawn()’.
  • The balanced used for the controlled data was 500.
  • The expected result is true.

A meaningful method name allows anyone reviewing the results to understand what the unit test was testing for. Moreover, it signals the data to be tested, the expected result, and what was tested.

If the test fails, knowing the expected result is critical in allowing for easier troubleshooting and ensuring no regressions are introduced.

Test Case Data

The data used needs to be enough to execute the test. For unit testing, we want to make it as simple as possible to test the most basic unit of our application. The data could be as simple as making a string or object variable for which you can control the data. Or a mock framework can be used for the test if a dependency is not available or you need that dependency to be in a specific state.

Having just enough to test that one part if sufficient. You DO NOT need to configure every piece of the application for the test to run.

All of this affects how the unit test will behave since this is the data being used for unit test execution. As such, this part of unit testing is the most time consuming as it requires some understanding of the code you are testing to know what data to use for testing.

Keep it simple by using just the parts needed for the code being tested. Mocks are very useful in this phase as they allow you to control how methods from those objects will behave when interacting with your test.

For example, given the following data:

Screen capture of code showing how to control behavior of objects

We avoided the “real customer class” by using a mock for the “customer class” for testing isolation. We do not want to introduce nor configure another object for this test as it adds another layer of maintainability for that object, and it is not affecting the result of the method under test.

The next variable to be created is the “initial balance”—something known due to knowledge of the code. The next line shows the Account object being created along with the mock and the Initial Balance to prepare the method we are testing for with the data we just used.

So in this example, the account object is configured with the mock customer since we do not care about the customer object’s data and we passed an initial balance that we can control for our test.

The next line defines the input as the method under test requires a number to be used. We defined the “balance” to be used in the method we are testing for. Then the method is executed with the result of the method being stored in our variable for us to use later.

Applying an Assertion

Once the test can complete successfully (as in it runs from start to finish with no exceptions or errors), then it is time to apply an assertion to the unit test. Without the assertion, the unit test is meaningless since there is nothing you are enforcing to ensure it is working as intended.

Collecting coverage of what lines were executed does tell what was executed but it does not provide enough detail to determine the following:

  • If the code is behaving as expected.
  • If the code meets quality targets.
  • If the data returned is the expected data.

An assertion can be as basic as:

Screen capture of code showing an assertion

As long as the unit test contains one assertion that is checking the method under test result, this is a meaningful unit test.

Screen capture of code for a meaningful unit test with one assertion

By applying the standard format of unit test, a team can easily maintain, read, and/or update tests with more ease to readily see where more testing can be applied to the rest of the application.

infographic showing a team at work around an mega large monitor. Guy to left on smartphone, guy sitting on top of monitor working on laptop, girl on ladder drawing a bar chart on monitor with an oversized pencil, guy standing in front of monitor talking into a megaphone, girl to right of monitor taking notes.

What Are the Best Practices for Writing Quality Test Cases?

How to write effective tests and test cases can be streamlined over time. Some best practices include using strong titles, strong descriptions, and keeping the language concise and clear.

But you’ll also want to include preconditions, assumptions, and the expected results, too. All of this information is relevant for the software tester — especially when determining whether the test case should be a “pass” or a “fail” instead.

A cheat sheet for creating test cases that work well is as follows:

  • Keep things simple and transparent.
  • Make test cases reusable.
  • Keep test case IDs unique.
  • Peer review is important.
  • Test cases should have the end user or defined requirements in mind.
  • Specify expected results and assumptions.

Graph showing a test plan which includes test suites A, B and C

Simple, unique, specific, open to feedback, and focused on reusability: that’s the way of a great test case. For a more visual look at how to write a quality test case, check out Parasoft’s webinar on the subject.

Test Suite vs. Test Plan

The other aspect of a test case involves test suites and test plans. These differ in key ways and both are vital to accurate test case development.

Improve Unit Testing for Java With Automation

What Is a Test Suite?

A test suite comes into play for test cases as it relates to source code, the collection of dependencies, or the suite of tests to be performed on code. Test suites allow you to categorize test cases in ways that align with any analysis or planning needs.

This means that core software features might have their own test suite while another test suite is for a specific testing type such as smoke or security. Think of test suites as a bookshelf to organize your test cases on.

What Is a Test Plan?

In contrast, a test plan is more like the umbrella that stands over all of the test suites. If test cases are books and test suites are bookshelves, then test plans are the room that contains the bookshelf.

Generally, test plans are set up in terms of manual tests, automated tests, and a general format of how to go about testing. They’ll test the software from the foundation up utilizing test suites and test cases before implementing changes or adding new features.

Infographic showing guy in orange shirt and black pants sitting and working at a desk with a monitor.

Best Test Case Writing Tools

Parasoft generally develops its tools and suites with the “George Jetson” theory in mind. That is to say that we want our clients to be able to “press a button” and have everything taken care of. While this isn’t totally realistic, tools that have this focus on automation are the best to use when it comes to writing test cases.

Not only can they assist with automation, but they can help from the very beginning of development. After all, it’s too easy to get bogged down by small details or features. One might forget that software just has to function first. That’s where a Java unit testing tool like Parasoft Jtest comes in.

This tool allows beginners and experts alike to improve their unit testing skills more quickly, as well as the unit testing experience. After establishing a foundation, it executes the unit tests then guides the user to ensure that the tests are meaningful. When you can understand the kinds of things to look for in a test, test case writing becomes less intimidating.

Simplify API testing & boost software quality.

See test automation enhanced with AI & ML in action!