<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/property-based-testing-how-to-find-bugs-your-unit-tests-miss-kaogkw4ex" -->

---
title: Property-based testing: How to find bugs your unit tests...
description: Property-based testing checks that code satisfies general rules across many automatically generated inputs, rather than testing hand-picked examples. Using...
canonical: https://daily.dev/posts/property-based-testing-how-to-find-bugs-your-unit-tests-miss-kaogkw4ex
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Property-based testing: How to find bugs your unit tests miss | daily.dev
og:description: Property-based testing checks that code satisfies general rules across many automatically generated inputs, rather than testing hand-picked examples. Using...
og:url: https://daily.dev/posts/property-based-testing-how-to-find-bugs-your-unit-tests-miss-kaogkw4ex
og:image: https://api.daily.dev/og/posts/kAOGKW4ex.png
og:image:alt: Property-based testing: How to find bugs your unit tests miss
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Property-based testing: How to find bugs your unit tests miss

**[CircleCI](https://daily.dev/sources/circle)** · 16 min read · 0 upvotes · 0 comments

## Summary

Property-based testing checks that code satisfies general rules across many automatically generated inputs, rather than testing hand-picked examples. Using Python's Hypothesis library, a search-query normalizer that passes three unit tests fails an idempotence property: normalizing twice should equal normalizing once. Hypothesis finds that three consecutive spaces collapse to two spaces, then to one, because str.replace() only handles pairs. The fix uses a regex matching one or more spaces. Hypothesis defaults to 100 generated examples per test and can shrink failures to minimal counterexamples. Similar frameworks include fast-check for JavaScript/TypeScript and jqwik for Java, and tests can run in CircleCI alongside unit tests.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://circleci.com/blog/property-based-testing>

## Questions this post answers

### What is property-based testing and how is it different from unit testing?

Property-based testing checks whether code satisfies general rules, called properties, across many automatically generated inputs, instead of checking specific hand-picked examples against expected outputs. A framework like Hypothesis generates inputs such as empty lists, duplicates, or large collections, and checks whether each one satisfies the property, exposing edge cases unit tests might miss. The two approaches are complementary rather than replacements for each other.

_Developers weighing property-based versus example-based testing can find more comparisons on daily.dev._

### How does Hypothesis shrink failing test cases in Python?

Hypothesis automatically tries progressively simpler inputs that still reproduce a failure, a process called shrinking, so developers get a minimal reproducible counterexample instead of a large complicated one. For a string-normalization bug involving repeated spaces, Hypothesis reduced a complex failing string down to just a few characters, making the root cause of the bug easy to identify and fix.

_Anyone debugging flaky generated test failures can track Hypothesis tips and updates on daily.dev._

### Why would a string normalization function fail an idempotence test in Python?

A normalization function using str.replace() to collapse double spaces fails idempotence because a single pass doesn't fully collapse sequences of three or more consecutive spaces; it reduces them to two spaces, and a second pass is needed to get to one. The fix replaces the naive double-space replacement with a regular expression, r' +', that matches one or more consecutive spaces in a single pass.

_Developers hardening text-processing code against edge cases can follow more Python testing patterns on daily.dev._

## Similar posts on daily.dev

- [A testing conundrum](https://daily.dev/posts/a-testing-conundrum-3xscbuqqt) · Planet Python · 3 upvotes · 0 comments
- [Does your code match your spec?](https://daily.dev/posts/does-your-code-match-your-spec--beehfvwqo) · Kiro · 0 upvotes · 0 comments
- [Toward automated verification of unreviewed AI-generated code](https://daily.dev/posts/toward-automated-verification-of-unreviewed-ai-generated-code-iogcc4ffa) · Hacker News · 0 upvotes · 0 comments
- [The bug fix paradox: why AI agents keep breaking working code](https://daily.dev/posts/the-bug-fix-paradox-why-ai-agents-keep-breaking-working-code-7kgysrwe9) · Kiro · 5 upvotes · 0 comments
- [AI Agents Need These TypeScript Test Patterns](https://daily.dev/posts/ai-agents-need-these-typescript-test-patterns-qzble0pn8) · TypeScript.TV · 0 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#testing](https://daily.dev/tags/testing), [#cicd](https://daily.dev/tags/cicd), [#circleci](https://daily.dev/tags/circleci)

[View this post on daily.dev](https://daily.dev/posts/property-based-testing-how-to-find-bugs-your-unit-tests-miss-kaogkw4ex)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Property-based testing: How to find bugs your unit tests miss","url":"https://daily.dev/posts/property-based-testing-how-to-find-bugs-your-unit-tests-miss-kaogkw4ex","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/property-based-testing-how-to-find-bugs-your-unit-tests-miss-kaogkw4ex"},"datePublished":"2026-11-05T17:12:04.960Z","dateModified":"2026-11-05T17:16:13.877Z","description":"Property-based testing checks that code satisfies general rules across many automatically generated inputs, rather than testing hand-picked examples. Using...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/bf9575c49cb7a2f2bba2d6ee4986bb1c?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/bf9575c49cb7a2f2bba2d6ee4986bb1c?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"CircleCI","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"CircleCI","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/661fc536429943fdb5426b9f33fd8e3c","url":"https://daily.dev/sources/circle"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/property-based-testing-how-to-find-bugs-your-unit-tests-miss-kaogkw4ex","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python,testing,cicd,circleci","timeRequired":"PT16M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"CircleCI","item":"https://daily.dev/sources/circle"},{"@type":"ListItem","position":3,"name":"Property-based testing: How to find bugs your unit tests miss"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/property-based-testing-how-to-find-bugs-your-unit-tests-miss-kaogkw4ex#faq","mainEntity":[{"@type":"Question","name":"What is property-based testing and how is it different from unit testing?","acceptedAnswer":{"@type":"Answer","text":"Property-based testing checks whether code satisfies general rules, called properties, across many automatically generated inputs, instead of checking specific hand-picked examples against expected outputs. A framework like Hypothesis generates inputs such as empty lists, duplicates, or large collections, and checks whether each one satisfies the property, exposing edge cases unit tests might miss. The two approaches are complementary rather than replacements for each other. Developers weighing property-based versus example-based testing can find more comparisons on daily.dev."}},{"@type":"Question","name":"How does Hypothesis shrink failing test cases in Python?","acceptedAnswer":{"@type":"Answer","text":"Hypothesis automatically tries progressively simpler inputs that still reproduce a failure, a process called shrinking, so developers get a minimal reproducible counterexample instead of a large complicated one. For a string-normalization bug involving repeated spaces, Hypothesis reduced a complex failing string down to just a few characters, making the root cause of the bug easy to identify and fix. Anyone debugging flaky generated test failures can track Hypothesis tips and updates on daily.dev."}},{"@type":"Question","name":"Why would a string normalization function fail an idempotence test in Python?","acceptedAnswer":{"@type":"Answer","text":"A normalization function using str.replace() to collapse double spaces fails idempotence because a single pass doesn't fully collapse sequences of three or more consecutive spaces; it reduces them to two spaces, and a second pass is needed to get to one. The fix replaces the naive double-space replacement with a regular expression, r' +', that matches one or more consecutive spaces in a single pass. Developers hardening text-processing code against edge cases can follow more Python testing patterns on daily.dev."}}]}
```

