[{"data":1,"prerenderedAt":2120},["ShallowReactive",2],{"page-\u002Frust\u002F21-testing":3},{"id":4,"title":5,"body":6,"description":35,"extension":2114,"meta":2115,"navigation":108,"path":2116,"seo":2117,"stem":2118,"__hash__":2119},"content\u002Frust\u002F21-testing.md","21 — Testing",{"type":7,"value":8,"toc":2075},"minimark",[9,13,196,286,381,565,644,712,867,965,1054,1139,1256,1329,1430,1542,1620,1716,1787,1907,1981,2071],[10,11,5],"h1",{"id":12},"_21-testing",[14,15,17,27,95,136],"question-wrapper",{"language":16},"rust",[18,19,21,22,26],"h3",{"id":20},"q1-what-does-the-test-attribute-do","Q1. What does the ",[23,24,25],"code",{},"#[test]"," attribute do?",[28,29,30],"code-wrapper",{"language":16},[31,32,36],"pre",{"className":33,"code":34,"language":16,"meta":35,"style":35},"language-rust shiki shiki-themes github-light github-dark","#[test]\nfn adds_two() {\n    assert_eq!(2 + 2, 4);\n}\n","",[23,37,38,47,61,89],{"__ignoreMap":35},[39,40,43],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"ssxIu","#[test]\n",[39,48,50,54,58],{"class":41,"line":49},2,[39,51,53],{"class":52},"svdQ7","fn",[39,55,57],{"class":56},"sIsaT"," adds_two",[39,59,60],{"class":45},"() {\n",[39,62,64,67,70,74,77,80,83,86],{"class":41,"line":63},3,[39,65,66],{"class":56},"    assert_eq!",[39,68,69],{"class":45},"(",[39,71,73],{"class":72},"snvgF","2",[39,75,76],{"class":52}," +",[39,78,79],{"class":72}," 2",[39,81,82],{"class":45},", ",[39,84,85],{"class":72},"4",[39,87,88],{"class":45},");\n",[39,90,92],{"class":41,"line":91},4,[39,93,94],{"class":45},"}\n",[96,97,100,114,124,130],"ul",{"className":98},[99],"contains-task-list",[101,102,105,110,111],"li",{"className":103},[104],"task-list-item",[106,107],"input",{"disabled":108,"type":109},true,"checkbox"," It marks the function to run automatically before ",[23,112,113],{},"main",[101,115,117,119,120,123],{"className":116},[104],[106,118],{"disabled":108,"type":109}," It marks the function as a test case that ",[23,121,122],{},"cargo test"," discovers and runs as its own isolated execution",[101,125,127,129],{"className":126},[104],[106,128],{"disabled":108,"type":109}," It disables the function in release builds only",[101,131,133,135],{"className":132},[104],[106,134],{"disabled":108,"type":109}," It generates documentation from the function's body",[137,138,139,143,153],"details",{},[140,141,142],"summary",{},"Show Answer",[144,145,146,150,151,123],"p",{},[147,148,149],"strong",{},"Answer:"," B — It marks the function as a test case that ",[23,152,122],{},[144,154,155,158,159,161,162,164,165,167,168,170,171,173,174,178,179,181,182,185,186,188,189,192,193,195],{},[147,156,157],{},"Explanation:"," ",[23,160,25],{}," registers a function with the built-in test harness; ",[23,163,122],{}," compiles a special test binary that runs every ",[23,166,25],{},"-annotated function, each in its own thread by default, reporting pass\u002Ffail per test. It has nothing to do with ",[23,169,113],{}," startup order (rules out A) — test binaries don't even have the crate's normal ",[23,172,113],{},". It's excluded from ",[175,176,177],"em",{},"normal"," (non-test) builds entirely, not just release builds specifically (rules out C, ",[23,180,25],{}," code is compiled out unless ",[23,183,184],{},"cfg(test)"," is active, which happens for ",[23,187,122],{}," regardless of debug\u002Frelease). Doc generation is ",[23,190,191],{},"\u002F\u002F\u002F"," doc comments, unrelated to ",[23,194,25],{}," (rules out D).",[14,197,198,210,240],{},[18,199,201,202,205,206,209],{"id":200},"q2-why-is-cfgtest-commonly-placed-on-a-mod-tests-block-containing-unit-tests","Q2. Why is ",[23,203,204],{},"#[cfg(test)]"," commonly placed on a ",[23,207,208],{},"mod tests { ... }"," block containing unit tests?",[96,211,213,219,225,234],{"className":212},[99],[101,214,216,218],{"className":215},[104],[106,217],{"disabled":108,"type":109}," It makes the tests run in parallel instead of sequentially",[101,220,222,224],{"className":221},[104],[106,223],{"disabled":108,"type":109}," It ensures the test module (and everything inside it, including test-only imports) is compiled only when building for testing, not in normal builds",[101,226,228,230,231],{"className":227},[104],[106,229],{"disabled":108,"type":109}," It is required syntax for any function using ",[23,232,233],{},"assert_eq!",[101,235,237,239],{"className":236},[104],[106,238],{"disabled":108,"type":109}," It hides the test results from the terminal output",[137,241,242,244,249],{},[140,243,142],{},[144,245,246,248],{},[147,247,149],{}," B — It ensures the test module (and everything inside it, including test-only imports) is compiled only when building for testing, not in normal builds",[144,250,251,158,253,255,256,259,260,262,263,266,267,269,270,272,273,276,277,279,280,283,284,195],{},[147,252,157],{},[23,254,204],{}," is conditional compilation: the annotated item only exists in builds where the ",[23,257,258],{},"test"," cfg flag is set, which ",[23,261,122],{}," sets automatically. Wrapping unit tests in a ",[23,264,265],{},"#[cfg(test)] mod tests { use super::*; ... }"," block means test code, test-only dependencies, and test helper functions never bloat or ship in the production binary. It's unrelated to test parallelism, which is a ",[23,268,122],{}," runtime behavior controlled separately (rules out A, see also the test-isolation question later in this file). ",[23,271,233],{}," works in any function regardless of ",[23,274,275],{},"cfg"," (rules out C). Output visibility is controlled by ",[23,278,122],{}," flags like ",[23,281,282],{},"--nocapture",", not by ",[23,285,184],{},[14,287,288,296,345],{},[18,289,291,292,295],{"id":290},"q3-where-do-rust-integration-tests-live-and-how-do-they-differ-from-unit-tests-in-src","Q3. Where do Rust integration tests live, and how do they differ from unit tests in ",[23,293,294],{},"src\u002F","?",[96,297,299,309,326,332],{"className":298},[99],[101,300,302,304,305,308],{"className":301},[104],[106,303],{"disabled":108,"type":109}," In ",[23,306,307],{},"src\u002Ftests\u002F",", and they have access to private items just like unit tests",[101,310,312,314,315,318,319,321,322,325],{"className":311},[104],[106,313],{"disabled":108,"type":109}," In a top-level ",[23,316,317],{},"tests\u002F"," directory (sibling to ",[23,320,294],{},"); each file there is compiled as its own separate crate that can only call the library's ",[23,323,324],{},"pub"," API, not its private internals",[101,327,329,331],{"className":328},[104],[106,330],{"disabled":108,"type":109}," Integration tests and unit tests are the same thing in Rust — there's no distinction",[101,333,335,304,337,340,341,344],{"className":334},[104],[106,336],{"disabled":108,"type":109},[23,338,339],{},"Cargo.toml",", as declarative ",[23,342,343],{},"[[test]]"," blocks with no Rust code",[137,346,347,349,360],{},[140,348,142],{},[144,350,351,353,354,318,356,321,358,325],{},[147,352,149],{}," B — In a top-level ",[23,355,317],{},[23,357,294],{},[23,359,324],{},[144,361,362,364,365,368,369,371,372,374,375,377,378,380],{},[147,363,157],{}," Cargo automatically treats every ",[23,366,367],{},".rs"," file directly inside ",[23,370,317],{}," as an independent test crate that depends on and links against your library crate exactly like an external consumer would — meaning it exercises only the public API, which is valuable for catching \"this only works because a test reaches into internals\" bugs. A is wrong about location and about access — putting a file in ",[23,373,307],{}," doesn't grant it the \"separate crate, public-API-only\" property that defines integration tests; that's purely a ",[23,376,317],{},"-directory behavior. C conflates two genuinely different testing layers Rust distinguishes on purpose. D misunderstands the mechanism — no manifest declaration is needed; Cargo's ",[23,379,317],{}," convention is filesystem-based and automatic.",[14,382,383,390,477,517],{"language":16},[18,384,386,387,389],{"id":385},"q4-do-doctests-code-examples-in-documentation-comments-actually-get-executed","Q4. Do doctests (code examples in ",[23,388,191],{}," documentation comments) actually get executed?",[28,391,392],{"language":16},[31,393,395],{"className":33,"code":394,"language":16,"meta":35,"style":35},"\u002F\u002F\u002F Adds one to the given number.\n\u002F\u002F\u002F\n\u002F\u002F\u002F ```\n\u002F\u002F\u002F let x = my_crate::add_one(2);\n\u002F\u002F\u002F assert_eq!(x, 3);\n\u002F\u002F\u002F ```\npub fn add_one(x: i32) -> i32 {\n    x + 1\n}\n",[23,396,397,403,408,413,418,424,429,460,472],{"__ignoreMap":35},[39,398,399],{"class":41,"line":42},[39,400,402],{"class":401},"sdCPZ","\u002F\u002F\u002F Adds one to the given number.\n",[39,404,405],{"class":41,"line":49},[39,406,407],{"class":401},"\u002F\u002F\u002F\n",[39,409,410],{"class":41,"line":63},[39,411,412],{"class":401},"\u002F\u002F\u002F ```\n",[39,414,415],{"class":41,"line":91},[39,416,417],{"class":401},"\u002F\u002F\u002F let x = my_crate::add_one(2);\n",[39,419,421],{"class":41,"line":420},5,[39,422,423],{"class":401},"\u002F\u002F\u002F assert_eq!(x, 3);\n",[39,425,427],{"class":41,"line":426},6,[39,428,412],{"class":401},[39,430,432,434,437,440,443,446,449,452,455,457],{"class":41,"line":431},7,[39,433,324],{"class":52},[39,435,436],{"class":52}," fn",[39,438,439],{"class":56}," add_one",[39,441,442],{"class":45},"(x",[39,444,445],{"class":52},":",[39,447,448],{"class":56}," i32",[39,450,451],{"class":45},") ",[39,453,454],{"class":52},"->",[39,456,448],{"class":56},[39,458,459],{"class":45}," {\n",[39,461,463,466,469],{"class":41,"line":462},8,[39,464,465],{"class":45},"    x ",[39,467,468],{"class":52},"+",[39,470,471],{"class":72}," 1\n",[39,473,475],{"class":41,"line":474},9,[39,476,94],{"class":45},[96,478,480,486,499,505],{"className":479},[99],[101,481,483,485],{"className":482},[104],[106,484],{"disabled":108,"type":109}," No — they're purely illustrative text, never compiled or run",[101,487,489,491,492,494,495,498],{"className":488},[104],[106,490],{"disabled":108,"type":109}," Yes — ",[23,493,122],{}," compiles and runs every fenced code block in a doc comment as its own test, unless the block is explicitly marked otherwise (e.g. ",[23,496,497],{},"```ignore",")",[101,500,502,504],{"className":501},[104],[106,503],{"disabled":108,"type":109}," They're only checked for correct Markdown syntax, not compiled",[101,506,508,510,511,514,515],{"className":507},[104],[106,509],{"disabled":108,"type":109}," They run only when ",[23,512,513],{},"cargo doc"," is invoked, never during ",[23,516,122],{},[137,518,519,521,530],{},[140,520,142],{},[144,522,523,525,526,494,528,498],{},[147,524,149],{}," B — Yes — ",[23,527,122],{},[23,529,497],{},[144,531,532,534,535,537,538,541,542,545,546,548,549,551,552,554,555,558,559,561,562,564],{},[147,533,157],{}," Doctests are real, executable tests: ",[23,536,122],{}," extracts each ",[23,539,540],{},"```"," fenced block from doc comments, wraps it in an implicit ",[23,543,544],{},"fn main()"," if needed, compiles it as its own tiny binary linked against the crate's public API, and runs it — an ",[23,547,233],{}," failure or panic inside one fails the test suite just like a ",[23,550,25],{}," function would. This is a genuine gotcha for newcomers who assume doc examples are \"just comments\" (option A) and are surprised when a stale example breaks CI. Fences can opt out with annotations like ",[23,553,497],{}," or ",[23,556,557],{},"```text"," (rules out the idea that all blocks always run unconditionally, though the default is that they do). It's not merely a syntax\u002Flint check (rules out C), and doctests run under ",[23,560,122],{},", independent of whether ",[23,563,513],{}," is ever invoked (rules out D).",[14,566,567,578,608],{},[18,568,570,571,574,575,577],{"id":569},"q5-what-does-should_panic-do-when-applied-to-a-test-function","Q5. What does ",[23,572,573],{},"#[should_panic]"," do when applied to a ",[23,576,25],{}," function?",[96,579,581,587,593,599],{"className":580},[99],[101,582,584,586],{"className":583},[104],[106,585],{"disabled":108,"type":109}," It suppresses panic output so the test suite doesn't print a stack trace",[101,588,590,592],{"className":589},[104],[106,591],{"disabled":108,"type":109}," It asserts the test function must panic for the test to be considered passing; if the function returns normally, the test fails",[101,594,596,598],{"className":595},[104],[106,597],{"disabled":108,"type":109}," It marks the test as expected to fail and skips it",[101,600,602,604,605],{"className":601},[104],[106,603],{"disabled":108,"type":109}," It catches the panic and converts it into a ",[23,606,607],{},"Result::Err",[137,609,610,612,617],{},[140,611,142],{},[144,613,614,616],{},[147,615,149],{}," B — It asserts the test function must panic for the test to be considered passing; if the function returns normally, the test fails",[144,618,619,158,621,623,624,627,628,631,632,635,636,639,640,643],{},[147,620,157],{},[23,622,573],{}," inverts the usual pass condition: the test harness runs the function expecting a panic, marks the test as passed if one occurs, and — importantly — marks it as ",[175,625,626],{},"failed"," if the function completes without panicking. It's commonly paired with ",[23,629,630],{},"expected = \"substring\""," to also verify the panic message matches, catching the case where the function panics for the wrong reason. It doesn't just silence output (rules out A) — panic details still print by default so you can see what happened. It's not the same as ",[23,633,634],{},"#[ignore]",", which actually skips a test rather than expecting a panic (rules out C). And it doesn't convert anything into ",[23,637,638],{},"Result"," — that's a different, non-panicking test convention (",[23,641,642],{},"fn test() -> Result\u003C(), String>",") entirely (rules out D).",[14,645,646,653,680],{},[18,647,649,650,652],{"id":648},"q6-how-does-cargo-test-run-multiple-test-functions-by-default","Q6. How does ",[23,651,122],{}," run multiple test functions by default?",[96,654,656,662,668,674],{"className":655},[99],[101,657,659,661],{"className":658},[104],[106,660],{"disabled":108,"type":109}," Sequentially, one at a time, in the order they appear in the source file",[101,663,665,667],{"className":664},[104],[106,666],{"disabled":108,"type":109}," In parallel across multiple threads, so tests should not assume exclusive access to shared external state (files, env vars, ports) unless they coordinate",[101,669,671,673],{"className":670},[104],[106,672],{"disabled":108,"type":109}," In a random, single-threaded order",[101,675,677,679],{"className":676},[104],[106,678],{"disabled":108,"type":109}," All tests run in one shared thread but interleaved via async cooperative scheduling",[137,681,682,684,689],{},[140,683,142],{},[144,685,686,688],{},[147,687,149],{}," B — In parallel across multiple threads, so tests should not assume exclusive access to shared external state (files, env vars, ports) unless they coordinate",[144,690,691,693,694,696,697,700,701,704,705,708,709,711],{},[147,692,157],{}," By default, ",[23,695,122],{}," spins up a thread pool and runs test functions concurrently for speed, which is exactly why tests that mutate shared global state (a file on disk, a process-wide environment variable, a fixed network port, a ",[23,698,699],{},"static"," with interior mutability) can flake or corrupt each other unless they're made independent or explicitly serialized (e.g. ",[23,702,703],{},"--test-threads=1",", or a crate like ",[23,706,707],{},"serial_test","). This surprises people coming from test runners that default to sequential execution (option A). It's not randomized-but-single-threaded (rules out C), and it's plain OS-thread parallelism, not async scheduling (rules out D) — ",[23,710,122],{},"'s default harness has no async runtime involved.",[14,713,714,720,784,821],{"language":16},[18,715,717,718,295],{"id":716},"q7-what-is-the-simplest-way-to-check-that-a-function-returns-the-expected-value-in-a-test","Q7. What is the simplest way to check that a function returns the expected value in a ",[23,719,25],{},[28,721,722],{"language":16},[31,723,725],{"className":33,"code":724,"language":16,"meta":35,"style":35},"#[test]\nfn parses_valid_input() {\n    let result = parse(\"42\");\n    assert_eq!(result, Ok(42));\n}\n",[23,726,727,731,740,762,780],{"__ignoreMap":35},[39,728,729],{"class":41,"line":42},[39,730,46],{"class":45},[39,732,733,735,738],{"class":41,"line":49},[39,734,53],{"class":52},[39,736,737],{"class":56}," parses_valid_input",[39,739,60],{"class":45},[39,741,742,745,748,751,754,756,760],{"class":41,"line":63},[39,743,744],{"class":52},"    let",[39,746,747],{"class":45}," result ",[39,749,750],{"class":52},"=",[39,752,753],{"class":56}," parse",[39,755,69],{"class":45},[39,757,759],{"class":758},"sJ6F3","\"42\"",[39,761,88],{"class":45},[39,763,764,766,769,772,774,777],{"class":41,"line":91},[39,765,66],{"class":56},[39,767,768],{"class":45},"(result, ",[39,770,771],{"class":56},"Ok",[39,773,69],{"class":45},[39,775,776],{"class":72},"42",[39,778,779],{"class":45},"));\n",[39,781,782],{"class":41,"line":420},[39,783,94],{"class":45},[96,785,787,795,804,813],{"className":786},[99],[101,788,790,158,792,794],{"className":789},[104],[106,791],{"disabled":108,"type":109},[23,793,233],{},", which panics (failing the test) with a diff of the left and right values if they aren't equal",[101,796,798,158,800,803],{"className":797},[104],[106,799],{"disabled":108,"type":109},[23,801,802],{},"println!",", since printed output alone fails the test if incorrect",[101,805,807,158,809,812],{"className":806},[104],[106,808],{"disabled":108,"type":109},[23,810,811],{},"if result != Ok(42) { return; }",", which cargo interprets as a failure",[101,814,816,158,818,820],{"className":815},[104],[106,817],{"disabled":108,"type":109},[23,819,25],{}," functions cannot assert on return values, only on side effects",[137,822,823,825,832],{},[140,824,142],{},[144,826,827,829,830,794],{},[147,828,149],{}," A — ",[23,831,233],{},[144,833,834,836,837,839,840,843,844,846,847,846,850,853,854,856,857,859,860,862,863,866],{},[147,835,157],{}," The test harness considers a test failed if the function panics (or, for the ",[23,838,638],{},"-returning test convention, if it returns ",[23,841,842],{},"Err","); ",[23,845,233],{},"\u002F",[23,848,849],{},"assert_ne!",[23,851,852],{},"assert!"," are macros that panic with a helpful message (showing both compared values for ",[23,855,233],{},") when the condition doesn't hold, which is exactly what drives pass\u002Ffail. ",[23,858,802],{}," output alone is inert — the harness doesn't parse printed text to decide pass\u002Ffail, it only reacts to a panic or early ",[23,861,842],{}," (rules out B). Silently ",[23,864,865],{},"return","-ing early does not signal failure to the harness at all — the test would report as passed (rules out C), which is itself a subtle pitfall to watch for in hand-rolled test logic. Return-value assertions are the most common thing tests do; nothing prevents it (rules out D).",[14,868,869,876,897,940],{"language":16},[18,870,872,873,875],{"id":871},"q8-what-happens-when-a-test-function-is-empty-no-assertions-no-panics-just-an-empty-body","Q8. What happens when a ",[23,874,25],{}," function is empty (no assertions, no panics, just an empty body)?",[28,877,878],{"language":16},[31,879,881],{"className":33,"code":880,"language":16,"meta":35,"style":35},"#[test]\nfn todo_write_this_test() {}\n",[23,882,883,887],{"__ignoreMap":35},[39,884,885],{"class":41,"line":42},[39,886,46],{"class":45},[39,888,889,891,894],{"class":41,"line":49},[39,890,53],{"class":52},[39,892,893],{"class":56}," todo_write_this_test",[39,895,896],{"class":45},"() {}\n",[96,898,900,908,917,928],{"className":899},[99],[101,901,903,158,905,907],{"className":902},[104],[106,904],{"disabled":108,"type":109},[23,906,122],{}," fails it, requiring at least one assertion",[101,909,911,913,914,916],{"className":910},[104],[106,912],{"disabled":108,"type":109}," It reports as passing — an empty function neither panics nor returns ",[23,915,842],{},", so the harness has no reason to consider it failed, even though it verifies nothing",[101,918,920,922,923,925,926],{"className":919},[104],[106,921],{"disabled":108,"type":109}," It's a compile error — ",[23,924,25],{}," functions must contain at least one ",[23,927,852],{},[101,929,931,158,933,935,936,939],{"className":930},[104],[106,932],{"disabled":108,"type":109},[23,934,122],{}," marks it ",[23,937,938],{},"ignored"," automatically since it does nothing",[137,941,942,944,951],{},[140,943,142],{},[144,945,946,948,949,916],{},[147,947,149],{}," B — It reports as passing — an empty function neither panics nor returns ",[23,950,842],{},[144,952,953,955,956,958,959,961,962,964],{},[147,954,157],{}," The test harness's pass criterion is purely \"did this function panic or return ",[23,957,842],{},"\" — it has no concept of \"did this test actually check anything.\" A stub test left behind as a TODO will happily report green forever, which is a genuine production trap: a passing test suite can hide untested code paths behind empty or assertion-less test functions. Nothing in the language or ",[23,960,122],{}," enforces a minimum number of assertions (rules out A and C — there's no such compile-time requirement). ",[23,963,634],{}," is an explicit, separate opt-out attribute a developer must add themselves; it is never inferred from an empty body (rules out D).",[14,966,967,978,1009],{},[18,968,970,971,974,975,977],{"id":969},"q9-two-tests-both-write-to-the-same-hardcoded-file-path-tmpoutputtxt-then-assert-on-its-contents-running-cargo-test-default-parallel-execution-shows-intermittent-non-deterministic-failures-why","Q9. Two tests both write to the same hardcoded file path, ",[23,972,973],{},"\u002Ftmp\u002Foutput.txt",", then assert on its contents. Running ",[23,976,122],{}," (default parallel execution) shows intermittent, non-deterministic failures. Why?",[96,979,981,989,995,1001],{"className":980},[99],[101,982,984,158,986,988],{"className":983},[104],[106,985],{"disabled":108,"type":109},[23,987,122],{}," corrupts the filesystem when run in parallel",[101,990,992,994],{"className":991},[104],[106,993],{"disabled":108,"type":109}," The two tests race on the shared file — running concurrently on different threads, one test's write can interleave with or overwrite the other's before its own assertion reads the file back",[101,996,998,1000],{"className":997},[104],[106,999],{"disabled":108,"type":109}," Rust's file I\u002FO is not thread-safe at the language level, causing undefined behavior",[101,1002,1004,158,1006,1008],{"className":1003},[104],[106,1005],{"disabled":108,"type":109},[23,1007,233],{}," is not reentrant across threads",[137,1010,1011,1013,1018],{},[140,1012,142],{},[144,1014,1015,1017],{},[147,1016,149],{}," B — The two tests race on the shared file — running concurrently on different threads, one test's write can interleave with or overwrite the other's before its own assertion reads the file back",[144,1019,1020,1022,1023,1025,1026,1029,1030,1033,1034,554,1036,1039,1040,1042,1043,1046,1047,1050,1051,1053],{},[147,1021,157],{}," This is the canonical test-isolation pitfall: tests are expected to be independent, but a hardcoded shared resource (a fixed file path, a fixed port, a shared env var, a ",[23,1024,699],{}," counter) breaks that independence, and default parallel test execution turns the resulting race into a flaky, order-dependent failure that's hard to reproduce. ",[147,1027,1028],{},"Debug",": fixes include giving each test a unique temp path (e.g. via ",[23,1031,1032],{},"tempfile"," or a name derived from the test), serializing the offending tests (",[23,1035,703],{},[23,1037,1038],{},"#[serial]"," from ",[23,1041,707],{},"), or restructuring the test to avoid shared mutable external state entirely. Filesystem operations themselves aren't corrupted by concurrency at the OS level (rules out A); this isn't a language-level data race or UB — ",[23,1044,1045],{},"std::fs"," calls are ordinary syscalls, safe to call from multiple threads, they just aren't automatically ",[175,1048,1049],{},"coordinated"," for you (rules out C); and ",[23,1052,233],{}," is a plain macro with no reentrancy concept — the race is entirely in the shared file, not in the assertion (rules out D).",[14,1055,1056,1063,1103],{},[18,1057,1059,1060,1062],{"id":1058},"q10-what-does-ignore-do-on-a-test-function-and-how-do-you-run-ignored-tests","Q10. What does ",[23,1061,634],{}," do on a test function, and how do you run ignored tests?",[96,1064,1066,1074,1086,1095],{"className":1065},[99],[101,1067,1069,1071,1072],{"className":1068},[104],[106,1070],{"disabled":108,"type":109}," It permanently disables the test; there is no way to run it via ",[23,1073,122],{},[101,1075,1077,1079,1080,1082,1083],{"className":1076},[104],[106,1078],{"disabled":108,"type":109}," It excludes the test from the default ",[23,1081,122],{}," run, but it can still be run explicitly with ",[23,1084,1085],{},"cargo test -- --ignored",[101,1087,1089,1091,1092,1094],{"className":1088},[104],[106,1090],{"disabled":108,"type":109}," It's identical to deleting the ",[23,1093,25],{}," attribute",[101,1096,1098,1100,1101],{"className":1097},[104],[106,1099],{"disabled":108,"type":109}," It marks the test as expected to fail, similar to ",[23,1102,573],{},[137,1104,1105,1107,1116],{},[140,1106,142],{},[144,1108,1109,1111,1112,1082,1114],{},[147,1110,149],{}," B — It excludes the test from the default ",[23,1113,122],{},[23,1115,1085],{},[144,1117,1118,158,1120,1122,1123,1125,1126,1128,1129,1132,1133,1135,1136,1138],{},[147,1119,157],{},[23,1121,634],{}," is meant for tests that are valid but too slow, environment-dependent, or otherwise unsuitable to run on every default ",[23,1124,122],{}," invocation (e.g. tests that hit a real network service); they're skipped by default but remain runnable on demand via ",[23,1127,1085],{}," (or ",[23,1130,1131],{},"--include-ignored"," to run everything). It's not a permanent disable (rules out A) and not equivalent to removing ",[23,1134,25],{}," entirely, since the function is still recognized and reported as \"ignored\" rather than simply not existing as a test (rules out C). It has nothing to do with expecting a panic — that's ",[23,1137,573],{},"'s job, and the two attributes address unrelated concerns (rules out D).",[14,1140,1141,1152,1206],{},[18,1142,1144,1145,1148,1149,1151],{"id":1143},"q11-a-test-function-is-written-as-fn-returns_config-result-string-without-should_panic-what-determines-whether-this-test-passes","Q11. A test function is written as ",[23,1146,1147],{},"fn returns_config() -> Result\u003C(), String> { ... }"," without ",[23,1150,573],{},". What determines whether this test passes?",[96,1153,1155,1167,1188,1197],{"className":1154},[99],[101,1156,1158,1160,1161,1163,1164],{"className":1157},[104],[106,1159],{"disabled":108,"type":109}," It never passes, because ",[23,1162,25],{}," functions must return ",[23,1165,1166],{},"()",[101,1168,1170,1172,1173,1176,1177,1180,1181,1183,1184,1187],{"className":1169},[104],[106,1171],{"disabled":108,"type":109}," The harness treats ",[23,1174,1175],{},"Ok(())"," as pass and ",[23,1178,1179],{},"Err(_)"," as fail, letting the test use ",[23,1182,295],{}," to propagate errors instead of ",[23,1185,1186],{},"unwrap()","-triggered panics",[101,1189,1191,1193,1194,1196],{"className":1190},[104],[106,1192],{"disabled":108,"type":109}," Only the presence of the ",[23,1195,25],{}," attribute matters; the return type is ignored",[101,1198,1200,1202,1203,1205],{"className":1199},[104],[106,1201],{"disabled":108,"type":109}," It always fails at compile time because ",[23,1204,638],{}," cannot appear in test signatures",[137,1207,1208,1210,1223],{},[140,1209,142],{},[144,1211,1212,1214,1215,1176,1217,1180,1219,1183,1221,1187],{},[147,1213,149],{}," B — The harness treats ",[23,1216,1175],{},[23,1218,1179],{},[23,1220,295],{},[23,1222,1186],{},[144,1224,1225,1227,1228,1230,1231,1234,1235,1238,1239,1242,1243,1245,1246,1248,1249,1252,1253,1255],{},[147,1226,157],{}," Since Rust 2018, ",[23,1229,25],{}," functions may return any type implementing ",[23,1232,1233],{},"std::process::Termination",", most commonly ",[23,1236,1237],{},"Result\u003C(), E>"," where ",[23,1240,1241],{},"E: Debug"," — this lets test bodies use ",[23,1244,295],{}," on fallible operations and get a clean ",[23,1247,842],{}," printout on failure instead of a panic from ",[23,1250,1251],{},".unwrap()",". ",[23,1254,1166],{},"-returning tests are still the common case, but they aren't the only option (rules out A and D, both of which describe restrictions that don't exist). The return type is very much inspected by the harness to decide pass\u002Ffail — it isn't ignored (rules out C).",[14,1257,1258,1265,1300],{},[18,1259,1261,1262,1264],{"id":1260},"q12-what-happens-to-output-from-println-inside-a-passing-test-by-default","Q12. What happens to output from ",[23,1263,802],{}," inside a passing test, by default?",[96,1266,1268,1274,1283,1289],{"className":1267},[99],[101,1269,1271,1273],{"className":1270},[104],[106,1272],{"disabled":108,"type":109}," It always prints immediately to the terminal",[101,1275,1277,1279,1280,1282],{"className":1276},[104],[106,1278],{"disabled":108,"type":109}," The test harness captures (suppresses) stdout for passing tests by default; it's only shown for tests that fail, unless ",[23,1281,282],{}," is passed",[101,1284,1286,1288],{"className":1285},[104],[106,1287],{"disabled":108,"type":109}," It's written to a log file instead of the terminal",[101,1290,1292,158,1294,1296,1297,1299],{"className":1291},[104],[106,1293],{"disabled":108,"type":109},[23,1295,802],{}," cannot be used inside ",[23,1298,25],{}," functions at all",[137,1301,1302,1304,1311],{},[140,1303,142],{},[144,1305,1306,1308,1309,1282],{},[147,1307,149],{}," B — The test harness captures (suppresses) stdout for passing tests by default; it's only shown for tests that fail, unless ",[23,1310,282],{},[144,1312,1313,1315,1316,1318,1319,1321,1322,1325,1326,1328],{},[147,1314,157],{}," By default ",[23,1317,122],{}," captures each test's stdout\u002Fstderr and only surfaces it for tests that fail, keeping a clean summary for a large, mostly-passing suite; debugging with stray ",[23,1320,802],{},"s that never appear is a common early confusion (assumption A). Passing ",[23,1323,1324],{},"cargo test -- --nocapture"," disables this capturing so all output streams live regardless of pass\u002Ffail. There's no log-file redirection involved (rules out C), and ",[23,1327,802],{}," works perfectly fine inside tests — it's simply capture behavior, not a restriction on the macro itself (rules out D).",[14,1330,1331,1342,1386],{},[18,1332,1334,1335,1338,1339,1341],{"id":1333},"q13-a-unit-test-module-does-use-super-to-access-the-parent-modules-private-items-why-does-this-work-even-though-those-items-have-no-pub-modifier","Q13. A unit test module does ",[23,1336,1337],{},"use super::*;"," to access the parent module's private items. Why does this work even though those items have no ",[23,1340,324],{}," modifier?",[96,1343,1345,1355,1369,1377],{"className":1344},[99],[101,1346,1348,158,1350,1352,1353],{"className":1347},[104],[106,1349],{"disabled":108,"type":109},[23,1351,204],{}," implicitly makes every item in the crate ",[23,1354,324],{},[101,1356,1358,1360,1361,1364,1365,1368],{"className":1357},[104],[106,1359],{"disabled":108,"type":109}," The ",[23,1362,1363],{},"tests"," submodule is a ",[175,1366,1367],{},"child"," of the module it's testing, and Rust's privacy rule makes a module's private items visible to all of its descendants — the test module included",[101,1370,1372,158,1374,1376],{"className":1371},[104],[106,1373],{"disabled":108,"type":109},[23,1375,1337],{}," bypasses privacy checks as a special case for testing",[101,1378,1380,1382,1383],{"className":1379},[104],[106,1381],{"disabled":108,"type":109}," It only works if every tested item is additionally marked ",[23,1384,1385],{},"pub(crate)",[137,1387,1388,1390,1399],{},[140,1389,142],{},[144,1391,1392,1394,1395,1364,1397,1368],{},[147,1393,149],{}," B — The ",[23,1396,1363],{},[175,1398,1367],{},[144,1400,1401,1403,1404,1406,1407,1409,1410,158,1413,1416,1417,1419,1420,1422,1423,1426,1427,1429],{},[147,1402,157],{}," This is the same general privacy rule covered for modules generally: a private item is visible in its defining module and every module nested inside it, and ",[23,1405,208],{}," declared inside the module under test is exactly such a descendant — so ",[23,1408,1337],{}," can name and call private functions without any special-case testing behavior. This is precisely why unit tests conventionally live in a ",[23,1411,1412],{},"#[cfg(test)] mod tests",[175,1414,1415],{},"inside"," the same file as the code, while integration tests in ",[23,1418,317],{}," (a separate crate) deliberately cannot see private items — different levels of the module tree, different visibility outcomes. ",[23,1421,204],{}," only controls conditional compilation, not privacy (rules out A). There's no special glob-import privacy bypass (rules out C); ",[23,1424,1425],{},"use"," never overrides visibility, it can only bring already-visible items into scope. And no extra ",[23,1428,1385],{}," is required — plain private is already sufficient for a descendant module (rules out D).",[14,1431,1432,1453,1499],{},[18,1433,1435,1436,1438,1439,1442,1443,1446,1447,1449,1450,1452],{"id":1434},"q14-in-an-integration-test-file-under-tests-why-does-use-my_crateinternal_helper-fail-to-compile-if-internal_helper-is-a-pubcrate-not-pub-function-in-the-library","Q14. In an integration test file under ",[23,1437,317],{},", why does ",[23,1440,1441],{},"use my_crate::internal_helper;"," fail to compile if ",[23,1444,1445],{},"internal_helper"," is a ",[23,1448,1385],{}," (not ",[23,1451,324],{},") function in the library?",[96,1454,1456,1467,1479,1487],{"className":1455},[99],[101,1457,1459,158,1461,1463,1464,1466],{"className":1458},[104],[106,1460],{"disabled":108,"type":109},[23,1462,317],{}," files cannot use ",[23,1465,1425],{}," statements at all",[101,1468,1470,1472,1473,1475,1476,1478],{"className":1469},[104],[106,1471],{"disabled":108,"type":109}," Each file in ",[23,1474,317],{}," is compiled as an entirely separate crate consuming the library through its public API only; ",[23,1477,1385],{}," explicitly excludes visibility outside the defining crate, and the integration test is, from the compiler's perspective, a different crate",[101,1480,1482,158,1484,1486],{"className":1481},[104],[106,1483],{"disabled":108,"type":109},[23,1485,1385],{}," items are visible to integration tests but not unit tests",[101,1488,1490,1492,1493,1495,1496,1498],{"className":1489},[104],[106,1491],{"disabled":108,"type":109}," It's a typo-only issue; ",[23,1494,1385],{}," and ",[23,1497,324],{}," are otherwise identical",[137,1500,1501,1503,1512],{},[140,1502,142],{},[144,1504,1505,1507,1508,1475,1510,1478],{},[147,1506,149],{}," B — Each file in ",[23,1509,317],{},[23,1511,1385],{},[144,1513,1514,1516,1517,1519,1520,1522,1523,1526,1527,1529,1530,1532,1533,1536,1537,1495,1539,1541],{},[147,1515,157],{}," This directly follows from how ",[23,1518,317],{}," is set up (Q3): each file there is its own crate linked against the library the way any external consumer would be, so it is bound by the same rules any other downstream crate faces — ",[23,1521,1385],{}," items are, by definition, invisible past the crate boundary. This is actually a ",[175,1524,1525],{},"feature",": it forces integration tests to exercise the same API surface real users get, catching \"only works via internals\" bugs. ",[23,1528,1425],{}," is completely normal and necessary in ",[23,1531,317],{}," files (rules out A). Visibility rules aren't different for integration vs. unit tests as a special case — it's a direct consequence of crate boundaries, and it's the reverse of C (integration tests see ",[175,1534,1535],{},"less",", not more, than unit tests). ",[23,1538,1385],{},[23,1540,324],{}," differ precisely in this cross-crate reachability, which is the whole point, not a typo (rules out D).",[14,1543,1544,1548,1586],{},[18,1545,1547],{"id":1546},"q15-whats-the-idiomatic-way-to-organize-tests-that-need-expensive-shared-setup-eg-spinning-up-an-in-memory-database-without-letting-one-tests-mutations-leak-into-anothers-results","Q15. What's the idiomatic way to organize tests that need expensive shared setup (e.g., spinning up an in-memory database) without letting one test's mutations leak into another's results?",[96,1549,1551,1561,1567,1576],{"className":1550},[99],[101,1552,1554,1556,1557,1560],{"className":1553},[104],[106,1555],{"disabled":108,"type":109}," Use a single ",[23,1558,1559],{},"static mut"," database instance shared by all tests for efficiency",[101,1562,1564,1566],{"className":1563},[104],[106,1565],{"disabled":108,"type":109}," Have each test construct its own fresh, independent instance of the resource (or reset state at the start of each test), so tests remain independent even when run in parallel",[101,1568,1570,1572,1573,1575],{"className":1569},[104],[106,1571],{"disabled":108,"type":109}," Force all tests to run with ",[23,1574,703],{}," permanently as the default workaround",[101,1577,1579,1581,1582,1585],{"className":1578},[104],[106,1580],{"disabled":108,"type":109}," Put all setup logic in ",[23,1583,1584],{},"#[test] fn setup()"," and rely on test execution order to run it first",[137,1587,1588,1590,1595],{},[140,1589,142],{},[144,1591,1592,1594],{},[147,1593,149],{}," B — Have each test construct its own fresh, independent instance of the resource (or reset state at the start of each test), so tests remain independent even when run in parallel",[144,1596,1597,158,1599,1602,1603,1605,1606,1609,1610,1612,1613,1615,1616,1619],{},[147,1598,157],{},[147,1600,1601],{},"Idiom",": the healthiest fix for shared-state flakiness is to make each test self-contained (its own in-memory DB instance, its own temp directory, its own fixture) rather than fighting the test runner's default concurrency — this keeps the suite fast and each test's failure meaningful in isolation. ",[23,1604,1559],{}," (A) is both a legacy ",[23,1607,1608],{},"unsafe","-only construct and reintroduces exactly the shared-mutable-state race this question is about — it is not a fix. Forcing single-threaded execution everywhere (C) sacrifices the speed benefit of parallel tests project-wide just to paper over a design issue in a few tests. Relying on a test literally named\u002Fordered to run \"first\" (D) doesn't work — ",[23,1611,122],{},"'s execution order isn't guaranteed or controllable that way, and treating a ",[23,1614,25],{}," function as a setup hook is not a supported pattern (use a helper function called from each test, or a ",[23,1617,1618],{},"OnceLock","\u002Ffixture pattern instead).",[14,1621,1622,1626,1664],{},[18,1623,1625],{"id":1624},"q16-which-is-the-more-idiomatic-assertion-style-for-a-test-that-must-produce-a-clear-failure-message-when-comparing-two-computed-values","Q16. Which is the more idiomatic assertion style for a test that must produce a clear failure message when comparing two computed values?",[96,1627,1629,1637,1646,1654],{"className":1628},[99],[101,1630,1632,158,1634],{"className":1631},[104],[106,1633],{"disabled":108,"type":109},[23,1635,1636],{},"if a != b { panic!(\"failed\"); }",[101,1638,1640,158,1642,1645],{"className":1639},[104],[106,1641],{"disabled":108,"type":109},[23,1643,1644],{},"assert_eq!(a, b, \"computed value did not match expected for input {:?}\", input);"," — using the built-in comparison macro with an optional custom context message",[101,1647,1649,158,1651],{"className":1648},[104],[106,1650],{"disabled":108,"type":109},[23,1652,1653],{},"assert!(format!(\"{:?}\", a) == format!(\"{:?}\", b));",[101,1655,1657,1659,1660,1663],{"className":1656},[104],[106,1658],{"disabled":108,"type":109}," Silently allowing the test to continue if ",[23,1661,1662],{},"a != b",", and checking a log file afterward",[137,1665,1666,1668,1675],{},[140,1667,142],{},[144,1669,1670,1672,1673,1645],{},[147,1671,149],{}," B — ",[23,1674,1644],{},[144,1676,1677,158,1679,1681,1682,846,1684,1686,1687,846,1690,1693,1694,1697,1698,1701,1702,1495,1705,1708,1709,1711,1712,1715],{},[147,1678,157],{},[147,1680,1601],{},": ",[23,1683,233],{},[23,1685,849],{}," are preferred over a hand-rolled ",[23,1688,1689],{},"if",[23,1691,1692],{},"panic!"," because they automatically print both compared values in a readable diff on failure, and they accept an optional trailing format string for extra context — combining both gives the clearest failure output with the least code. A hand-rolled ",[23,1695,1696],{},"panic!(\"failed\")"," (A) throws away the actual values that mismatched, making debugging a failure much harder. Comparing via ",[23,1699,1700],{},"format!(\"{:?}\", ...)"," string equality (C) is a needless workaround — it obscures the real values behind their debug-formatted strings and loses type-level comparison semantics (e.g. it would consider ",[23,1703,1704],{},"-0.0",[23,1706,1707],{},"0.0"," different if their ",[23,1710,1028],{}," output differs, or ",[23,1713,1714],{},"NaN"," cases mismatch bizarrely). Silently continuing on a mismatch (D) defeats the entire purpose of a test.",[14,1717,1718,1722,1757],{},[18,1719,1721],{"id":1720},"q17-why-is-it-generally-considered-best-practice-for-unit-tests-to-avoid-depending-on-wall-clock-time-or-real-network-calls","Q17. Why is it generally considered best practice for unit tests to avoid depending on wall-clock time or real network calls?",[96,1723,1725,1733,1739,1751],{"className":1724},[99],[101,1726,1728,1730,1731],{"className":1727},[104],[106,1729],{"disabled":108,"type":109}," Rust's test harness physically disallows network access during ",[23,1732,122],{},[101,1734,1736,1738],{"className":1735},[104],[106,1737],{"disabled":108,"type":109}," Such dependencies make tests slow, flaky (affected by network conditions, clock skew, timing races), and non-reproducible across environments and CI runs — prefer injecting a fake clock\u002Fmock service or testing pure logic separately from I\u002FO",[101,1740,1742,158,1744,1746,1747,1750],{"className":1741},[104],[106,1743],{"disabled":108,"type":109},[23,1745,233],{}," cannot compare ",[23,1748,1749],{},"std::time::Instant"," values",[101,1752,1754,1756],{"className":1753},[104],[106,1755],{"disabled":108,"type":109}," Only integration tests are allowed to perform I\u002FO; unit tests are compiled without network access",[137,1758,1759,1761,1766],{},[140,1760,142],{},[144,1762,1763,1765],{},[147,1764,149],{}," B — Such dependencies make tests slow, flaky (affected by network conditions, clock skew, timing races), and non-reproducible across environments and CI runs — prefer injecting a fake clock\u002Fmock service or testing pure logic separately from I\u002FO",[144,1767,1768,158,1770,1772,1773,1775,1776,1778,1779,1782,1783,1786],{},[147,1769,157],{},[147,1771,1601],{},": tests that reach out over the real network or depend on precise timing are a leading cause of CI flakiness — a temporary DNS blip, a slow CI runner, or a shared clock jitter can fail a test that has nothing wrong with the code under test. The standard fix is dependency injection (pass in a trait object or fake clock\u002Fservice implementation for tests) so the logic under test is deterministic, with any real I\u002FO covered separately by a smaller number of integration tests that explicitly accept that cost. There is no language- or harness-level network block during ",[23,1774,122],{}," (rules out A and D — nothing stops a test from making a real HTTP call, which is exactly the problem). ",[23,1777,233],{}," works on any ",[23,1780,1781],{},"PartialEq + Debug"," type including ",[23,1784,1785],{},"Instant"," (rules out C) — the issue isn't comparability, it's non-determinism.",[14,1788,1789,1805,1859],{},[18,1790,1792,1793,1795,1796,1798,1799,846,1801,1804],{"id":1791},"q18-what-is-a-common-pitfall-of-writing-test-functions-that-call-unwrap-liberally-on-resultoption-values-from-the-code-under-test","Q18. What is a common pitfall of writing ",[23,1794,25],{}," functions that call ",[23,1797,1251],{}," liberally on ",[23,1800,638],{},[23,1802,1803],{},"Option"," values from the code under test?",[96,1806,1808,1819,1845,1853],{"className":1807},[99],[101,1809,1811,158,1813,1815,1816,1818],{"className":1810},[104],[106,1812],{"disabled":108,"type":109},[23,1814,1251],{}," is banned inside ",[23,1817,25],{}," functions by the compiler",[101,1820,1822,1824,1825,846,1827,1830,1831,1834,1835,1837,1838,1840,1841,1844],{"className":1821},[104],[106,1823],{"disabled":108,"type":109}," It works fine for surfacing failures as panics, but the failure message on an ",[23,1826,842],{},[23,1828,1829],{},"None"," can be uninformative compared to ",[23,1832,1833],{},"expect(\"context\")"," or a ",[23,1836,638],{},"-returning test with ",[23,1839,295],{},", making it harder to diagnose ",[175,1842,1843],{},"why"," a test failed from CI logs alone",[101,1846,1848,158,1850,1852],{"className":1847},[104],[106,1849],{"disabled":108,"type":109},[23,1851,1251],{}," silently converts errors into passing tests",[101,1854,1856,1858],{"className":1855},[104],[106,1857],{"disabled":108,"type":109}," It causes tests to run in a different thread than normal",[137,1860,1861,1863,1880],{},[140,1862,142],{},[144,1864,1865,1867,1868,846,1870,1830,1872,1834,1874,1837,1876,1840,1878,1844],{},[147,1866,149],{}," B — It works fine for surfacing failures as panics, but the failure message on an ",[23,1869,842],{},[23,1871,1829],{},[23,1873,1833],{},[23,1875,638],{},[23,1877,295],{},[175,1879,1843],{},[144,1881,1882,158,1884,1681,1886,1888,1889,1892,1893,1896,1897,1900,1901,1903,1904,1906],{},[147,1883,157],{},[147,1885,1601],{},[23,1887,1251],{}," does correctly fail the test (any panic fails it), but its default panic message is generic (",[23,1890,1891],{},"called Result::unwrap() on an Err value: ...","), whereas ",[23,1894,1895],{},".expect(\"parsing config from valid TOML should not fail\")"," or restructuring the test as ",[23,1898,1899],{},"fn test() -> Result\u003C(), Error> { ...; Ok(()) }"," with ",[23,1902,295],{}," gives future-you (or a teammate reading a CI log at 2am) immediate context about which operation failed and why, without needing to reproduce locally. ",[23,1905,1251],{}," is not disallowed anywhere in tests (rules out A), it does not swallow errors into a false pass — quite the opposite, it panics loudly (rules out C) — and it has no effect on which thread a test runs on (rules out D).",[14,1908,1909,1922,1954],{},[18,1910,1912,1913,1915,1916,1918,1919,1921],{"id":1911},"q19-why-do-many-real-world-rust-projects-prefer-to-keep-expensive-environment-dependent-integration-tests-separate-from-fast-unit-tests-eg-via-ignore-feature-flags-or-separate-tests-binaries-rather-than-mixing-everything-into-one-cargo-test-run","Q19. Why do many real-world Rust projects prefer to keep expensive, environment-dependent integration tests separate from fast unit tests (e.g., via ",[23,1914,634],{},", feature flags, or separate ",[23,1917,317],{}," binaries), rather than mixing everything into one ",[23,1920,122],{}," run?",[96,1923,1925,1931,1940,1948],{"className":1924},[99],[101,1926,1928,1930],{"className":1927},[104],[106,1929],{"disabled":108,"type":109}," cargo physically cannot compile more than one kind of test in the same crate",[101,1932,1934,1936,1937,1939],{"className":1933},[104],[106,1935],{"disabled":108,"type":109}," Keeping the default ",[23,1938,122],{}," run fast and hermetic encourages developers to actually run it constantly (tight feedback loop), while slower\u002Fenvironment-dependent tests are opted into explicitly (e.g., in a scheduled CI job) rather than punishing every local test run",[101,1941,1943,158,1945,1947],{"className":1942},[104],[106,1944],{"disabled":108,"type":109},[23,1946,634],{}," is required by the compiler for any test that takes longer than one second",[101,1949,1951,1953],{"className":1950},[104],[106,1952],{"disabled":108,"type":109}," Mixing test types causes silent data corruption in the test binary",[137,1955,1956,1958,1965],{},[140,1957,142],{},[144,1959,1960,1962,1963,1939],{},[147,1961,149],{}," B — Keeping the default ",[23,1964,122],{},[144,1966,1967,158,1969,1971,1972,1974,1975,1977,1978,1980],{},[147,1968,157],{},[147,1970,1601],{},": a test suite that takes 30 seconds because of a handful of slow, flaky, or environment-coupled tests trains developers to stop running it locally, which defeats the entire purpose of fast feedback — separating \"always run this\" from \"run this in CI or on demand\" (via ",[23,1973,634],{},", a Cargo feature flag, or a distinct ",[23,1976,317],{}," binary invoked separately) keeps the fast path fast without deleting valuable slower coverage. This is a process\u002Fworkflow best practice, not a compiler limitation — nothing stops you from mixing test kinds in one crate (rules out A and D, neither of which describes any real constraint), and there's no enforced timing threshold that mandates ",[23,1979,634],{}," — it's a judgment call developers make deliberately (rules out C).",[14,1982,1983,1990,2029],{},[18,1984,1986,1987,1989],{"id":1985},"q20-a-test-suite-has-one-slow-test-that-takes-45-seconds-due-to-a-large-fixture-buried-among-hundreds-of-millisecond-scale-unit-tests-and-it-isnt-marked-ignore-whats-the-idiomatic-fix-and-why-not-just-delete-the-slow-test","Q20. A test suite has one slow test that takes 45 seconds due to a large fixture, buried among hundreds of millisecond-scale unit tests, and it isn't marked ",[23,1988,634],{},". What's the idiomatic fix, and why not just delete the slow test?",[96,1991,1993,1999,2011,2020],{"className":1992},[99],[101,1994,1996,1998],{"className":1995},[104],[106,1997],{"disabled":108,"type":109}," Delete it — a slow test is never worth keeping",[101,2000,2002,2004,2005,2007,2008,2010],{"className":2001},[104],[106,2003],{"disabled":108,"type":109}," Mark it ",[23,2006,634],{}," (with a comment explaining why), or move it to a ",[23,2009,317],{}," integration binary run separately in CI, so the fast default suite stays quick while the valuable coverage isn't lost — deleting it would remove real regression protection just to fix a workflow annoyance",[101,2012,2014,2016,2017,2019],{"className":2013},[104],[106,2015],{"disabled":108,"type":109}," Wrap its body in ",[23,2018,573],{}," so it fails fast instead of running to completion",[101,2021,2023,2025,2026,2028],{"className":2022},[104],[106,2024],{"disabled":108,"type":109}," Rename the function so ",[23,2027,122],{}," alphabetically runs it last",[137,2030,2031,2033,2042],{},[140,2032,142],{},[144,2034,2035,2037,2038,2007,2040,2010],{},[147,2036,149],{}," B — Mark it ",[23,2039,634],{},[23,2041,317],{},[144,2043,2044,158,2046,2048,2049,2052,2053,2055,2056,2058,2059,2061,2062,2064,2065,2067,2068,2070],{},[147,2045,157],{},[147,2047,1601],{},": the test itself may well be catching real bugs (large-input behavior, performance regressions, resource-heavy edge cases) — the actual problem is the ",[175,2050,2051],{},"default local workflow"," getting slower, not that the test lacks value. ",[23,2054,634],{}," (paired with ",[23,2057,1085],{}," in a dedicated CI job or nightly run) or relocating it to its own ",[23,2060,317],{}," binary that CI invokes on a different cadence both preserve the coverage while keeping the everyday ",[23,2063,122],{}," loop fast. Deleting it outright (A) throws away a real regression check to solve what's really a scheduling\u002Fworkflow problem. ",[23,2066,573],{}," (C) changes the test's pass condition to \"must panic,\" which is unrelated to speed and would be actively wrong if the test isn't supposed to panic. ",[23,2069,122],{},"'s execution order isn't reliably alphabetical or otherwise developer-controlled, and even if it were, running last doesn't make a 45-second test any faster or less disruptive to the overall run time (rules out D).",[2072,2073,2074],"style",{},"html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-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 .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}",{"title":35,"searchDepth":49,"depth":49,"links":2076},[2077,2079,2081,2083,2085,2087,2089,2091,2093,2095,2097,2099,2101,2103,2105,2106,2107,2108,2110,2112],{"id":20,"depth":63,"text":2078},"Q1. What does the #[test] attribute do?",{"id":200,"depth":63,"text":2080},"Q2. Why is #[cfg(test)] commonly placed on a mod tests { ... } block containing unit tests?",{"id":290,"depth":63,"text":2082},"Q3. Where do Rust integration tests live, and how do they differ from unit tests in src\u002F?",{"id":385,"depth":63,"text":2084},"Q4. Do doctests (code examples in \u002F\u002F\u002F documentation comments) actually get executed?",{"id":569,"depth":63,"text":2086},"Q5. What does #[should_panic] do when applied to a #[test] function?",{"id":648,"depth":63,"text":2088},"Q6. How does cargo test run multiple test functions by default?",{"id":716,"depth":63,"text":2090},"Q7. What is the simplest way to check that a function returns the expected value in a #[test]?",{"id":871,"depth":63,"text":2092},"Q8. What happens when a #[test] function is empty (no assertions, no panics, just an empty body)?",{"id":969,"depth":63,"text":2094},"Q9. Two tests both write to the same hardcoded file path, \u002Ftmp\u002Foutput.txt, then assert on its contents. Running cargo test (default parallel execution) shows intermittent, non-deterministic failures. Why?",{"id":1058,"depth":63,"text":2096},"Q10. What does #[ignore] do on a test function, and how do you run ignored tests?",{"id":1143,"depth":63,"text":2098},"Q11. A test function is written as fn returns_config() -> Result\u003C(), String> { ... } without #[should_panic]. What determines whether this test passes?",{"id":1260,"depth":63,"text":2100},"Q12. What happens to output from println! inside a passing test, by default?",{"id":1333,"depth":63,"text":2102},"Q13. A unit test module does use super::*; to access the parent module's private items. Why does this work even though those items have no pub modifier?",{"id":1434,"depth":63,"text":2104},"Q14. In an integration test file under tests\u002F, why does use my_crate::internal_helper; fail to compile if internal_helper is a pub(crate) (not pub) function in the library?",{"id":1546,"depth":63,"text":1547},{"id":1624,"depth":63,"text":1625},{"id":1720,"depth":63,"text":1721},{"id":1791,"depth":63,"text":2109},"Q18. What is a common pitfall of writing #[test] functions that call .unwrap() liberally on Result\u002FOption values from the code under test?",{"id":1911,"depth":63,"text":2111},"Q19. Why do many real-world Rust projects prefer to keep expensive, environment-dependent integration tests separate from fast unit tests (e.g., via #[ignore], feature flags, or separate tests\u002F binaries), rather than mixing everything into one cargo test run?",{"id":1985,"depth":63,"text":2113},"Q20. A test suite has one slow test that takes 45 seconds due to a large fixture, buried among hundreds of millisecond-scale unit tests, and it isn't marked #[ignore]. What's the idiomatic fix, and why not just delete the slow test?","md",{},"\u002Frust\u002F21-testing",{"title":5,"description":35},"rust\u002F21-testing","HkvTJwK8shLAN5pqm9b-RjVxlNTESB7NxOHinBwDqug",1787335398422]