diff --git a/docs/test/coverage.md b/docs/test/coverage.md index 333eb3fda8..73c1b142b0 100644 --- a/docs/test/coverage.md +++ b/docs/test/coverage.md @@ -52,9 +52,22 @@ It is possible to specify a coverage threshold in `bunfig.toml`. If your test su coverageThreshold = 0.9 # to set different thresholds for lines and functions -coverageThreshold = { lines = 0.9, functions = 0.9 } +coverageThreshold = { lines = 0.9, functions = 0.9, statements = 0.9 } ``` +Setting any of these thresholds enables `fail_on_low_coverage`, causing the test run to fail if coverage is below the threshold. + +### Exclude test files from coverage + +By default, test files themselves are included in coverage reports. You can exclude them with: + +```toml +[test] +coverageSkipTestFiles = true # default false +``` + +This will exclude files matching test patterns (e.g., _.test.ts, _\_spec.js) from the coverage report. + ### Sourcemaps Internally, Bun transpiles all files by default, so Bun automatically generates an internal [source map](https://web.dev/source-maps/) that maps lines of your original source code onto Bun's internal representation. If for any reason you want to disable this, set `test.coverageIgnoreSourcemaps` to `true`; this will rarely be desirable outside of advanced use cases. @@ -64,6 +77,14 @@ Internally, Bun transpiles all files by default, so Bun automatically generates coverageIgnoreSourcemaps = true # default false ``` +### Coverage defaults + +By default, coverage reports: + +1. Exclude `node_modules` directories +2. Exclude files loaded via non-JS/TS loaders (e.g., .css, .txt) unless a custom JS loader is specified +3. Include test files themselves (can be disabled with `coverageSkipTestFiles = true` as shown above) + ### Coverage reporters By default, coverage reports will be printed to the console. diff --git a/docs/test/discovery.md b/docs/test/discovery.md index 2ea4e56103..99abade4f7 100644 --- a/docs/test/discovery.md +++ b/docs/test/discovery.md @@ -83,4 +83,3 @@ Tests are run in the following order: 1. Test files are executed sequentially (not in parallel) 2. Within each file, tests run sequentially based on their definition order -3. Tests defined with `test.only()` or within a `describe.only()` block will cause other tests to be skipped when using `--only` diff --git a/docs/test/writing.md b/docs/test/writing.md index 058ed4c8aa..6ecb625de2 100644 --- a/docs/test/writing.md +++ b/docs/test/writing.md @@ -127,7 +127,7 @@ fix the test. ## `test.only` -To run a particular test or suite of tests use `test.only()` or `describe.only()`. Once declared, running `bun test --only` will only execute tests/suites that have been marked with `.only()`. Running `bun test` without the `--only` option with `test.only()` declared will result in all tests in the given suite being executed _up to_ the test with `.only()`. `describe.only()` functions the same in both execution scenarios. +To run a particular test or suite of tests use `test.only()` or `describe.only()`. ```ts import { test, describe } from "bun:test"; @@ -232,7 +232,7 @@ describe.if(isMacOS)("macOS-specific features", () => { test("feature A", () => { // only runs on macOS }); - + test("feature B", () => { // only runs on macOS }); @@ -278,7 +278,7 @@ describe.each([ test(`returns ${expected}`, () => { expect(a + b).toBe(expected); }); - + test(`sum is greater than each value`, () => { expect(a + b).toBeGreaterThan(a); expect(a + b).toBeGreaterThan(b); @@ -297,16 +297,16 @@ How arguments are passed to your test function depends on the structure of your // Array items passed as individual arguments test.each([ [1, 2, 3], - [4, 5, 9] + [4, 5, 9], ])("add(%i, %i) = %i", (a, b, expected) => { expect(a + b).toBe(expected); }); // Object items passed as a single argument test.each([ - {a: 1, b: 2, expected: 3}, - {a: 4, b: 5, expected: 9} -])("add($a, $b) = $expected", (data) => { + { a: 1, b: 2, expected: 3 }, + { a: 4, b: 5, expected: 9 }, +])("add($a, $b) = $expected", data => { expect(data.a + data.b).toBe(data.expected); }); ``` @@ -370,7 +370,7 @@ There are a number of options available for formatting the test title: // Basic specifiers test.each([ ["hello", 123], - ["world", 456] + ["world", 456], ])("string: %s, number: %i", (str, num) => { // "string: hello, number: 123" // "string: world, number: 456" @@ -378,18 +378,15 @@ test.each([ // %p for pretty-format output test.each([ - [{name: "Alice"}, {a: 1, b: 2}], - [{name: "Bob"}, {x: 5, y: 10}] + [{ name: "Alice" }, { a: 1, b: 2 }], + [{ name: "Bob" }, { x: 5, y: 10 }], ])("user %p with data %p", (user, data) => { // "user { name: 'Alice' } with data { a: 1, b: 2 }" // "user { name: 'Bob' } with data { x: 5, y: 10 }" }); // %# for index -test.each([ - "apple", - "banana" -])("fruit #%# is %s", (fruit) => { +test.each(["apple", "banana"])("fruit #%# is %s", fruit => { // "fruit #0 is apple" // "fruit #1 is banana" }); @@ -406,7 +403,7 @@ Use `expect.hasAssertions()` to verify that at least one assertion is called dur ```ts test("async work calls assertions", async () => { expect.hasAssertions(); // Will fail if no assertions are called - + const data = await fetchData(); expect(data).toBeDefined(); }); @@ -421,7 +418,7 @@ Use `expect.assertions(count)` to verify that a specific number of assertions ar ```ts test("exactly two assertions", () => { expect.assertions(2); // Will fail if not exactly 2 assertions are called - + expect(1 + 1).toBe(2); expect("hello").toContain("ell"); });