get_tests
Retrieve test cases from TestRail test runs with filtering options for status, labels, and pagination to analyze test execution data.
Instructions
Returns a list of tests for a test run.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | The ID of the test run | |
| status_id | No | A comma-separated list of status IDs to filter by | |
| limit | No | The number that sets the limit of tests to be shown on the response (max 250, default 250) | |
| offset | No | The number that sets the position where the response should start from (pagination offset) | |
| label_id | No | IDs of labels as comma separated values to filter by |
Implementation Reference
- src/server.ts:733-753 (handler)MCP tool handler function: destructures input parameters, constructs filters, calls the service layer getTests function, logs progress, and returns the result as formatted JSON text content for MCP.async ({ run_id, status_id, limit, offset, label_id }) => { logger.debug(`Get tests tool called with run_id: ${run_id}`); const filters = { run_id, status_id, limit, offset, label_id, }; const result = await getTests(filters); logger.debug(`Get tests tool completed. Found ${result.tests.length} tests.`); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; }, );
- src/server.ts:720-721 (registration)Registration of the 'get_tests' MCP tool with the server, specifying name, metadata, input schema, and handler reference.server.registerTool( 'get_tests',
- src/server.ts:722-732 (schema)Input schema definition for the get_tests tool using Zod validators, defining required run_id and optional filters for status, limit, offset, and labels.{ title: 'Get TestRail Tests', description: 'Returns a list of tests for a test run.', inputSchema: { run_id: z.number().int().positive().describe('The ID of the test run'), status_id: z.array(z.number().int().positive()).optional().describe('A comma-separated list of status IDs to filter by'), limit: z.number().int().positive().optional().describe('The number that sets the limit of tests to be shown on the response (max 250, default 250)'), offset: z.number().int().min(0).optional().describe('The number that sets the position where the response should start from (pagination offset)'), label_id: z.array(z.number().int().positive()).optional().describe('IDs of labels as comma separated values to filter by'), }, },
- Service layer helper: getTests function transforms tool filters to client params, calls TestRailClient.getTests, normalizes response by extracting custom fields, and returns structured TestsResponse.export async function getTests(filters: GetTestsFilters): Promise<TestsResponse> { // Transform service filters to client parameters const clientParams: GetTestsParams = { run_id: filters.run_id, status_id: filters.status_id, limit: filters.limit, offset: filters.offset, label_id: filters.label_id, }; const response: TestRailTestsResponse = await testRailClient.getTests(clientParams); // Transform tests to normalized format const transformedTests: TestSummary[] = response.tests.map((test) => { // Extract custom fields (any fields not in the standard interface) const standardFields = ['id', 'title']; const custom: Record<string, unknown> = {}; Object.keys(test).forEach((key) => { if (!standardFields.includes(key)) { custom[key] = test[key]; } }); return { id: test.id, title: test.title, custom: Object.keys(custom).length > 0 ? custom : undefined, }; }); return { offset: response.offset, limit: response.limit, size: response.size, _links: response._links, tests: transformedTests, }; }
- Client layer HTTP client method: constructs TestRail API URL /get_tests/{run_id} with query params for filters, performs GET request with axios, handles errors, and returns raw API response.async getTests(params: GetTestsParams): Promise<TestRailTestsResponse> { try { // Build query parameters const queryParams = new URLSearchParams(); // Handle status_id filter (comma-separated list) if (params.status_id && params.status_id.length > 0) { queryParams.append('status_id', params.status_id.join(',')); } // Handle pagination parameters if (params.limit !== undefined) { queryParams.append('limit', params.limit.toString()); } if (params.offset !== undefined) { queryParams.append('offset', params.offset.toString()); } // Handle label_id filter (comma-separated list) if (params.label_id && params.label_id.length > 0) { queryParams.append('label_id', params.label_id.join(',')); } const queryString = queryParams.toString(); const url = `/get_tests/${params.run_id}${queryString ? `&${queryString}` : ''}`; const res = await this.http.get(url); if (res.status >= 200 && res.status < 300) { logger.info({ message: 'Successfully retrieved tests for run', runId: params.run_id, testCount: res.data.tests?.length || 0, responseSize: JSON.stringify(res.data).length, }); return res.data; } else { throw new Error(`HTTP ${res.status}: ${res.statusText}`); } } catch (error) { const normalized = this.normalizeError(error); const safeDetails = this.getSafeErrorDetails(error); logger.error({ message: 'Failed to retrieve tests for run', runId: params.run_id, error: normalized, details: safeDetails, }); throw normalized; } }