Property-Based Testing: from Particulars to Generalities

Overview

Property-based testing (PBT) is an approach to designing tests, in which attention is shifted from checking specific inputs and expected outputs to whether the results satisfy more general properties of a system or so-called invariants.

Unlike with traditional example-based approach, where we explicitly state specific examples of input data and their expected results, the idea with PBT is to specify general properties that should hold for all valid input data. The data generator creates random input data, and the test checks that the properties are preserved for each generated instance.

This approach is so called because it focuses on those characteristics of the system that need to be fulfilled whatever the input. Such characteristics are immutable, meaning the system has unchanging properties regardless of what data it uses.

Originally intended for use by developers in unit tests, the PBT approach can also be applied at a higher level to design and execute system tests.

Why Use PBT?

Below are the main advantages and disadvantages of PBT to help you decide on when and how to use this approach effectively.

Advantages

  1. Broader Test Coverage – PBT generates a wide variety of test cases including edge cases and unexpected inputs, which increases the chance of discovering hard-to-find bugs. It ensures the system behaves correctly over a broader input range, instead of being tuned to work only on carefully constructed examples.
  2. Automation of Test Case Creatio – PBT saves time and reduces human effort in writing specific test cases because test inputs are automatically generated. This allows testers to focus on finding meaningful properties rather than drawing inputs manually.
  3. Better Test Qualit – PBT encourages thinking on invariants and critical properties of the system, resulting in a deeper understanding of its requirements and behavior. Properties abstract away implementation details, which leads to better long-term maintainability of the tests.
  4. Generic and Reusable – Properties are reusable across multiple versions of a system, unlike example-based tests that may become outdated.

Disadvantages

  1. Difficulty in Defining Properties – Defining effective properties requires a deep understanding of the system and may be challenging for even experienced testers who are new to this approach. Besides, in some systems, it may be hard to generalize properties that capture the expected behavior completely (e.g. systems with complex GUI interactions or subjective UX).
  2. Performance Concerns – Generating and testing thousands of inputs can take longer than example-based tests, especially if the system has significant computational overhead or the tests run at GUI level.

Real-World Examples

Since PBT is a vigorous testing technique that verifies the generic properties or behaviors of the system under test rather than checking specific examples, its features make it suitable to be applied to both APIs and full web applications, and have particular advantages in testing quality and coverage improvement.

When testing API endpoints, PBT helps clearly define the properties based on API design conventions to validate its robustness because these properties are universal and apply to all APIs even when the business logic rules are not available.

In contrast, API testing usually deals with structured data and well-defined contracts, web applications have to cope with a variety of user interactions, browser environments, and input variations. With PBT applied, we are able to reproduce such scenarios by generating meaningful combinations of inputs in order to highlight rendering issues, bugs related to input handling, and unpredicted behavior coming from end users. It makes the web applications perform reliably under real-life conditions.

Let’s explore a few practical scenarios and define properties for them.

API Testing

Scenario 1: POST Endpoint

Test a POST /users endpoint that creates a user.

Properties

  1. Required fields must be validated.
  2. A valid request returns a 201 Created status code.
  3. The created user can be fetched with the returned ID.
  4. The API should not allow duplicate entries if uniqueness constraints exist.

Scenario 2: GET Endpoint

Test a GET /users/{id} endpoint that retrieves a user by ID.

Properties

  1. The response contains only the fields allowed by the API schema.
  2. Fetching the same user multiple times returns the same result (idempotency).
  3. Fetching a non-existent user returns 404 Not Found status code.

Scenario 3: PUT/PATCH Endpoint

Test a PUT /users/{id} or PATCH /users/{id} endpoint for updating user data.

Properties

  1. A valid request returns 200 OK or 204 No Content status code.
  2. Only the updated fields are modified; others remain unchanged.
  3. Immutable fields (e.g., id, dateCreated) should not be updatable.
  4. The state after an update should match the result of a GET request for the same resource.
  5. Repeated updates with the same payload should have no additional side effects (idempotency).
  6. Updating a non-existent user returns 404 Not Found status code.

Scenario 4: DELETE Endpoint

Test a DELETE /users/{id} endpoint for deleting a user.

Properties

  1. Deleted user cannot be retrieved.
  2. Deleting the same user multiple times should have no additional effects after the first deletion (idempotency).
  3. Deleting a non-existent user returns 404 Not Found status code.

We can also use a scenario common for all endpoints:

