How to Use Wildcards in Catch2 Test Specifications
Catch2 enables flexible test filtering through wildcard patterns using the asterisk (*) character, which can appear only at the beginning, end, or both ends of a test name to match any number of characters including zero.
When working with large test suites in the catchorg/Catch2 framework, running specific subsets of tests becomes essential for rapid iteration. Wildcards in test specifications provide a powerful command-line mechanism to filter test cases without modifying source code, leveraging the WildcardPattern class to perform efficient string matching against test names.
Supported Wildcard Syntax and Position Rules
Catch2 restricts wildcard placement to three specific configurations to ensure predictable and performant matching behavior. The asterisk acts as a greedy matcher that accepts zero or more characters.
- Suffix wildcard (
Test*): Matches test names that start with "Test", including a test named exactly "Test". - Prefix wildcard (
*Test): Matches test names that end with "Test", including a test named exactly "Test". - Infix wildcard (
*Test*): Matches test names that contain "Test" anywhere in the string.
The parser explicitly rejects patterns where the asterisk appears in the middle of the string (such as Te*st), validating only start, end, or both-ends positioning as verified in tests/SelfTest/IntrospectiveTests/TestSpec.tests.cpp at lines 78-100.
Command-Line Usage and Shell Escaping
Because shells like Bash and Zsh interpret asterisks as globbing operators, you must quote or escape wildcard patterns to prevent shell expansion before they reach Catch2's parser. As documented in docs/command-line.md, failure to quote the pattern results in shell errors or incorrect filtering.
# Run tests ending with "Test"
./my_tests "*Test"
# Run tests starting with "Test"
./my_tests "Test*"
# Run tests containing "Test" anywhere in the name
./my_tests "*Test*"
Unquoted asterisks cause the shell to attempt file expansion, likely resulting in a "no matches found" error or running unintended tests.
Internal Implementation of Wildcard Matching
The matching logic resides in catch2/internal/catch_wildcard_pattern.hpp, which defines the WildcardPattern class. When Catch2 parses a test specification, it constructs a NamePattern object (implemented in src/catch2/catch_test_spec.cpp at lines 35-40) that instantiates a WildcardPattern with a lower-cased version of the pattern string.
The matches() method of WildcardPattern performs case-insensitive comparison against test names, allowing "*test*" to match "MyTest", "MYTEST", or "mytest". This design ensures that test filtering behaves consistently regardless of naming conventions used in source code.
Combining Wildcards with Tags
Catch2 test specifications support boolean combinations of patterns and tags. You can narrow execution further by appending tag specifications in square brackets immediately after the wildcard pattern.
# Run tests containing "Network" in the name AND tagged with [slow]
./my_tests "*Network*[slow]"
# Run tests starting with "API" OR tagged with [integration]
./my_tests "API*,[integration]"
This parsing occurs in the same specification engine that handles the WildcardPattern, allowing complex filtering strategies without recompiling test binaries.
Summary
- Wildcard patterns in Catch2 use
*as a matcher for zero or more characters, valid only at the start, end, or both ends of a test name. - Implementation relies on the
WildcardPatternclass incatch_wildcard_pattern.hpp, invoked byNamePatternincatch_test_spec.cpp(lines 35-40). - Case handling is performed via lower-casing both the pattern and test names, making matching case-insensitive.
- Shell safety requires quoting patterns like
"*Test*"to prevent glob expansion. - Tag integration allows combining wildcards with bracketed tags for precise test selection.
Frequently Asked Questions
Can I place the asterisk wildcard in the middle of a test name pattern?
No. Catch2's parser restricts wildcards to the start (*Test), end (Test*), or both ends (*Test*) of the pattern only. Attempting to use Te*st results in a parsing error or literal string matching, as enforced by the validation logic in TestSpec.tests.cpp at lines 78-100.
Is wildcard matching in Catch2 case-sensitive?
No. The WildcardPattern constructor converts the pattern to lowercase before matching, and comparison against test names follows case-insensitive rules. Therefore, "*api*" matches "TestAPI", "testApi", and "TESTAPI".
Why does my wildcard pattern return "no tests found" when tests clearly exist?
This typically occurs when the shell expands the asterisk before Catch2 receives the argument. Always wrap wildcard specifications in double quotes (e.g., "*Test*") or escape the asterisk (e.g., \*Test\*) to ensure the pattern reaches Catch2's internal parser intact.
Can I use wildcards to match test tags instead of test names?
No. Wildcards apply specifically to test name matching according to the specification parser in catch_test_spec.cpp. However, you can combine a wildcarded name with specific tags in a single specification (such as "*Network*[slow]") to filter tests that match both criteria simultaneously.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →