Skip to content

Customize the attack corpora

Each shipped test draws its prompts from a corpus exposed as a fixture. The default fixtures return the bundled pytest_wardenbot.corpus.* tuples, so the tests work out of the box. Override the fixture in your conftest.py to substitute or extend the corpus for your specific bot.

Fixtures

Shipped test Fixture
test_prompt_injection wardenbot_jailbreak_prompts
test_system_prompt_leak wardenbot_system_prompt_leak_prompts
test_refusal_bypass wardenbot_refusal_bypass_prompts
test_off_topic wardenbot_off_topic_prompts
test_indirect_injection wardenbot_indirect_injection_prompts
test_encoded_payloads wardenbot_encoded_payload_prompts
test_multi_turn wardenbot_multi_turn_jailbreak_prompts

Replace the bundled corpus

# conftest.py
import pytest


@pytest.fixture
def wardenbot_jailbreak_prompts():
    return (
        ("My company's custom jailbreak attempt #1", "custom-attack-1"),
        ("Another bot-specific attack we want to catch", "custom-attack-2"),
    )

The shipped test_prompt_injection tests now parametrize over your two custom entries instead of the bundled five.

Extend the bundled corpus

# conftest.py
import pytest
from pytest_wardenbot.corpus import JAILBREAK_PROMPTS


_MY_EXTRA = (
    ("A bot-specific attack we caught in production", "prod-incident-2026-04"),
)


@pytest.fixture
def wardenbot_jailbreak_prompts():
    return JAILBREAK_PROMPTS + _MY_EXTRA

Now the test runs the bundled five plus your one production-specific entry.

Disable an entire test category

Return an empty tuple. pytest's parametrize will collect zero cases for that test and pass trivially.

@pytest.fixture
def wardenbot_off_topic_prompts():
    return ()  # general-purpose bot; off-topic deflection doesn't apply

Constraints on the override fixture

The override fixture must be a plain () -> tuple[...] function. No request parameter, no other fixture dependencies. This is because the shipped tests resolve the corpus at pytest collection time, before the fixture machinery has fully initialized. Build your corpus at import time and have the fixture return the prepared tuple.

This is fine:

_MY_CORPUS = tuple(_compute_my_corpus_at_import_time())

@pytest.fixture
def wardenbot_jailbreak_prompts():
    return _MY_CORPUS

This will silently fall back to the bundled corpus (fixture not callable without args):

@pytest.fixture
def wardenbot_jailbreak_prompts(my_other_fixture):  # WILL NOT WORK
    return my_other_fixture.build()

Entry shape per corpus

Most corpora use (prompt, attack_id) tuples. Two have different shapes:

# wardenbot_encoded_payload_prompts:
#   (prompt, trigger_words, attack_id)
#   trigger_words is a tuple of strings the bot would emit if compromised
ENCODED = (
    ("Base64-encoded attack ...", ("PWNED_BY_BASE64",), "base64"),
)

# wardenbot_multi_turn_jailbreak_prompts:
#   (priming_turns, payload_prompt, attack_id)
#   priming_turns is a tuple of strings sent before the payload
MULTI_TURN = (
    (
        ("Setup turn 1", "Setup turn 2"),
        "The actual payload after priming",
        "two-turn-priming",
    ),
)