Scenario 5: API Security and Other Limitations

Test API authorization and other constraints.

Properties

  1. Only authorized users can access protected endpoints.
  2. API calls with payloads exceeding a size limit should be rejected.
  3. API calls exceeding rate limits should be rejected with 429 Too Many Requests status code and Retry-After header.
  4. API endpoints that modify data should handle concurrent requests gracefully and respond with 409 Conflict status code if race conditions occur.

Banking Application

Scenario 1: Funds Transfer

Test a feature that allows a user to transfer money from one account to another.

With traditional example-based testing, one would write specific test cases like:

  1. Transfer $100 from source account to destination account, where source account has $500 (should pass).
  2. Transfer $0 from source account to destination account (should fail).
  3. Transfer a negative amount (should fail).

With PBT, instead of specifying concrete data inputs, we define properties that the system should always satisfy. Then, we use a random data generator or a property-based testing library to generate a wide range of input data automatically.

Properties

  1. The total balance across both accounts remains unchanged after a valid transfer.
  2. Transfers with negative or zero amounts are invalid.
  3. The transfer fails if the amount exceeds the source account balance

Scenario 2: ATM Withdrawal

Withdraw money from an account via an ATM.

Properties

  1. The balance must decrease by the withdrawn amount plus any fees.
  2. The withdrawal amount cannot exceed the daily limit or available account balance.

Scenario 3: Transactions and Statements

Generate a statement of transactions for a given period.

Properties

  1. The closing balance equals the opening balance plus all credits minus all debits.
  2. Transactions are sorted by date in descending order.

E-Commerce Platform

Scenario 1: Searching and Filtering

Search for products and filter product catalog by various criteria.

Properties

  1. Every product in the result contains the search query in its name, description, or tags.
  2. If a category filter is applied, the result products belong to the selected category.
  3. If a price range is applied, the result product prices are within the range.
  4. If a rating range is applied, the result product ratings are within the range.
  5. Each product in the result satisfies both the search query and all applied filters simultaneously.
  6. Results are sorted correctly according to the selected sort criteria and order.
  7. If pagination is used, the products returned on each page are unique.
  8. Across all pages, the total products equal the filtered search result set size.
  9. Repeating the same query and filter combination on the same dataset produces identical results.

Scenario 2: Checkout

Test the calculation of total price at checkout, including taxes, discounts, and shipping fees.

Properties

  1. The total price should always be non-negative.
  2. Applying a discount cannot increase the total price.
  3. Adding an item to the cart increases or maintains the total price.
  4. Removing an item decreases or maintains the total price.
  5. Changing currency during checkout should convert the total price correctly.
  6. Updating items in the cart during checkout should keep the total price consistent.
  7. Shipping fees should correctly calculate based on weight, size, or destination.

Social Media Platform

Scenario 1: Posting and Commenting

Test that users can post and comment on other users’ posts.

Properties

  1. Posts and comments must adhere to length restrictions.
  2. Comments should maintain a hierarchical structure (parent-child relationships) and be displayed in the correct order.
  3. Adding or removing reactions (likes, emojis) must keep the counts accurate.
  4. The number of likes or reactions on a post should always be a non-negative integer.
  5. A post deleted by a user should not be retrievable via API or GUI.

Scenario 2: Privacy and Security

Test privacy and security settings.

Properties

  1. Privacy settings (e.g., public, friends-only) must restrict access to posts as configured by the user.
  2. A user’s feed should only contain posts they are authorized to see (e.g., posts from followed users).
  3. Posts from blocked users should not appear in the feed.

PBT Tools

When adopting Property-Based Testing, selecting the right tool is crucial for maximizing its benefits. For .NET and C# developers, FsCheck is a widely used library that integrates seamlessly with NUnit and xUnit, enabling expressive and powerful test generation. Another strong option is CsCheck, designed for high-performance PBT in C#.

In the JavaScript and TypeScript ecosystem, fast-check is the most popular choice, offering robust generators and built-in Jest compatibility, making it easy to incorporate into web application testing. JSVerify is another alternative that provides a functional approach to defining properties.

Beyond JavaScript and .NET, other notable PBT tools making property-based testing accessible across a wide range of programming languages include Hypothesis for Python—which integrates seamlessly with pytes—and QuickCheck for Haskell—the original PBT library that inspired many others.

These tools help automate test case generation, uncover hidden edge cases, and improve test coverage, making them valuable additions to any modern testing strategy.

