Skip to content

Instantly share code, notes, and snippets.

View jangia's full-sized avatar

Jan Giacomelli jangia

View GitHub Profile
import re
import pytest
REDIRECT_REGEX = r"(^/([A-Za-z0-9#&?=]+|$)|^https://my.domain\.com/[A-Za-z0-9#&?=/]*$)"
def is_valid_success_url(url: str) -> bool:
return bool(re.match(REDIRECT_REGEX, url))
@jangia
jangia / test_spies.py
Created March 13, 2025 14:57
create_autospec – easily ensure that mocked objects are called correctly (Spies)
from unittest.mock import MagicMock, create_autospec
class MyCRMService:
def sync_user(self, *, first_name: str, last_name: str, email: str) -> None:
print("Calling MyCRM's REST API to send data there. That's slow and unreliable.")
class CreateUser:
def __init__(self, *, crm_service: MyCRMService) -> None:
@jangia
jangia / test_stubs.py
Created March 13, 2025 14:55
create_autospec – easily ensure that mocked objects are called correctly (Stubs)
import time
from unittest.mock import MagicMock, create_autospec
class SentimentClassifier:
def predict(self, text: str) -> str:
# Imagine that prediction is taking a long time
time.sleep(5)
return "positive"
@jangia
jangia / test_email_validator_abuse.py
Created February 5, 2025 19:57
Parametrize tests using pytest - abuse
import pytest
from email_validator import is_valid_email
@pytest.mark.parametrize(
"email,is_valid",
[
("[email protected]", True),
("gqehtjwyeumi,", False),
@jangia
jangia / email_validator.py
Last active February 5, 2025 19:52
Parametrize tests using pytest
import re
def is_valid_email(email: str) -> bool:
return bool(re.search(r"^[\w\.\-\+']+@[\w\.\-]+\.\w+$", email))
@jangia
jangia / models.py
Created April 10, 2024 05:41
Test behavior, not implementation details - part 3
from dataclasses import dataclass
from enum import Enum
class TaskStatus(str, Enum):
OPEN = "OPEN"
CLOSED = "CLOSED"
@dataclass
@jangia
jangia / tests.py
Created March 27, 2024 19:11
Testing behavior, not implementation details – part 2 (tests)
import sqlite3
import pytest
from models import Task, TaskStatus
from store import TaskStoreSQLite
@pytest.fixture
def connection(tmp_path) -> sqlite3.Connection:
@jangia
jangia / models.py
Created March 27, 2024 18:48
Testing behavior, not implementation details – part 2 (model & store)
from dataclasses import dataclass
from enum import Enum
class TaskStatus(str, Enum):
OPEN = "OPEN"
CLOSED = "CLOSED"
@dataclass
@jangia
jangia / tests.py
Created March 18, 2024 17:26
Testing behavior, not implementation details – In-Memory Store Tests
# behavior/tests.py
def test_add_task_():
store = TaskStoreInMemory()
task = Task(title="Do the dishes", status=TaskStatus.OPEN)
store.add_task(task)
assert store.tasks[0].title == "Do the dishes"
@jangia
jangia / store.py
Created March 18, 2024 17:25
Testing behavior, not implementation details – In-Memory Store
# behavior/store.py
class TaskStoreInMemory(TaskStore):
def __init__(self):
self._tasks = []
def add_task(self, task: Task) -> None:
self._tasks.append(task)
def list_tasks(self) -> list[Task]: