Skip to content

Commit

Permalink
Implement junit test reporter (#15205)
Browse files Browse the repository at this point in the history
Co-authored-by: Jarred-Sumner <[email protected]>
Co-authored-by: Dylan Conway <[email protected]>
Co-authored-by: Dylan Conway <[email protected]>
  • Loading branch information
4 people authored Nov 19, 2024
1 parent daece6a commit 3ef35d7
Show file tree
Hide file tree
Showing 7 changed files with 790 additions and 9 deletions.
43 changes: 43 additions & 0 deletions docs/cli/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,49 @@ $ bun test ./test/specific-file.test.ts

The test runner runs all tests in a single process. It loads all `--preload` scripts (see [Lifecycle](https://bun.sh/docs/test/lifecycle) for details), then runs all tests. If a test fails, the test runner will exit with a non-zero exit code.

## CI/CD integration

`bun test` supports a variety of CI/CD integrations.

### GitHub Actions

`bun test` automatically detects if it's running inside GitHub Actions and will emit GitHub Actions annotations to the console directly.

No configuration is needed, other than installing `bun` in the workflow and running `bun test`.

#### How to install `bun` in a GitHub Actions workflow

To use `bun test` in a GitHub Actions workflow, add the following step:

```yaml
jobs:
build:
name: build-app
runs-on: ubuntu-latest
steps:
- name: Install bun
uses: oven-sh/setup-bun
- name: Install dependencies # (assuming your project has dependencies)
run: bun install # You can use npm/yarn/pnpm instead if you prefer
- name: Run tests
run: bun test
```
From there, you'll get GitHub Actions annotations.
### JUnit XML reports (GitLab, etc.)
To use `bun test` with a JUnit XML reporter, you can use the `--reporter=junit` in combination with `--reporter-outfile`.

```sh
$ bun test --reporter=junit --reporter-outfile=./bun.xml
```

This will continue to output to stdout/stderr as usual, and also write a JUnit
XML report to the given path at the very end of the test run.

JUnit XML is a popular format for reporting test results in CI/CD pipelines.

## Timeouts

Use the `--timeout` flag to specify a _per-test_ timeout in milliseconds. If a test times out, it will be marked as failed. The default value is `5000`.
Expand Down
11 changes: 11 additions & 0 deletions src/bunfig.zig
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,17 @@ pub const Bunfig = struct {
this.ctx.test_options.coverage.enabled = expr.data.e_boolean.value;
}

if (test_.get("reporter")) |expr| {
try this.expect(expr, .e_object);
if (expr.get("junit")) |junit_expr| {
try this.expectString(junit_expr);
if (junit_expr.data.e_string.len() > 0) {
this.ctx.test_options.file_reporter = .junit;
this.ctx.test_options.reporter_outfile = try junit_expr.data.e_string.string(allocator);
}
}
}

if (test_.get("coverageReporter")) |expr| brk: {
this.ctx.test_options.coverage.reporters = .{ .text = false, .lcov = false };
if (expr.data == .e_string) {
Expand Down
22 changes: 22 additions & 0 deletions src/cli.zig
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ pub const Arguments = struct {
clap.parseParam("--coverage-dir <STR> Directory for coverage files. Defaults to 'coverage'.") catch unreachable,
clap.parseParam("--bail <NUMBER>? Exit the test suite after <NUMBER> failures. If you do not specify a number, it defaults to 1.") catch unreachable,
clap.parseParam("-t, --test-name-pattern <STR> Run only tests with a name that matches the given regex.") catch unreachable,
clap.parseParam("--reporter <STR> Specify the test reporter. Currently --reporter=junit is the only supported format.") catch unreachable,
clap.parseParam("--reporter-outfile <STR> The output file used for the format from --reporter.") catch unreachable,
};
pub const test_params = test_only_params ++ runtime_params_ ++ transpiler_params_ ++ base_params_;

Expand Down Expand Up @@ -524,6 +526,23 @@ pub const Arguments = struct {
}
}

if (args.option("--reporter-outfile")) |reporter_outfile| {
ctx.test_options.reporter_outfile = reporter_outfile;
}

if (args.option("--reporter")) |reporter| {
if (strings.eqlComptime(reporter, "junit")) {
if (ctx.test_options.reporter_outfile == null) {
Output.errGeneric("--reporter=junit expects an output file from --reporter-outfile", .{});
Global.crash();
}
ctx.test_options.file_reporter = .junit;
} else {
Output.errGeneric("unrecognized reporter format: '{s}'. Currently, only 'junit' is supported", .{reporter});
Global.crash();
}
}

if (args.option("--coverage-dir")) |dir| {
ctx.test_options.coverage.reports_directory = dir;
}
Expand Down Expand Up @@ -1354,6 +1373,9 @@ pub const Command = struct {
bail: u32 = 0,
coverage: TestCommand.CodeCoverageOptions = .{},
test_filter_regex: ?*RegularExpression = null,

file_reporter: ?TestCommand.FileReporter = null,
reporter_outfile: ?[]const u8 = null,
};

pub const Debugger = union(enum) {
Expand Down
Loading

0 comments on commit 3ef35d7

Please sign in to comment.