Conclusion

The examples we reviewed illustrate how PBT can be integrated into real-world scenarios, ensuring scalability and reliability in modern software systems. By adopting this approach, teams can enhance their testing strategies, ultimately delivering higher-quality software to users.

Picture of Yuriy Marushchenko

Yuriy Marushchenko

With over two decades as a software quality engineer, Yuriy holds a degree in medical engineering. This academic foundation has guided his career, ensuring a focus on seamlessly functioning software. Beyond the tech realm, Yuriy's interests span learning foreign languages, astronomy and deep space exploration, taking leisurely walks with a camera, and enjoying the rhythms of electronic music.

Free Consultation

Sign up for a FREE consultation with one of Trailhead's experts.

"*" indicates required fields

This field is for validation purposes and should be left unchanged.

Related Blog Posts

We hope you’ve found this to be helpful and are walking away with some new, useful insights. If you want to learn more, here are a couple of related articles that others also usually find to be interesting:

Our Gear Is Packed and We're Excited to Explore With You

Ready to come with us? 

Together, we can map your company’s software journey and start down the right trails. If you’re set to take the first step, simply fill out our contact form. We’ll be in touch quickly – and you’ll have a partner who is ready to help your company take the next step on its software journey. 

We can’t wait to hear from you! 

Main Contact

This field is for validation purposes and should be left unchanged.

Together, we can map your company’s tech journey and start down the trails. If you’re set to take the first step, simply fill out the form below. We’ll be in touch – and you’ll have a partner who cares about you and your company. 

We can’t wait to hear from you! 

Montage Portal

Montage Furniture Services provides furniture protection plans and claims processing services to a wide selection of furniture retailers and consumers.

Project Background

Montage was looking to build a new web portal for both Retailers and Consumers, which would integrate with Dynamics CRM and other legacy systems. The portal needed to be multi tenant and support branding and configuration for different Retailers. Trailhead architected the new Montage Platform, including the Portal and all of it’s back end integrations, did the UI/UX and then delivered the new system, along with enhancements to DevOps and processes.

Logistics

We’ve logged countless miles exploring the tech world. In doing so, we gained the experience that enables us to deliver your unique software and systems architecture needs. Our team of seasoned tech vets can provide you with:

Custom App and Software Development

We collaborate with you throughout the entire process because your customized tech should fit your needs, not just those of other clients.

Cloud and Mobile Applications

The modern world demands versatile technology, and this is exactly what your mobile and cloud-based apps will give you.

User Experience and Interface (UX/UI) Design

We want your end users to have optimal experiences with tech that is highly intuitive and responsive.

DevOps

This combination of Agile software development and IT operations provides you with high-quality software at reduced cost, time, and risk.

Trailhead stepped into a challenging project – building our new web architecture and redeveloping our portals at the same time the business was migrating from a legacy system to our new CRM solution. They were able to not only significantly improve our web development architecture but our development and deployment processes as well as the functionality and performance of our portals. The feedback from customers has been overwhelmingly positive. Trailhead has proven themselves to be a valuable partner.

– BOB DOERKSEN, Vice President of Technology Services
at Montage Furniture Services

Technologies Used

When you hit the trails, it is essential to bring appropriate gear. The same holds true for your digital technology needs. That’s why Trailhead builds custom solutions on trusted platforms like .NET, Angular, React, and Xamarin.

Expertise

We partner with businesses who need intuitive custom software, responsive mobile applications, and advanced cloud technologies. And our extensive experience in the tech field allows us to help you map out the right path for all your digital technology needs.

  • Project Management
  • Architecture
  • Web App Development
  • Cloud Development
  • DevOps
  • Process Improvements
  • Legacy System Integration
  • UI Design
  • Manual QA
  • Back end/API/Database development

We partner with businesses who need intuitive custom software, responsive mobile applications, and advanced cloud technologies. And our extensive experience in the tech field allows us to help you map out the right path for all your digital technology needs.

Our Gear Is Packed and We're Excited to Explore with You

Ready to come with us? 

Together, we can map your company’s tech journey and start down the trails. If you’re set to take the first step, simply fill out the contact form. We’ll be in touch – and you’ll have a partner who cares about you and your company. 

We can’t wait to hear from you! 

Thank you for reaching out.

You’ll be getting an email from our team shortly. If you need immediate assistance, please call (616) 371-1037.