Understanding PyTorch’s Test Infrastructure PyTorch's test infrastructure dynamically generates test names across devices and dtypes, causing CI failures to show names like TestLinalgCUDA.test_matmul_cuda_float32 that differ from source templates. The system uses device-generic tests, OpInfos, and CI sharding to validate thousands of combinations automatically. For local debugging, pytest -k and test/run_test.py are recommended for reproducing generated test failures. Featured projects TL;DR - PyTorch tests are often generated at import time, so CI failures may show device/dtype-specific names that differ from the source template. - For local debugging, pytest -k and test/run test.py are usually the fastest ways to reproduce generated test failures. - Device-generic tests, operator metadata through OpInfos, and CI sharding are the key pieces to understand when contributing or debugging PyTorch tests. PyTorch tests are often generated dynamically across devices and dtypes, which is why test names in CI may look different from the class and method names in the source file. This post explains how device-generic tests, OpInfos, instantiate device type tests , and CI sharding fit together, and how contributors can run and debug PyTorch tests more effectively. Why PyTorch Testing Feels Different If you have ever opened a pull request against PyTorch, watched a generated test like TestLinalgCUDA.test matmul cuda float32 fail in CI, and wondered where that name came from – or tried running a test by its source name and got “no tests collected” – this guide is for you. PyTorch’s test infrastructure https://github.com/pytorch/pytorch/wiki/Running-and-writing-tests is built for scale. Depending on the decorators used and operator metadata provided through OpInfos, section1 a single test method https://github.com/pytorch/pytorch/blob/main/test/test ops.py can expand across multiple devices, dtypes, and operators automatically. That is what lets PyTorch validate thousands of combinations without thousands of handwritten tests. But it also means the test you write in the source file is not always the exact test that CI runs, which can be confusing the first time you encounter it. Note: Many helpers discussed in this guide live under torch.testing. internal, which is PyTorch’s internal test infrastructure. If you are testing your own project, use public APIs like pytest and torch.testing.assert close https://docs.pytorch.org/docs/2.12/testing.html instead. The Naming Mystery: Why “No Tests Collected”? One of the first confusing moments for new PyTorch contributors is trying to run a test by the class and method name they see in the source file: pytest test/test torch.py::TestTorch::test matmul In many PyTorch test files, this may return “no tests collected.” That is usually not because the test is missing. It is because the class in the source file is a template, not the final class that the test runner sees. When the file is imported, instantiate device type tests expands the template into concrete device-specific classes such as TestTorchCPU, TestTorchCUDA, or TestTorchMPS. If the test is also parameterized by dtype, the generated method name may include the device and dtype as well, for example test matmul cuda float32. These generated classes are built from the original template class and PyTorch’s device-specific test bases, so they still inherit the shared behavior provided by PyTorch’s internal TestCase. For local debugging, it is usually easier to filter by the generated test name pattern instead of targeting the original template class directly: pytest test/test torch.py -k "test matmul" pytest test/test torch.py -k "test matmul cuda float32" Once you know that PyTorch generates the runnable test names during import, CI failures become much easier to map back to the source test. How Device-Generic Tests Work PyTorch runs across devices such as CPU, CUDA, MPS, and XPU, and many tests need to validate behavior across float16, float32, float64, bfloat16, integer, and other dtypes. Writing a separate test for every device and dtype combination would quickly become a maintenance nightmare. So PyTorch uses test templates. You write one test method with device and dtype parameters: python def test basic self, device, dtype : ... When Python imports the test file, instantiate device type tests expands that template across the selected device types and dtypes. For example, one template class can produce generated classes such as TestMatmulCPU, TestMatmulCUDA, and TestMatmulMPS, with generated methods such as test basic cuda float32. Figure 1: Test Class Hierarchy & Instantiation Flow The generated names follow this pattern: