[{"data":1,"prerenderedAt":672},["ShallowReactive",2],{"page-\u002Fadvanced-pytest-architecture-configuration\u002Foptimizing-test-discovery\u002Fselecting-affected-tests-with-pytest-testmon\u002F":3},{"id":4,"title":5,"body":6,"description":635,"extension":636,"meta":637,"navigation":667,"path":668,"seo":669,"stem":670,"__hash__":671},"content\u002Fadvanced-pytest-architecture-configuration\u002Foptimizing-test-discovery\u002Fselecting-affected-tests-with-pytest-testmon\u002Findex.md","Selecting Affected Tests with pytest-testmon",{"type":7,"value":8,"toc":624},"minimark",[9,18,21,26,49,53,56,88,96,114,120,123,262,266,276,279,283,319,323,326,335,341,344,445,449,452,466,483,489,536,542,546,549,552,555,559,565,571,580,584,615,620],[10,11,12,13,17],"p",{},"A suite of four thousand tests that takes six minutes is fine in CI and painful in an edit-run loop, where the developer changed one function and wants to know within seconds whether anything broke. ",[14,15,16],"code",{},"pytest-testmon"," narrows the run to the tests that could have been affected, using coverage data from previous runs to know which tests executed which lines. Change a function, and only the tests that ran that function are selected.",[10,19,20],{},"It is a genuinely effective tool for local feedback and a risky one as a sole CI gate. The speed-up is not marginal: on a typical service, most edits touch code exercised by a few percent of the suite, so the selected run is one or two orders of magnitude faster than the full one. That changes behaviour — developers who can get an answer in five seconds run the tests after every change rather than once before pushing, and that alone catches a class of mistakes much earlier. Knowing precisely what it can and cannot see — Python lines, yes; configuration, data files and dependency versions, no — is what lets a team take the speed without the blind spots.",[22,23,25],"h2",{"id":24},"prerequisites","Prerequisites",[27,28,29,40,46],"ul",{},[30,31,32,35,36,39],"li",{},[14,33,34],{},"pytest-testmon >= 2.1"," and ",[14,37,38],{},"pytest >= 8.0",".",[30,41,42,45],{},[14,43,44],{},"coverage"," installed; testmon uses it to record which lines each test executes.",[30,47,48],{},"A suite without heavy cross-test state, since selection assumes a test's outcome depends only on its own recorded code.",[22,50,52],{"id":51},"solution","Solution",[10,54,55],{},"Seed the database once with a full run, then let each subsequent run select.",[57,58,63],"pre",{"className":59,"code":60,"language":61,"meta":62,"style":62},"language-bash shiki shiki-themes github-light github-dark","# 1. Full run: records every test's executed lines into .testmondata.\npytest --testmon -q\n","bash","",[14,64,65,74],{"__ignoreMap":62},[66,67,70],"span",{"class":68,"line":69},"line",1,[66,71,73],{"class":72},"sJ8bj","# 1. Full run: records every test's executed lines into .testmondata.\n",[66,75,77,81,85],{"class":68,"line":76},2,[66,78,80],{"class":79},"sScJk","pytest",[66,82,84],{"class":83},"sj4cs"," --testmon",[66,86,87],{"class":83}," -q\n",[57,89,94],{"className":90,"code":92,"language":93,"meta":62},[91],"language-text","4127 passed in 358.2s\n","text",[14,95,92],{"__ignoreMap":62},[57,97,99],{"className":59,"code":98,"language":61,"meta":62,"style":62},"# 2. Edit one function in src\u002Fmyapp\u002Fpricing.py, then:\npytest --testmon -q\n",[14,100,101,106],{"__ignoreMap":62},[66,102,103],{"class":68,"line":69},[66,104,105],{"class":72},"# 2. Edit one function in src\u002Fmyapp\u002Fpricing.py, then:\n",[66,107,108,110,112],{"class":68,"line":76},[66,109,80],{"class":79},[66,111,84],{"class":83},[66,113,87],{"class":83},[57,115,118],{"className":116,"code":117,"language":93,"meta":62},[91],"testmon: changed files: src\u002Fmyapp\u002Fpricing.py, skipping collection of 211 files\n38 passed, 4089 deselected in 6.4s\n",[14,119,117],{"__ignoreMap":62},[10,121,122],{},"Thirty-eight tests executed that function; those are the ones that ran. Six seconds instead of six minutes is the difference between running tests after every edit and running them once before pushing.",[124,125,128,258],"figure",{"className":126},[127],"diagram",[129,130,137,138,137,142,137,146,137,164,137,172,137,180,137,189,137,195,137,199,137,205,137,211,137,215,137,219,137,223,137,229,137,233,137,237,137,244,137,249,137,254],"svg",{"viewBox":131,"role":132,"ariaLabelledBy":133,"xmlns":136},"0 0 820 262","img",[134,135],"tm-t","tm-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","\n  ",[139,140,141],"title",{"id":134},"How testmon decides which tests to run",[143,144,145],"desc",{"id":135},"A full run records, for each test, a fingerprint of the code blocks it executed into a local database. After an edit, testmon fingerprints the changed file, finds the tests whose recorded fingerprints include the changed blocks, and runs only those, deselecting the rest.",[147,148,149,150,137],"defs",{},"\n    ",[151,152,159],"marker",{"id":153,"viewBox":154,"refX":155,"refY":156,"markerWidth":157,"markerHeight":157,"orient":158},"tm-a","0 0 10 10","9","5","7","auto-start-reverse",[160,161],"path",{"d":162,"fill":163},"M0 0 L10 5 L0 10 z","#3d405b",[165,166],"rect",{"x":167,"y":167,"width":168,"height":169,"rx":170,"fill":171},"0","820","262","14","#fffdf8",[93,173,179],{"x":174,"y":175,"textAnchor":176,"fontSize":177,"fontWeight":178,"fill":163},"410","28","middle","16","700","Record once, select from fingerprints thereafter",[165,181],{"x":182,"y":183,"width":184,"height":185,"rx":186,"fill":187,"stroke":163,"strokeWidth":188},"26","60","200","80","11","#f4f1de","1.6",[93,190,194],{"x":191,"y":192,"textAnchor":176,"fontSize":193,"fontWeight":178,"fill":163},"126","88","12","full run",[93,196,198],{"x":191,"y":197,"textAnchor":176,"fontSize":186,"fill":163},"110","coverage per test",[68,200],{"x1":201,"y1":202,"x2":203,"y2":202,"stroke":163,"strokeWidth":188,"markerEnd":204},"230","100","264","url(#tm-a)",[165,206],{"x":207,"y":183,"width":184,"height":185,"rx":186,"fill":208,"stroke":209,"strokeWidth":210},"270","#f7f0da","#f2cc8f","2",[93,212,214],{"x":213,"y":192,"textAnchor":176,"fontSize":193,"fontWeight":178,"fill":163},"370",".testmondata",[93,216,218],{"x":213,"y":197,"textAnchor":176,"fontSize":186,"fill":217},"#8a5a00","test → code fingerprints",[68,220],{"x1":221,"y1":202,"x2":222,"y2":202,"stroke":163,"strokeWidth":188,"markerEnd":204},"474","508",[165,224],{"x":225,"y":183,"width":226,"height":185,"rx":186,"fill":227,"stroke":228,"strokeWidth":210},"514","280","#e6f0ea","#81b29a",[93,230,232],{"x":231,"y":192,"textAnchor":176,"fontSize":193,"fontWeight":178,"fill":163},"654","next run",[93,234,236],{"x":231,"y":197,"textAnchor":176,"fontSize":186,"fill":235},"#2a5f49","changed blocks → affected tests",[165,238],{"x":182,"y":239,"width":240,"height":241,"rx":186,"fill":242,"stroke":243,"strokeWidth":210},"164","768","76","#fbe9e3","#e07a5f",[93,245,248],{"x":246,"y":247,"fontSize":193,"fontWeight":178,"fill":163},"46","190","what fingerprints cannot see",[93,250,253],{"x":246,"y":251,"fontSize":186,"fill":252},"214","#8f3d22","config and data files · dependency upgrades · environment variables · C extensions",[93,255,257],{"x":246,"y":256,"fontSize":186,"fill":163},"232","a change to any of these may affect tests whose recorded Python lines did not change",[259,260,261],"figcaption",{},"The upper row is why the tool is fast. The lower box is why it cannot be the only gate.",[22,263,265],{"id":264},"why-this-works","Why this works",[10,267,268,269,272,273,275],{},"During a ",[14,270,271],{},"--testmon"," run, the plugin uses ",[14,274,44],{}," to trace which code blocks each test executes, and stores a fingerprint of those blocks per test in a SQLite database. On a later run it fingerprints the current source, compares, and marks as affected every test whose recorded blocks have changed. Unchanged tests are deselected, and whole files whose tests are all unaffected are skipped at collection, which is where most of the time saving comes from.",[10,277,278],{},"The fingerprinting is block-level rather than file-level, so editing one function in a large module selects only the tests that executed that function — not every test that imported the module. That granularity is what makes the selections small enough to be useful.",[22,280,282],{"id":281},"edge-cases-and-failure-modes","Edge cases and failure modes",[27,284,285,292,298,304,310],{},[30,286,287,291],{},[288,289,290],"strong",{},"Non-Python inputs."," A change to a YAML fixture, a SQL migration or a template affects tests without changing any traced Python line. testmon does not see it; run the relevant tests explicitly or the full suite.",[30,293,294,297],{},[288,295,296],{},"Dependency upgrades."," A new version of a library changes behaviour with no change to your source. Invalidate the database, or run everything, whenever the lockfile changes.",[30,299,300,303],{},[288,301,302],{},"Tests with cross-test state."," If test B depends on state left by test A, running B alone because only its code changed can produce a failure — or hide one. testmon exposes order dependence; fix it rather than working around it.",[30,305,306,309],{},[288,307,308],{},"Coverage overhead on the recording run."," Tracing slows the full run noticeably. Record on a schedule or on merge rather than on every CI job.",[30,311,312,315,316,318],{},[288,313,314],{},"A stale database in CI."," Without the cached ",[14,317,214],{},", every CI run selects everything. Restore it from the main branch's last run.",[22,320,322],{"id":321},"using-it-in-ci-without-losing-safety","Using it in CI without losing safety",[10,324,325],{},"In CI, testmon is most valuable on pull requests, where the change is small and feedback speed matters, and least safe as the final word on whether a change can merge. The arrangement that captures the benefit and bounds the risk has three parts.",[10,327,328,329,331,332,334],{},"On merges to the main branch, run the full suite with ",[14,330,271],{},", which both verifies everything and refreshes the database. Cache the resulting ",[14,333,214],{}," keyed on the main branch's commit.",[10,336,337,338,340],{},"On pull requests, restore that cache and run with ",[14,339,271],{},". The selection is computed against main, so the run executes exactly the tests the pull request's changes could affect. Most pull requests finish in a fraction of the full suite's time.",[10,342,343],{},"Before merge — in the merge queue, or as a required nightly — run the full suite without selection. That catches everything testmon cannot see: configuration changes, dependency bumps, data files, and interactions that coverage tracing misses.",[124,345,347,442],{"className":346},[127],[129,348,137,353,137,356,137,359,137,366,137,370,137,375,137,381,137,387,137,391,137,395,137,398,137,403,137,407,137,410,137,414,137,417,137,420,137,424,137,427,137,431,137,435,137,438],{"viewBox":349,"role":132,"ariaLabelledBy":350,"xmlns":136},"0 0 800 236",[351,352],"tmci-t","tmci-d",[139,354,355],{"id":351},"testmon in a CI pipeline",[143,357,358],{"id":352},"Merges to main run the full suite with testmon and cache the refreshed database. Pull requests restore that cache and run only the affected tests for fast feedback. The merge queue or a nightly job runs the full suite without selection to catch changes coverage tracing cannot see.",[147,360,149,361,137],{},[151,362,364],{"id":363,"viewBox":154,"refX":155,"refY":156,"markerWidth":157,"markerHeight":157,"orient":158},"tmci-a",[160,365],{"d":162,"fill":163},[165,367],{"x":167,"y":167,"width":368,"height":369,"rx":170,"fill":171},"800","236",[93,371,374],{"x":372,"y":175,"textAnchor":176,"fontSize":373,"fontWeight":178,"fill":163},"400","15.5","Fast where it is safe, full where it matters",[165,376],{"x":377,"y":378,"width":379,"height":380,"rx":193,"fill":208,"stroke":209,"strokeWidth":210},"24","56","240","140",[93,382,386],{"x":383,"y":384,"textAnchor":176,"fontSize":385,"fontWeight":178,"fill":163},"144","82","12.5","merge to main",[93,388,390],{"x":389,"y":197,"fontSize":186,"fill":163},"40","full run with --testmon",[93,392,394],{"x":389,"y":393,"fontSize":186,"fill":163},"132","refreshes the database",[93,396,397],{"x":389,"y":239,"fontSize":186,"fill":217},"cache .testmondata",[68,399],{"x1":400,"y1":191,"x2":401,"y2":191,"stroke":163,"strokeWidth":188,"markerEnd":402},"268","294","url(#tmci-a)",[165,404],{"x":405,"y":378,"width":406,"height":380,"rx":193,"fill":227,"stroke":228,"strokeWidth":210},"300","220",[93,408,409],{"x":174,"y":384,"textAnchor":176,"fontSize":385,"fontWeight":178,"fill":163},"pull request",[93,411,413],{"x":412,"y":197,"fontSize":186,"fill":163},"316","restore the cache",[93,415,416],{"x":412,"y":393,"fontSize":186,"fill":163},"run affected tests only",[93,418,419],{"x":412,"y":239,"fontSize":186,"fill":235},"minutes → seconds",[68,421],{"x1":422,"y1":191,"x2":423,"y2":191,"stroke":163,"strokeWidth":188,"markerEnd":402},"524","550",[165,425],{"x":426,"y":378,"width":406,"height":380,"rx":193,"fill":242,"stroke":243,"strokeWidth":210},"556",[93,428,430],{"x":429,"y":384,"textAnchor":176,"fontSize":385,"fontWeight":178,"fill":163},"666","merge queue",[93,432,434],{"x":433,"y":197,"fontSize":186,"fill":163},"572","full run, no selection",[93,436,437],{"x":433,"y":393,"fontSize":186,"fill":163},"catches config, data,",[93,439,441],{"x":433,"y":440,"fontSize":186,"fill":163},"154","and dependency changes",[259,443,444],{},"Selection shortens the feedback loop; the full run keeps the gate honest. Dropping the right-hand box is the configuration that eventually ships a bug.",[22,446,448],{"id":447},"covering-the-inputs-testmon-cannot-see","Covering the inputs testmon cannot see",[10,450,451],{},"The blind spots are predictable, which means they can be covered by rule rather than left to chance. Three categories account for nearly every case where testmon's selection is wrong.",[10,453,454,457,458,461,462,465],{},[288,455,456],{},"Files the tests read at runtime"," — JSON fixtures, SQL files, templates, YAML configuration. A change to one affects every test that loads it, but no Python line changed. The simplest cover is a CI rule: if any file under ",[14,459,460],{},"tests\u002Fdata\u002F"," or ",[14,463,464],{},"config\u002F"," changed, skip selection and run everything. testmon's own configuration can also be told about additional dependency files, which is more precise where it is supported.",[10,467,468,471,472,475,476,461,479,482],{},[288,469,470],{},"The dependency set"," — a lockfile change can alter behaviour anywhere. Treat any change to ",[14,473,474],{},"poetry.lock",", ",[14,477,478],{},"uv.lock",[14,480,481],{},"requirements*.txt"," as a reason to run the full suite and rebuild the database.",[10,484,485,488],{},[288,486,487],{},"The environment"," — interpreter version, environment variables, feature flags set outside the code. These rarely change within a pull request, but when a CI image is updated the database recorded under the old image is no longer trustworthy. Keying the cache on the image version as well as the branch removes that risk.",[124,490,492,533],{"className":491},[127],[129,493,137,498,137,501,137,504,137,507,137,510,137,515,137,520,137,523,137,526,137,529],{"viewBox":494,"role":132,"ariaLabelledBy":495,"xmlns":136},"0 0 800 234",[496,497],"blind-t","blind-d",[139,499,500],{"id":496},"Rules that cover testmon's blind spots",[143,502,503],{"id":497},"Three rows. When data or configuration files change, run the full suite. When the lockfile changes, run the full suite and rebuild the database. When the CI image changes, invalidate the cached database by keying it on the image version. Otherwise, selection applies.",[165,505],{"x":167,"y":167,"width":368,"height":506,"rx":170,"fill":171},"234",[93,508,509],{"x":372,"y":175,"textAnchor":176,"fontSize":373,"fontWeight":178,"fill":163},"Three rules, then trust the selection",[165,511],{"x":182,"y":512,"width":513,"height":246,"rx":514,"fill":242,"stroke":243,"strokeWidth":210},"50","748","10",[93,516,519],{"x":246,"y":517,"fontSize":518,"fill":163},"78","11.5","tests\u002Fdata\u002F or config\u002F changed → run everything",[165,521],{"x":182,"y":522,"width":513,"height":246,"rx":514,"fill":208,"stroke":209,"strokeWidth":210},"104",[93,524,525],{"x":246,"y":393,"fontSize":518,"fill":163},"lockfile changed → run everything and rebuild .testmondata",[165,527],{"x":182,"y":528,"width":513,"height":246,"rx":514,"fill":187,"stroke":163,"strokeWidth":188},"158",[93,530,532],{"x":246,"y":531,"fontSize":518,"fill":163},"186","CI image changed → cache key includes the image version, so the database resets",[259,534,535],{},"With these three rules in the pipeline, the remaining risk is small enough that a nightly full run covers it comfortably.",[10,537,538,539,541],{},"The rules are cheap to implement because CI systems already know which files a change touched. A few lines in the pipeline definition that check the changed paths and choose between ",[14,540,271],{}," and a full run give the speed of selection for ordinary code changes and the safety of a full run for exactly the changes selection cannot reason about.",[22,543,545],{"id":544},"what-selection-reveals-about-a-suite","What selection reveals about a suite",[10,547,548],{},"An unexpected side effect of adopting testmon is that it exposes problems a full run hides. The most common is order dependence. A test that passes in the full run because an earlier test left the database, a cache or a module-level variable in a helpful state will fail when testmon selects it alone, and the failure looks like a regression in whatever code the developer just changed.",[10,550,551],{},"That is uncomfortable the first few times and valuable thereafter. Every such failure is a genuine isolation bug — the test was never self-contained, it was only ever passing by accident of ordering — and fixing it makes the suite more reliable under parallel execution and random ordering as well. Teams that adopt testmon typically find and fix a handful of these in the first week and then rarely see another.",[10,553,554],{},"The second thing selection reveals is how much of the suite exercises any given piece of code. A function whose change selects four hundred tests is either central to the system or tested far more redundantly than necessary, and the testmon output makes that visible at every edit. It is a rough but useful signal for where a suite has accumulated overlapping tests that could be consolidated, which is the kind of maintenance that otherwise never gets prioritised because nobody can see where the redundancy is.",[22,556,558],{"id":557},"frequently-asked-questions","Frequently Asked Questions",[10,560,561,564],{},[288,562,563],{},"How does testmon know which tests a change affects?","\nIt records, for every test, which lines of which files executed while it ran, and stores the fingerprint in a local database. On the next run it compares the current source against those fingerprints and selects only the tests whose recorded code changed.",[10,566,567,570],{},[288,568,569],{},"Is it safe to use testmon in CI as the only test run?","\nNot as the only one. Coverage-based selection misses changes that affect behaviour without changing executed Python lines — configuration files, data files, dependency upgrades, environment variables. Use it for fast feedback and keep a full run on merge or nightly.",[10,572,573,576,577,579],{},[288,574,575],{},"Where is the dependency data stored?","\nIn a ",[14,578,214],{}," SQLite file in the project root. Locally it persists between runs; in CI it must be cached and restored between jobs or every run starts from nothing and selects everything.",[22,581,583],{"id":582},"related","Related",[27,585,586,594,601,608],{},[30,587,588,593],{},[589,590,592],"a",{"href":591},"\u002Fadvanced-pytest-architecture-configuration\u002Foptimizing-test-discovery\u002F","Optimizing Test Discovery"," — the collection costs testmon avoids for unaffected files.",[30,595,596,600],{},[589,597,599],{"href":598},"\u002Fadvanced-pytest-architecture-configuration\u002Foptimizing-test-discovery\u002Fsharding-a-test-suite-across-ci-runners\u002F","Sharding a Test Suite Across CI Runners"," — the complementary way to make the full run fast.",[30,602,603,607],{},[589,604,606],{"href":605},"\u002Fsystematic-debugging-performance-profiling\u002Fdebugging-tests-in-ci-and-containers\u002Fbisecting-test-order-dependencies\u002F","Bisecting Test-Order Dependencies"," — the cross-test state that selection tends to expose.",[30,609,610,614],{},[589,611,613],{"href":612},"\u002Fadvanced-pytest-architecture-configuration\u002Fcoverage-measurement-and-enforcement\u002Fenforcing-diff-coverage-on-pull-requests\u002F","Enforcing Diff Coverage on Pull Requests"," — another use of per-change coverage data.",[10,616,617,618],{},"← Back to ",[589,619,592],{"href":591},[621,622,623],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":62,"searchDepth":76,"depth":76,"links":625},[626,627,628,629,630,631,632,633,634],{"id":24,"depth":76,"text":25},{"id":51,"depth":76,"text":52},{"id":264,"depth":76,"text":265},{"id":281,"depth":76,"text":282},{"id":321,"depth":76,"text":322},{"id":447,"depth":76,"text":448},{"id":544,"depth":76,"text":545},{"id":557,"depth":76,"text":558},{"id":582,"depth":76,"text":583},"Run only the tests affected by a change using pytest-testmon's coverage-based dependency database: local loops, CI usage, cache invalidation, and where selection is unsafe.","md",{"slug":638,"type":639,"breadcrumb":16,"datePublished":640,"dateModified":640,"faq":641,"howto":648},"selecting-affected-tests-with-pytest-testmon","article","2026-09-18",[642,644,646],{"q":563,"a":643},"It records, for every test, which lines of which files executed while it ran, and stores the fingerprint in a local database. On the next run it compares the current source against those fingerprints and selects only the tests whose recorded code changed.",{"q":569,"a":645},"Not as the only one. Coverage-based selection misses changes that affect behaviour without changing executed Python lines — configuration files, data files, dependency upgrades, environment variables. Use it for fast feedback and keep a full run on merge or nightly.",{"q":575,"a":647},"In a .testmondata SQLite file in the project root. Locally it persists between runs; in CI it must be cached and restored between jobs or every run starts from nothing and selects everything.",{"name":649,"description":650,"steps":651},"How to use pytest-testmon for affected-test selection","Build the dependency database with a full run, then let testmon select tests from code changes, keeping a periodic full run as the safety net.",[652,655,658,661,664],{"name":653,"text":654},"Install and seed the database","Run pytest --testmon once on a clean tree so every test's dependencies are recorded.",{"name":656,"text":657},"Use it in the local loop","Re-run pytest --testmon after each edit; only affected tests execute.",{"name":659,"text":660},"Account for non-Python inputs","Tell testmon about data and configuration files the tests depend on, or run the full suite when they change.",{"name":662,"text":663},"Cache the database in CI","Restore .testmondata from the main branch so pull-request runs select against a known baseline.",{"name":665,"text":666},"Keep a full run as the safety net","Run the entire suite on merge or nightly to catch what coverage-based selection cannot see.",true,"\u002Fadvanced-pytest-architecture-configuration\u002Foptimizing-test-discovery\u002Fselecting-affected-tests-with-pytest-testmon",{"title":5,"description":635},"advanced-pytest-architecture-configuration\u002Foptimizing-test-discovery\u002Fselecting-affected-tests-with-pytest-testmon\u002Findex","9jigj5LGAq7pkWyAJSO7-VfhFh5IHwcasnPFzbFdVLE",1789718768738]