Skip to Content

How To Use Pytest Markers to Categorize and Selectively Run LLM Tests?

Learn how to apply pytest markers to categorize behavioral tests, organize your AI evaluation suite, and selectively run specific model safeguard checks.

Question

When implementing an automated behavioral test suite with pytest, what is the primary function of using markers?

A. To run tests in parallel across multiple machines
B. To generate reports on test coverage
C. To automatically fix errors in test cases
D. To categorize and selectively run tests

Answer

D. To categorize and selectively run tests

Explanation

When evaluating large language models (LLMs), your automated behavioral test suite will quickly grow to include hundreds of distinct checks. You might have tests specifically designed to catch prompt injections, evaluate factual accuracy, measure summarization quality, or ensure the model refuses to generate toxic content.

Running every single test in your suite every time you make a minor prompt adjustment is highly inefficient. It slows down development and quickly burns through expensive API tokens if you are querying live commercial models. Pytest markers solve this logistical problem by allowing you to tag and organize your test functions.

Categorizing AI Safeguards with Markers

Markers act as custom labels applied directly to your test code using the @pytest.mark decorator. By tagging your tests, you create distinct, runnable categories within your larger suite.

For example, you might label all tests dealing with data privacy as @pytest.mark.privacy, and all tests verifying mathematical reasoning as @pytest.mark.reasoning. When you want to verify a recent fix to your privacy guardrails, you simply instruct the command line to execute only the privacy subset: pytest -m privacy. The framework will automatically bypass the mathematical reasoning tests entirely.

This selective execution provides three main operational advantages for machine learning teams:

  1. Cost Control: Differentiate between tests that run locally against mocked endpoints and those that require paid API calls to live models. Tag the live ones with @pytest.mark.expensive so developers only run them before a major deployment rather than during everyday iteration.
  2. Speed and Efficiency: Tag tests that evaluate massive context windows as @pytest.mark.slow. This allows your CI/CD pipeline to run quick, fundamental sanity checks on every code commit while saving the lengthy, slow evaluations for a nightly scheduled build.
  3. Targeted Debugging: If your LLM starts failing jailbreak evaluations, you can isolate the problem immediately by running pytest -m jailbreak. You focus strictly on the broken behavior without sorting through unrelated test logs.

Registering Custom Markers for Production

To prevent typos and keep your test suite organized, always register your custom markers in your project’s pytest.ini file. If a developer accidentally types @pytest.mark.toxcc instead of @pytest.mark.toxic, the framework will throw a strict warning. Documenting your markers ensures the entire engineering team understands exactly how to filter and execute the right behavioral tests at the right time.