能否通过插件或原生方式从pytest动态生成Jenkins Pipeline阶段?
Great question! While there isn't a fully "native" one-click solution from either pytest or Jenkins to automatically map each test case to a Pipeline stage, there are streamlined ways to achieve this that are more robust than your initial manual approach. Let's walk through them:
1. Optimize Your Existing Approach with Cleaner Pytest Test Collection
Your current method works, but we can make the test collection more reliable by using pytest's built-in quiet mode for test collection, which outputs a clean, consistent list of test identifiers:
stage("Run Tests in Parallel Stages") { steps { script { // Use -q to get a simplified, line-separated list of test nodes def rawTestList = sh( script: "pytest tests/ --collect-only -q", returnStdout: true ).trim().split('\n') def testStages = [:] rawTestList.each { testNode -> // Split the test node into file path and test name (e.g., tests/test_auth.py::test_login -> [file, name]) def [testFile, testName] = testNode.split('::') testStages[testName] = { stage(testName) { sh "pytest ${testFile} -k ${testName}" } } } // Run all test stages in parallel for Blue Ocean visibility parallel testStages } } }
This avoids messy string parsing of unstructured output, since --collect-only -q outputs each test in the standard file.py::test_name format. In Blue Ocean, each parallel stage will show up as a separate, clickable node so you can see exactly which tests passed/failed at a glance.
2. Use Pytest Plugins for Structured Test Data
For even more reliability, use a pytest plugin to export test metadata in a structured format (like JSON), which is easier to parse in Jenkins:
Step 1: Install the pytest-json-report plugin
pip install pytest-json-report
Step 2: Parse the JSON Report in Jenkins Pipeline
stage("Generate & Run Test Stages") { steps { script { // Collect tests and export to JSON sh "pytest tests/ --collect-only --json-report --json-report-file=test_catalog.json" // Read and parse the JSON file def testCatalog = readJSON file: 'test_catalog.json' def testStages = [:] testCatalog.tests.each { test -> def testNode = test.nodeid // Full test identifier (file::name) def testName = test.name def testFile = testNode.split('::')[0] testStages[testName] = { stage(testName) { sh "pytest ${testFile} -k ${testName}" } } } parallel testStages } } }
The JSON report includes additional metadata (like test markers, module paths) if you need to filter or group tests later, making this approach more scalable.
3. Key Notes for Blue Ocean Visibility
- When using
parallel, Blue Ocean will render each test stage as an individual item in the pipeline view, exactly what you're looking for. - If you need to run tests sequentially instead of in parallel, simply replace
parallel testStageswithtestStages.each { key, value -> value() }—each test will still show up as a separate stage in Blue Ocean.
Are There "Native" Plugins for This?
As of now, there's no Jenkins plugin or pytest feature that directly generates Pipeline stages per test case out of the box. The above methods are the most practical and maintainable ways to achieve your goal, leveraging pytest's test collection capabilities and Jenkins' scripted Pipeline flexibility.
内容的提问来源于stack exchange,提问作者Aryeh K

