Skip to content

Commit

Permalink
Implement outputting JUnit XML report (#147, #50)
Browse files Browse the repository at this point in the history
- impl `writer::JUnit` behind `output-junit` Cargo feature
- make `writer::Basic` generic over `io::Write` implementor

Co-authored-by: Kai Ren <tyranron@gmail.com>
  • Loading branch information
ilslv and tyranron authored Nov 9, 2021
1 parent a153215 commit 2e937cb
Show file tree
Hide file tree
Showing 16 changed files with 868 additions and 130 deletions.
6 changes: 6 additions & 0 deletions .clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
# See full lints list at:
# https://rust-lang.github.io/rust-clippy/master/index.html

doc-valid-idents = ["JUnit"]

standard-macro-braces = [
{ name = "assert", brace = "(" },
{ name = "assert_eq", brace = "(" },
{ name = "assert_ne", brace = "(" },
{ name = "format", brace = "(" },
{ name = "format_ident", brace = "(" },
{ name = "panic", brace = "(" },
{ name = "quote", brace = "{" },
{ name = "vec", brace = "[" },
]
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
strategy:
fail-fast: false
matrix:
feature: ['<none>', 'macros', 'timestamps']
feature: ["<none>", "macros", "timestamps", "output-junit"]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ All user visible changes to `cucumber` crate will be documented in this file. Th
### Added

- Ability for step functions to return `Result`. ([#151])
- Arbitrary output for `writer::Basic` ([#147])
- `writer::JUnit` ([JUnit XML report][0110-1]) behind the `output-junit` feature flag ([#147])

[#147]: /../../pull/147
[#151]: /../../pull/151
[0110-1]: https://llg.cubic.org/docs/junit



Expand Down
15 changes: 13 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ repository = "https://github.com/cucumber-rs/cucumber"
readme = "README.md"
categories = ["asynchronous", "development-tools::testing"]
keywords = ["cucumber", "testing", "bdd", "atdd", "async"]
include = ["/src/", "/tests/wait.rs", "/LICENSE-*", "/README.md", "/CHANGELOG.md"]
include = ["/src/", "/tests/junit.rs", "/tests/wait.rs", "/LICENSE-*", "/README.md", "/CHANGELOG.md"]

[package.metadata.docs.rs]
all-features = true
Expand All @@ -29,14 +29,16 @@ rustdoc-args = ["--cfg", "docsrs"]
default = ["macros"]
# Enables step attributes and auto-wiring.
macros = ["cucumber-codegen", "inventory"]
# Enables support for outputting JUnit XML report.
output-junit = ["junit-report", "timestamps"]
# Enables timestamps collecting for all events.
timestamps = []

[dependencies]
async-trait = "0.1.40"
atty = "0.2.14"
console = "0.15"
derive_more = { version = "0.99.16", features = ["as_ref", "deref", "deref_mut", "display", "error", "from"], default_features = false }
derive_more = { version = "0.99.16", features = ["as_ref", "deref", "deref_mut", "display", "error", "from", "into"], default_features = false }
either = "1.6"
futures = "0.3.17"
gherkin = { package = "gherkin_rust", version = "0.10" }
Expand All @@ -52,10 +54,19 @@ structopt = "0.3.25"
cucumber-codegen = { version = "0.11.0-dev", path = "./codegen", optional = true }
inventory = { version = "0.1.10", optional = true }

# "output-junit" feature dependencies
junit-report = { version = "0.7", optional = true }

[dev-dependencies]
humantime = "2.1"
tempfile = "3.2"
tokio = { version = "1.12", features = ["macros", "rt-multi-thread", "time"] }

[[test]]
name = "junit"
required-features = ["output-junit"]
harness = false

[[test]]
name = "wait"
harness = false
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ For more examples check out the Book ([current][1] | [edge][2]).

- `macros` (default): Enables step attributes and auto-wiring.
- `timestamps`: Enables timestamps collecting for all [Cucumber] events.
- `output-junit` (implies `timestamps`): Enables support for outputting [JUnit XML report].



Expand Down Expand Up @@ -131,7 +132,8 @@ at your option.


[Cucumber]: https://cucumber.io
[Gherkin]: https://cucumber.io/docs/gherkin/reference
[Gherkin]: https://cucumber.io/docs/gherkin/reference
[JUnit XML report]: https://llg.cubic.org/docs/junit

[1]: https://cucumber-rs.github.io/cucumber/current
[2]: https://cucumber-rs.github.io/cucumber/main
44 changes: 44 additions & 0 deletions book/src/Features.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,5 +431,49 @@ You may also extend CLI options with custom ones, if you have such a need for ru



## JUnit XML report

Library provides an ability to output tests result in as [JUnit XML report].

Just enable `output-junit` library feature in your `Cargo.toml`:
```toml
cucumber = { version = "0.11", features = ["output-junit"] }
```

And configure [Cucumber]'s output to `writer::JUnit`:
```rust
# use std::{convert::Infallible, fs, io};
#
# use async_trait::async_trait;
# use cucumber::WorldInit;
use cucumber::writer;

# #[derive(Debug, WorldInit)]
# struct World;
#
# #[async_trait(?Send)]
# impl cucumber::World for World {
# type Error = Infallible;
#
# async fn new() -> Result<Self, Self::Error> {
# Ok(World)
# }
# }
#
# #[tokio::main]
# async fn main() -> io::Result<()> {
let file = fs::File::create(dbg!(format!("{}/target/junit.xml", env!("CARGO_MANIFEST_DIR"))))?;
World::cucumber()
.with_writer(writer::JUnit::new(file))
.run("tests/features/book")
.await;
# Ok(())
# }
```




[Cucumber]: https://cucumber.io
[Gherkin]: https://cucumber.io/docs/gherkin
[JUnit XML report]: https://llg.cubic.org/docs/junit
2 changes: 1 addition & 1 deletion book/tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ publish = false

[dependencies]
async-trait = "0.1"
cucumber = { version = "0.11.0-dev", path = "../.." }
cucumber = { version = "0.11.0-dev", path = "../..", features = ["output-junit"] }
futures = "0.3"
skeptic = "0.13"
tokio = { version = "1", features = ["macros", "rt-multi-thread", "time"] }
Expand Down
6 changes: 3 additions & 3 deletions src/cucumber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -922,10 +922,10 @@ where
I: AsRef<Path>,
{
fn default() -> Self {
Cucumber::custom(
Self::custom(
parser::Basic::new(),
runner::Basic::default(),
writer::Basic::new().normalized().summarized(),
writer::Basic::default().normalized().summarized(),
)
}
}
Expand Down Expand Up @@ -957,7 +957,7 @@ where
/// [tag]: https://cucumber.io/docs/cucumber/api/#tags
#[must_use]
pub fn new() -> Self {
Cucumber::default()
Self::default()
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/parser/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use derive_more::{Display, Error};
use futures::stream;
use gherkin::GherkinEnv;
use globwalk::{GlobWalker, GlobWalkerBuilder};
use itertools::Itertools as _;
use structopt::StructOpt;

use crate::feature::Ext as _;
Expand Down Expand Up @@ -65,6 +66,7 @@ impl<I: AsRef<Path>> Parser<I> for Basic {
let walk = |walker: GlobWalker| {
walker
.filter_map(Result::ok)
.sorted_by(|l, r| Ord::cmp(l.path(), r.path()))
.filter(|file| {
file.path()
.extension()
Expand Down
Loading

0 comments on commit 2e937cb

Please sign in to comment.