Co to znamená
Pokrytí crate je číslo s commitnutou spodní mezí a push, který pod ni klesne, nezezelená. Dvě meze, každá jedno celé číslo v samostatném souboru: scripts/rust-coverage-threshold pro celý spustitelný soubor a scripts/session-coverage-threshold pro kanonickou doménu relace a kontinuity deklarovanou v scripts/session-coverage-domain. Obě čte každé místo, které měří — job coverage v CI, scripts/rust-check když je nainstalován cargo-llvm-cov, a just coverage — takže neexistuje druhá kopie žádného z těch čísel, která by mohla driftovat.
Měření vylučuje testovací kód. To je část, kterou stojí za to říct nahlas, protože dlouho tomu tak nebylo.
Princip
scripts/rust-coverage spustí cargo llvm-cov --all-targets --no-fail-fast --json jednou a export následně zpracuje. Soubor pod tests/, benches/ nebo examples/ a build.rs se zahodí celý; uvnitř souboru src/ se zahodí každá položka #[cfg(test)] podle rozsahu řádků, párováním složených závorek od úvodního řádku po závorku, která jej uzavírá, a stejně tak každá funkce #[test] a #[bench]. Zůstane testovaný kód a podíl se počítá nad ním na obou stranách.
Předchozí kontrola byla cargo llvm-cov --all-targets --summary-only --fail-under-lines "$(cat scripts/rust-coverage-threshold)", bez --ignore-filename-regex. --all-targets instrumentuje integrační sady a benchmarky jako vlastní zdrojové soubory a tento crate drží své unit testy inline jako #[cfg(test)] mod tests uvnitř src/*.rs, kam žádný regex na názvy souborů nedosáhne. Testovací kód je téměř vždy plně vykonán během běhu, který jej měří, takže každý napsaný test zvýšil procento, ať cokoli pokrýval, či ne, a každý smazaný je snížil. O prahu nad takovou směsí nelze uvažovat a samozřejmý způsob, jak jej udržet, je psát testy testů.
Druhá podlaha existuje, protože číslo za celý crate neříká nic o žádném konkrétním podsystému. Doména relací a kontinuity — kód, na kterém závisí paměť repozitáře o vlastní práci — může být na nule, zatímco číslo za celý crate zůstává zelené. scripts/session-coverage-domain jmenuje soubory, které pokrývá, po jednom na řádek, a skript odmítne doménu, která jmenuje soubor, jejž export nenese: zúžení domény pro zvýšení čísla je úprava, kterou recenzent vidí, ne tichá změna předmětu.
Obě meze jsou ratchety: každá je pokrytí, které její předmět změřil, když byla nastavena, dolní mez, která smí růst a nikdy klesnout. Mez crate je vázána na FLOOR_BOUND v scripts/ci/rust-command-check, kontrole blokujícího pravidla project.rust-command-tested-in-file, která odmítne mez pod ní; mez domény je vázána v případu níže. Žádná mez nestojí nad tím, co crate změřil, protože mez, kterou žádný běh nesplní, shazuje každý push stejně a o žádné změně nic neříká; nový nepokrytý kód je odmítnut tak jako tak kontrolou změněného kódu, project.new-code-is-covered.
test/cases/77_rust_evidence.sh kontroluje, že oba soubory drží jedno celé číslo, že žádné není pod svou mezí, že job pokrytí spouští skript, a nevolá znovu cargo llvm-cov --summary-only, že scripts/rust-check a just coverage dělají totéž a že každý soubor, který doména jmenuje, existuje.
Jak to vidět
cat scripts/rust-coverage-threshold scripts/session-coverage-threshold
cat scripts/session-coverage-domain
scripts/rust-coverage --report # measure and print, hold nothing
just coverage # cargo-llvm-cov: cargo install cargo-llvm-cov; rustup component add llvm-tools-preview
Zpráva vypisuje řádky, funkce a regiony pro crate i pro doménu a vedle řádkového čísla crate i číslo, které měřila stará kontrola — tentýž běh spočítaný s ponechaným testovacím kódem — takže rozdíl mezi nimi je vidět, ne tvrzen.
Co nepokrývá
Pokrytí se měří na Linuxu v CI, jednou za běh, který vybírá kontrolu rust-coverage (třídy rust a share z .ai/repo/ci/gates.yaml a každý plný plán); změna, která crate nemůže zasáhnout, jej nepřekompiluje s instrumentací. Skutečné pokrytí větví se neměří: cargo llvm-cov --branch potřebuje nightly toolchain a tento repozitář buildí na stable, takže ho zastupuje pokrytí regionů a zpráva říká regions, ne branches. Hranice pro celý crate je pouze na řádcích; hranice domény je na řádcích, funkcích a regionech dohromady. Soubor pod hranicí crate není odmítnut, dokud je crate jako celek nad ní.
Shellová polovina nástroje — lib/*.sh, která vlastní životní cyklus relace, knihu a úložiště záznamů — v tomto měření není a nemá žádnou spodní mez. scripts/shell-coverage ji měří, přesně pro funkce a jako uvedenou spodní mez pro řádky, a je nástrojem, ne kontrolou; důvod, proč jí není, je v její vlastní hlavičce.
Proč existuje
Provozovatel požádal o pokrytí blízké 100 procentům a o to, aby se to vynucovalo do budoucna. Práh, který počítá testy do svého jmenovatele, odpovídá na jinou otázku, než která padla: říká, kolik cratu plus jeho testů běželo, což roste, když se přidávají testy, a klesá, když se mažou, ať pokrývají cokoli. Odečtení testovacího kódu dělá z čísla to, co říká, a něco to stojí — poctivé číslo je nižší než to, které tiskla stará kontrola. Pravidlo project.rust-cli-evidence stanoví požadavek; toto tvrzení váže čísla ke kontrole.