<div align="center">
# 🔍 pytest-deepassert
</div>
<div align="center">
[](https://pypi.org/project/pytest-deepassert/)
[](https://pypi.org/project/pytest-deepassert/)
[](https://opensource.org/licenses/MIT)
[](https://pepy.tech/project/pytest-deepassert)
**Enhanced pytest assertions with detailed diffs powered by DeepDiff**
*Stop hunting through massive data dumps. Get precise, readable assertion failures.*
</div>
---
## Table of Contents
- [Why pytest-deepassert?](#why-pytest-deepassert)
- [How it works](#how-it-works)
- [Installation](#installation)
- [Key Features](#key-features)
- [Comparison with Standard Assertions](#comparison-with-standard-assertions)
- [Usage](#usage)
- [Configuration](#configuration)
- [API Reference](#api-reference)
- [Limitations](#limitations)
- [License](#license)
---
## What is it for?
When testing that one complex data structure equals another, you may have situations when only some small details differ, but it is really hard to see which ones because of the cluttered comparison report. That's when `pytest-deepassert` helps:
- **Quicker identification** of differences in large & nested objects
- **Focused output** that highlights what matters
- **Direct navigation** to specific changes
- **Structured diffs** for complex data
If you've ever struggled with understanding **WHAT EXACTLY** is mismatching in your `assert a == b` statement, `pytest-deepassert` is what you need!
## How it works
`pytest-deepassert` is a pytest plugin built on powerful [`deepdiff`](https://github.com/seperman/deepdiff) library. It provides **clear, detailed difference reports** for various data types:
- **Basic types**: `int`, `string`, `float`, `bool`
- **Collections**: `dict`, `list`, `tuple`, `set`, `frozenset`
- **Advanced types**: `OrderedDict`, `NamedTuple`, custom objects
- **Smart helpers**: Works with `pytest.approx()`, `mock.ANY`, and your custom comparators
## 🚀 Installation
### From PyPI (Recommended)
```bash
pip install pytest-deepassert
```
### From Source
```bash
git clone https://github.com/alexkuzmik/pytest-deepassert.git
cd pytest-deepassert
pip install -e .
```
**Requirements**: Python 3.8+ and pytest 6.0+
## ✨ Key Features
### **Precise Error Location**
- Pinpoints **exact paths** where differences occur
- No more hunting through massive data dumps
- Shows **specific field names** and **array indices**
### **Clear Change Description**
- Shows `left value` → `right value` for each difference
- Categorizes changes (values changed, items added/removed)
- **Human-readable** change descriptions
### **Smart Comparison Helpers**
- Works seamlessly with `pytest.approx()`, `mock.ANY`
- Supports **custom comparison helpers**
- Handles complex nested structures intelligently
### **Zero Configuration**
- **Just install and it works** - no setup required
- Can be disabled with `--no-deepassert` flag
- **Drop-in replacement** for standard assertions
---
## 📊 Comparison with Standard Assertions
> **TL;DR**: Standard pytest assertions work great for simple cases, but `pytest-deepassert` provides enhanced clarity for complex data structures.
### Example 1: Complex Dictionary Comparison
Consider this realistic test with nested dictionaries:
<details>
<summary><strong>Click to see the test code</strong></summary>
```python
import pytest
from unittest.mock import ANY
def test_user_profile_comparison():
expected = {
"user": {
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"preferences": {
"theme": "dark",
"notifications": True,
"language": "en"
},
"metadata": {
"created_at": ANY, # We don't care about exact timestamp
"last_login": "2023-12-01",
"login_count": 42,
"score": pytest.approx(85.5, abs=0.1) # Approximate float comparison
}
},
"permissions": ["read", "write", "admin"]
}
actual = {
"user": {
"id": 123,
"name": "Jane Doe", # Different name
"email": "jane@example.com", # Different email
"preferences": {
"theme": "light", # Different theme
"notifications": True,
"language": "es" # Different language
},
"metadata": {
"created_at": "2023-01-01T10:30:00Z", # This will match ANY
"last_login": "2023-11-30", # Different date
"login_count": 45, # Different count
"score": 85.52 # Close enough to match approx
}
},
"permissions": ["read", "write", "admin", "delete"] # Extra "delete" permission
}
assert expected == actual
```
</details>
#### 📄 **Standard pytest output**
<details>
<summary><strong>Click to see the standard output</strong></summary>
```
example_test1.py::test_user_profile_comparison FAILED
======================================== FAILURES ========================================
_________________________ test_user_profile_comparison _________________________
example_test1.py:45: in test_user_profile_comparison
assert expected == actual
E AssertionError: assert {'user': {'id': 123, 'name': 'John Doe', 'email': 'john@example.com', 'preferences': {'theme': 'dark', 'notifications': True, 'language': 'en'}, 'metadata': {'created_at': <ANY>, 'last_login': '2023-12-01', 'login_count': 42, 'score': 85.5 ± 0.1}}, 'permissions': ['read', 'write', 'admin']} == {'user': {'id': 123, 'name': 'Jane Doe', 'email': 'jane@example.com', 'preferences': {'theme': 'light', 'notifications': True, 'language': 'es'}, 'metadata': {'created_at': '2023-01-01T10:30:00Z', 'last_login': '2023-11-30', 'login_count': 45, 'score': 85.52}}, 'permissions': ['read', 'write', 'admin', 'delete']}
E
E Differing items:
E {'permissions': ['read', 'write', 'admin']} != {'permissions': ['read', 'write', 'admin', 'delete']}
E {'user': {'email': 'john@example.com', 'id': 123, 'metadata': {'created_at': <ANY>, 'last_login': '2023-12-01', 'login_count': 42, 'score': 85.5 ± 0.1}, 'name': 'John Doe', ...}} != {'user': {'email': 'jane@example.com', 'id': 123, 'metadata': {'created_at': '2023-01-01T10:30:00Z', 'last_login': '2023-11-30', 'login_count': 45, 'score': 85.52}, 'name': 'Jane Doe', ...}}
E
E Full diff:
E {
E 'permissions': [
E 'read',
E 'write',
E 'admin',
E - 'delete',
E ],
E 'user': {
E - 'email': 'jane@example.com',
E ? ^ -
E + 'email': 'john@example.com',
E ? ^^
E 'id': 123,
E 'metadata': {
E - 'created_at': '2023-01-01T10:30:00Z',
E + 'created_at': <ANY>,
E - 'last_login': '2023-11-30',
E ? ---
E + 'last_login': '2023-12-01',
E ? +++
E - 'login_count': 45,
E ? ^
E + 'login_count': 42,
E ? ^
E - 'score': 85.52,
E ? ^
E + 'score': 85.5 ± 0.1,
E ? ^^^^^^
E },
E - 'name': 'Jane Doe',
E ? ^ -
E + 'name': 'John Doe',
E ? ^^
E 'preferences': {
E - 'language': 'es',
E ? ^
E + 'language': 'en',
E ? ^
E 'notifications': True,
E - 'theme': 'light',
E ? ^^^^^
E + 'theme': 'dark',
E ? ^^^^
E },
E },
E }
```
</details>
#### ✨ **With pytest-deepassert** (with `pytest -vv`)
```
example_test1.py::test_user_profile_comparison FAILED
======================================== FAILURES ========================================
_________________________ test_user_profile_comparison _________________________
example_test1.py:45: in test_user_profile_comparison
assert expected == actual
E assert
E DeepAssert detailed comparison:
E Item root['permissions'][3] ("delete") added to iterable.
E Value of root['user']['name'] changed from "John Doe" to "Jane Doe".
E Value of root['user']['email'] changed from "john@example.com" to "jane@example.com".
E Value of root['user']['preferences']['theme'] changed from "dark" to "light".
E Value of root['user']['preferences']['language'] changed from "en" to "es".
E Value of root['user']['metadata']['last_login'] changed from "2023-12-01" to "2023-11-30".
E Value of root['user']['metadata']['login_count'] changed from 42 to 45.
E
E [... standard pytest diff continues below ...]
```
### 🎯 **Key Improvements**
| Feature | Standard pytest | pytest-deepassert |
|---------|----------------|-------------------|
| **Smart filtering** | Shows all field comparisons | ✅ **Ignores `created_at`** (matches `ANY`) |
| **Precision** | Comprehensive diff coverage | ✅ **Ignores `score`** (within `pytest.approx` tolerance) |
| **Focus** | Complete context provided | 🎯 **Highlights actual differences** |
| **Format** | String-based comparison | 📋 **Structured, categorized output** |
### 📋 Example 2: Smart Comparison Helpers
`pytest-deepassert` seamlessly handles special comparison helpers:
<details>
<summary><strong>Click to see the test code</strong></summary>
```python
import pytest
from unittest.mock import ANY
def test_with_special_comparisons():
expected = {
"timestamp": ANY, # We don't care about exact timestamp
"value": pytest.approx(3.14159, abs=0.001), # Approximate float comparison
"metadata": {
"version": "1.0.0",
"debug": False
}
}
actual = {
"timestamp": "2023-12-01T10:30:00Z",
"value": 3.14160, # Close enough
"metadata": {
"version": "1.0.1", # Different version
"debug": False
}
}
assert expected == actual
```
</details>
#### 📄 **Standard pytest output**
<details>
<summary><strong>Click to see the standard output</strong></summary>
```
example_test2.py::test_with_special_comparisons FAILED
======================================== FAILURES ========================================
______________________________________ test_with_special_comparisons _______________________________________
example_test2.py:23: in test_with_special_comparisons
assert expected == actual
E AssertionError: assert {'timestamp': <ANY>, 'value': 3.14159 ± 0.001, 'metadata': {'version': '1.0.0', 'debug': False}} == {'timestamp': '2023-12-01T10:30:00Z', 'value': 3.1416, 'metadata': {'version': '1.0.1', 'debug': False}}
E
E Common items:
E {'timestamp': <ANY>, 'value': 3.14159 ± 0.001}
E Differing items:
E {'metadata': {'debug': False, 'version': '1.0.0'}} != {'metadata': {'debug': False, 'version': '1.0.1'}}
E
E Full diff:
E {
E 'metadata': {
E 'debug': False,
E - 'version': '1.0.1',
E ? ^
E + 'version': '1.0.0',
E ? ^
E },
E - 'timestamp': '2023-12-01T10:30:00Z',
E + 'timestamp': <ANY>,
E - 'value': 3.1416,
E ? ^
E + 'value': 3.14159 ± 0.001,
E ? ^^^^^^^^^^
E }
```
</details>
#### ✨ **With pytest-deepassert**
```
example_test2.py::test_with_special_comparisons FAILED
======================================== FAILURES ========================================
______________________________________ test_with_special_comparisons _______________________________________
example_test2.py:23: in test_with_special_comparisons
assert expected == actual
E assert
E DeepAssert detailed comparison:
E Value of root['metadata']['version'] changed from "1.0.0" to "1.0.1".
E
E [... standard pytest diff continues below ...]
```
**Notice**: Only the **actual difference** (`version`) is shown. The `timestamp` and `value` fields are correctly ignored!
---
## 💡 Usage
### **Automatic Enhancement**
Once installed, `pytest-deepassert` **automatically** enhances all your `==` assertions inside the tests. No code changes required!
### **Configuration Options**
#### Disable deepassert
```bash
pytest --no-deepassert
```
---
## Configuration
`pytest-deepassert` works out of the box with **zero configuration**. However, you can customize its behavior:
### Command Line Options
| Option | Description |
|--------|-------------|
| `--no-deepassert` | Disable pytest-deepassert for this test run |
---
## Limitations
The tool only enhances assertions inside the test functions (pytest limitation).
If you want to have deep assertion reports in other places (e.g. helper functions for your test), consider using `pytest_deepassert.equal(left, right)` function.
```python
import pytest_deepassert
def helper_function_for_assertion(actual, expected):
pytest_deepassert.equal(actual, expected) # Enhanced diff on failure
```
---
## License
This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.
---
## Links
- **[PyPI Package](https://pypi.org/project/pytest-deepassert/)**
- **[GitHub Repository](https://github.com/alexkuzmik/pytest-deepassert)**
- **[Issue Tracker](https://github.com/alexkuzmik/pytest-deepassert/issues)**
- **[DeepDiff Library](https://github.com/seperman/deepdiff)**
---
<div align="center">
**Made by [Alexander Kuzmik](https://github.com/alexkuzmik)**
*This plugin comes from my desire to share a small tool that I initially built for myself and my team while working on [Opik](https://github.com/comet-ml/opik) python library.
It's built above another amazing open-sourced project - [deepdiff](https://github.com/seperman/deepdiff), so I guess I owe to the community a bit :).*
*If this project helped you, please consider giving it a ⭐ on GitHub!*
</div>
Raw data
{
"_id": null,
"home_page": null,
"name": "pytest-deepassert",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "assertions, debugging, diff, plugin, pytest, testing",
"author": null,
"author_email": "Alexander Kuzmik <alexander.kuzmik99@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/b0/1a/ab14d9bd4f86440473ccbd22d8862907af4e3304865c1ec6c424a8a1305f/pytest_deepassert-0.1.3.tar.gz",
"platform": null,
"description": "<div align=\"center\">\n\n# \ud83d\udd0d pytest-deepassert\n\n</div>\n<div align=\"center\">\n\n[](https://pypi.org/project/pytest-deepassert/)\n[](https://pypi.org/project/pytest-deepassert/)\n[](https://opensource.org/licenses/MIT)\n[](https://pepy.tech/project/pytest-deepassert)\n\n**Enhanced pytest assertions with detailed diffs powered by DeepDiff**\n\n*Stop hunting through massive data dumps. Get precise, readable assertion failures.*\n\n</div>\n\n---\n\n## Table of Contents\n\n- [Why pytest-deepassert?](#why-pytest-deepassert)\n- [How it works](#how-it-works)\n- [Installation](#installation)\n- [Key Features](#key-features)\n- [Comparison with Standard Assertions](#comparison-with-standard-assertions)\n- [Usage](#usage)\n- [Configuration](#configuration)\n- [API Reference](#api-reference)\n- [Limitations](#limitations)\n- [License](#license)\n\n---\n\n## What is it for?\n\nWhen testing that one complex data structure equals another, you may have situations when only some small details differ, but it is really hard to see which ones because of the cluttered comparison report. That's when `pytest-deepassert` helps:\n\n- **Quicker identification** of differences in large & nested objects\n- **Focused output** that highlights what matters\n- **Direct navigation** to specific changes\n- **Structured diffs** for complex data\n\nIf you've ever struggled with understanding **WHAT EXACTLY** is mismatching in your `assert a == b` statement, `pytest-deepassert` is what you need!\n\n## How it works\n\n`pytest-deepassert` is a pytest plugin built on powerful [`deepdiff`](https://github.com/seperman/deepdiff) library. It provides **clear, detailed difference reports** for various data types:\n\n- **Basic types**: `int`, `string`, `float`, `bool`\n- **Collections**: `dict`, `list`, `tuple`, `set`, `frozenset`\n- **Advanced types**: `OrderedDict`, `NamedTuple`, custom objects\n- **Smart helpers**: Works with `pytest.approx()`, `mock.ANY`, and your custom comparators\n\n## \ud83d\ude80 Installation\n\n### From PyPI (Recommended)\n\n```bash\npip install pytest-deepassert\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/alexkuzmik/pytest-deepassert.git\ncd pytest-deepassert\npip install -e .\n```\n\n**Requirements**: Python 3.8+ and pytest 6.0+\n\n## \u2728 Key Features\n\n### **Precise Error Location**\n- Pinpoints **exact paths** where differences occur\n- No more hunting through massive data dumps\n- Shows **specific field names** and **array indices**\n\n### **Clear Change Description**\n- Shows `left value` \u2192 `right value` for each difference\n- Categorizes changes (values changed, items added/removed)\n- **Human-readable** change descriptions\n\n### **Smart Comparison Helpers**\n- Works seamlessly with `pytest.approx()`, `mock.ANY`\n- Supports **custom comparison helpers**\n- Handles complex nested structures intelligently\n\n### **Zero Configuration**\n- **Just install and it works** - no setup required\n- Can be disabled with `--no-deepassert` flag\n- **Drop-in replacement** for standard assertions\n\n---\n\n## \ud83d\udcca Comparison with Standard Assertions\n\n> **TL;DR**: Standard pytest assertions work great for simple cases, but `pytest-deepassert` provides enhanced clarity for complex data structures.\n\n### Example 1: Complex Dictionary Comparison\n\nConsider this realistic test with nested dictionaries:\n\n<details>\n<summary><strong>Click to see the test code</strong></summary>\n\n```python\nimport pytest\nfrom unittest.mock import ANY\n\ndef test_user_profile_comparison():\n expected = {\n \"user\": {\n \"id\": 123,\n \"name\": \"John Doe\",\n \"email\": \"john@example.com\",\n \"preferences\": {\n \"theme\": \"dark\",\n \"notifications\": True,\n \"language\": \"en\"\n },\n \"metadata\": {\n \"created_at\": ANY, # We don't care about exact timestamp\n \"last_login\": \"2023-12-01\",\n \"login_count\": 42,\n \"score\": pytest.approx(85.5, abs=0.1) # Approximate float comparison\n }\n },\n \"permissions\": [\"read\", \"write\", \"admin\"]\n }\n\n actual = {\n \"user\": {\n \"id\": 123,\n \"name\": \"Jane Doe\", # Different name\n \"email\": \"jane@example.com\", # Different email\n \"preferences\": {\n \"theme\": \"light\", # Different theme\n \"notifications\": True,\n \"language\": \"es\" # Different language\n },\n \"metadata\": {\n \"created_at\": \"2023-01-01T10:30:00Z\", # This will match ANY\n \"last_login\": \"2023-11-30\", # Different date\n \"login_count\": 45, # Different count\n \"score\": 85.52 # Close enough to match approx\n }\n },\n \"permissions\": [\"read\", \"write\", \"admin\", \"delete\"] # Extra \"delete\" permission\n }\n\n assert expected == actual\n```\n\n</details>\n\n#### \ud83d\udcc4 **Standard pytest output**\n\n<details>\n<summary><strong>Click to see the standard output</strong></summary>\n\n```\nexample_test1.py::test_user_profile_comparison FAILED\n\n======================================== FAILURES ========================================\n_________________________ test_user_profile_comparison _________________________\nexample_test1.py:45: in test_user_profile_comparison\n assert expected == actual\nE AssertionError: assert {'user': {'id': 123, 'name': 'John Doe', 'email': 'john@example.com', 'preferences': {'theme': 'dark', 'notifications': True, 'language': 'en'}, 'metadata': {'created_at': <ANY>, 'last_login': '2023-12-01', 'login_count': 42, 'score': 85.5 \u00b1 0.1}}, 'permissions': ['read', 'write', 'admin']} == {'user': {'id': 123, 'name': 'Jane Doe', 'email': 'jane@example.com', 'preferences': {'theme': 'light', 'notifications': True, 'language': 'es'}, 'metadata': {'created_at': '2023-01-01T10:30:00Z', 'last_login': '2023-11-30', 'login_count': 45, 'score': 85.52}}, 'permissions': ['read', 'write', 'admin', 'delete']}\n\nE\nE Differing items:\nE {'permissions': ['read', 'write', 'admin']} != {'permissions': ['read', 'write', 'admin', 'delete']}\nE {'user': {'email': 'john@example.com', 'id': 123, 'metadata': {'created_at': <ANY>, 'last_login': '2023-12-01', 'login_count': 42, 'score': 85.5 \u00b1 0.1}, 'name': 'John Doe', ...}} != {'user': {'email': 'jane@example.com', 'id': 123, 'metadata': {'created_at': '2023-01-01T10:30:00Z', 'last_login': '2023-11-30', 'login_count': 45, 'score': 85.52}, 'name': 'Jane Doe', ...}}\n\nE\nE Full diff:\nE {\nE 'permissions': [\nE 'read',\nE 'write',\nE 'admin',\nE - 'delete',\nE ],\nE 'user': {\nE - 'email': 'jane@example.com',\nE ? ^ -\nE + 'email': 'john@example.com',\nE ? ^^\nE 'id': 123,\nE 'metadata': {\nE - 'created_at': '2023-01-01T10:30:00Z',\nE + 'created_at': <ANY>,\nE - 'last_login': '2023-11-30',\nE ? ---\nE + 'last_login': '2023-12-01',\nE ? +++\nE - 'login_count': 45,\nE ? ^\nE + 'login_count': 42,\nE ? ^\nE - 'score': 85.52,\nE ? ^\nE + 'score': 85.5 \u00b1 0.1,\nE ? ^^^^^^\nE },\nE - 'name': 'Jane Doe',\nE ? ^ -\nE + 'name': 'John Doe',\nE ? ^^\nE 'preferences': {\nE - 'language': 'es',\nE ? ^\nE + 'language': 'en',\nE ? ^\nE 'notifications': True,\nE - 'theme': 'light',\nE ? ^^^^^\nE + 'theme': 'dark',\nE ? ^^^^\nE },\nE },\nE }\n```\n\n</details>\n\n#### \u2728 **With pytest-deepassert** (with `pytest -vv`)\n\n```\nexample_test1.py::test_user_profile_comparison FAILED\n\n======================================== FAILURES ========================================\n_________________________ test_user_profile_comparison _________________________\nexample_test1.py:45: in test_user_profile_comparison\n assert expected == actual\nE assert\nE DeepAssert detailed comparison:\nE Item root['permissions'][3] (\"delete\") added to iterable.\nE Value of root['user']['name'] changed from \"John Doe\" to \"Jane Doe\".\nE Value of root['user']['email'] changed from \"john@example.com\" to \"jane@example.com\".\nE Value of root['user']['preferences']['theme'] changed from \"dark\" to \"light\".\nE Value of root['user']['preferences']['language'] changed from \"en\" to \"es\".\nE Value of root['user']['metadata']['last_login'] changed from \"2023-12-01\" to \"2023-11-30\".\nE Value of root['user']['metadata']['login_count'] changed from 42 to 45.\nE\nE [... standard pytest diff continues below ...]\n```\n\n### \ud83c\udfaf **Key Improvements**\n\n| Feature | Standard pytest | pytest-deepassert |\n|---------|----------------|-------------------|\n| **Smart filtering** | Shows all field comparisons | \u2705 **Ignores `created_at`** (matches `ANY`) |\n| **Precision** | Comprehensive diff coverage | \u2705 **Ignores `score`** (within `pytest.approx` tolerance) |\n| **Focus** | Complete context provided | \ud83c\udfaf **Highlights actual differences** |\n| **Format** | String-based comparison | \ud83d\udccb **Structured, categorized output** |\n\n\n### \ud83d\udccb Example 2: Smart Comparison Helpers\n\n`pytest-deepassert` seamlessly handles special comparison helpers:\n\n<details>\n<summary><strong>Click to see the test code</strong></summary>\n\n```python\nimport pytest\nfrom unittest.mock import ANY\n\ndef test_with_special_comparisons():\n expected = {\n \"timestamp\": ANY, # We don't care about exact timestamp\n \"value\": pytest.approx(3.14159, abs=0.001), # Approximate float comparison\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"debug\": False\n }\n }\n\n actual = {\n \"timestamp\": \"2023-12-01T10:30:00Z\",\n \"value\": 3.14160, # Close enough\n \"metadata\": {\n \"version\": \"1.0.1\", # Different version\n \"debug\": False\n }\n }\n\n assert expected == actual\n```\n\n</details>\n\n#### \ud83d\udcc4 **Standard pytest output**\n\n<details>\n<summary><strong>Click to see the standard output</strong></summary>\n\n```\nexample_test2.py::test_with_special_comparisons FAILED\n\n======================================== FAILURES ========================================\n______________________________________ test_with_special_comparisons _______________________________________\nexample_test2.py:23: in test_with_special_comparisons\n assert expected == actual\nE AssertionError: assert {'timestamp': <ANY>, 'value': 3.14159 \u00b1 0.001, 'metadata': {'version': '1.0.0', 'debug': False}} == {'timestamp': '2023-12-01T10:30:00Z', 'value': 3.1416, 'metadata': {'version': '1.0.1', 'debug': False}}\n\nE\nE Common items:\nE {'timestamp': <ANY>, 'value': 3.14159 \u00b1 0.001}\nE Differing items:\nE {'metadata': {'debug': False, 'version': '1.0.0'}} != {'metadata': {'debug': False, 'version': '1.0.1'}}\n\nE\nE Full diff:\nE {\nE 'metadata': {\nE 'debug': False,\nE - 'version': '1.0.1',\nE ? ^\nE + 'version': '1.0.0',\nE ? ^\nE },\nE - 'timestamp': '2023-12-01T10:30:00Z',\nE + 'timestamp': <ANY>,\nE - 'value': 3.1416,\nE ? ^\nE + 'value': 3.14159 \u00b1 0.001,\nE ? ^^^^^^^^^^\nE }\n```\n\n</details>\n\n#### \u2728 **With pytest-deepassert**\n\n```\nexample_test2.py::test_with_special_comparisons FAILED\n\n======================================== FAILURES ========================================\n______________________________________ test_with_special_comparisons _______________________________________\nexample_test2.py:23: in test_with_special_comparisons\n assert expected == actual\nE assert\nE DeepAssert detailed comparison:\nE Value of root['metadata']['version'] changed from \"1.0.0\" to \"1.0.1\".\nE\nE [... standard pytest diff continues below ...]\n```\n\n**Notice**: Only the **actual difference** (`version`) is shown. The `timestamp` and `value` fields are correctly ignored!\n\n---\n\n## \ud83d\udca1 Usage\n\n### **Automatic Enhancement**\n\nOnce installed, `pytest-deepassert` **automatically** enhances all your `==` assertions inside the tests. No code changes required!\n\n\n### **Configuration Options**\n\n#### Disable deepassert\n\n```bash\npytest --no-deepassert\n```\n\n---\n\n## Configuration\n\n`pytest-deepassert` works out of the box with **zero configuration**. However, you can customize its behavior:\n\n### Command Line Options\n\n| Option | Description |\n|--------|-------------|\n| `--no-deepassert` | Disable pytest-deepassert for this test run |\n\n\n---\n\n\n## Limitations\n\nThe tool only enhances assertions inside the test functions (pytest limitation).\nIf you want to have deep assertion reports in other places (e.g. helper functions for your test), consider using `pytest_deepassert.equal(left, right)` function.\n\n```python\nimport pytest_deepassert\n\ndef helper_function_for_assertion(actual, expected):\n pytest_deepassert.equal(actual, expected) # Enhanced diff on failure\n```\n\n\n---\n\n## License\n\nThis project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.\n\n---\n\n## Links\n\n- **[PyPI Package](https://pypi.org/project/pytest-deepassert/)**\n- **[GitHub Repository](https://github.com/alexkuzmik/pytest-deepassert)**\n- **[Issue Tracker](https://github.com/alexkuzmik/pytest-deepassert/issues)**\n- **[DeepDiff Library](https://github.com/seperman/deepdiff)**\n\n---\n\n<div align=\"center\">\n\n**Made by [Alexander Kuzmik](https://github.com/alexkuzmik)**\n\n*This plugin comes from my desire to share a small tool that I initially built for myself and my team while working on [Opik](https://github.com/comet-ml/opik) python library.\nIt's built above another amazing open-sourced project - [deepdiff](https://github.com/seperman/deepdiff), so I guess I owe to the community a bit :).*\n\n*If this project helped you, please consider giving it a \u2b50 on GitHub!*\n\n</div>\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A pytest plugin for enhanced assertion reporting with detailed diffs",
"version": "0.1.3",
"project_urls": {
"Homepage": "https://github.com/alexkuzmik/pytest-deepassert",
"Issues": "https://github.com/alexkuzmik/pytest-deepassert/issues",
"Repository": "https://github.com/alexkuzmik/pytest-deepassert"
},
"split_keywords": [
"assertions",
" debugging",
" diff",
" plugin",
" pytest",
" testing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "685a148c8be946431165382cb35b8ff6f901fd02dc59f154e9d85b18814882ac",
"md5": "0d03adee378815ea6d737b2157ff8c52",
"sha256": "24fa191ecb069a3a15670dadc945305026b7206595e615e10f2b1f3ff818e987"
},
"downloads": -1,
"filename": "pytest_deepassert-0.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0d03adee378815ea6d737b2157ff8c52",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 10059,
"upload_time": "2025-09-02T21:59:10",
"upload_time_iso_8601": "2025-09-02T21:59:10.552182Z",
"url": "https://files.pythonhosted.org/packages/68/5a/148c8be946431165382cb35b8ff6f901fd02dc59f154e9d85b18814882ac/pytest_deepassert-0.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b01aab14d9bd4f86440473ccbd22d8862907af4e3304865c1ec6c424a8a1305f",
"md5": "5b38c1d4b82763d09ddd13223bd004d0",
"sha256": "c5c788b13c69e82a34f9e06d1ff0141d6d69eb07cb07a213d0ab7ad7e8950184"
},
"downloads": -1,
"filename": "pytest_deepassert-0.1.3.tar.gz",
"has_sig": false,
"md5_digest": "5b38c1d4b82763d09ddd13223bd004d0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 11716,
"upload_time": "2025-09-02T21:59:11",
"upload_time_iso_8601": "2025-09-02T21:59:11.661254Z",
"url": "https://files.pythonhosted.org/packages/b0/1a/ab14d9bd4f86440473ccbd22d8862907af4e3304865c1ec6c424a8a1305f/pytest_deepassert-0.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-02 21:59:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "alexkuzmik",
"github_project": "pytest-deepassert",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pytest-deepassert"
}