Skip to content

Commit d8b7a3e

Browse files
authored
java: Implement TestNG XML formatter (#2)
Implement a message based TestNG formatter.
1 parent 84ab547 commit d8b7a3e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2651
-0
lines changed

.github/renovate.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
3+
"extends": [
4+
"github>cucumber/renovate-config"
5+
]
6+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Release GitHub
2+
3+
on:
4+
push:
5+
branches: [release/*]
6+
7+
jobs:
8+
create-github-release:
9+
name: Create GitHub Release and Git tag
10+
runs-on: ubuntu-latest
11+
environment: Release
12+
permissions:
13+
contents: write
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: cucumber/[email protected]
17+
with:
18+
github-token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release-mvn.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Release Maven
2+
3+
on:
4+
push:
5+
branches: [release/*]
6+
7+
jobs:
8+
publish-mvn:
9+
name: Publish Maven Package
10+
runs-on: ubuntu-latest
11+
environment: Release
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-java@v4
15+
with:
16+
distribution: 'temurin'
17+
java-version: '11'
18+
cache: 'maven'
19+
- uses: cucumber/[email protected]
20+
with:
21+
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
22+
gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
23+
nexus-username: cukebot
24+
nexus-password: ${{ secrets.SONATYPE_PASSWORD }}
25+
working-directory: java

.github/workflows/test-java.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: test-java
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- renovate/**
8+
pull_request:
9+
branches:
10+
- main
11+
workflow_call:
12+
13+
jobs:
14+
test-java:
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
os:
20+
- ubuntu-latest
21+
java: ["11", "17"]
22+
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
- uses: actions/setup-java@v4
27+
with:
28+
distribution: "zulu"
29+
java-version: ${{ matrix.java }}
30+
cache: "maven"
31+
32+
- run: mvn verify
33+
working-directory: java
34+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: test-testdata
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
test-testdata:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
17+
- uses: actions/checkout@v4
18+
19+
- uses: actions/setup-node@v4
20+
with:
21+
cache: 'npm'
22+
cache-dependency-path: testdata/package-lock.json
23+
24+
- run: npm ci
25+
working-directory: testdata
26+
27+
- name: check repository is not dirty
28+
run: "[[ -z $(git status --porcelain) ]]"
29+
30+
- name: show diff
31+
if: ${{ failure() }}
32+
run: git status --porcelain

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.idea/
2+
*.iml

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
### Added
10+
- Java implementation
11+
12+
## 0.0.0
13+
14+
[Unreleased]: https://github.com/cucumber/cucumber-junit-xml-formatter/compare/v0.0.0...HEAD
15+
[0.0.0]: https://github.com/cucumber/cucumber-junit-xml-formatter/compare/438ec1f6218a849eb2a684982e2ff7e304a3155f...v0.0.0

java/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea/
2+
*.iml
3+
target/

java/README.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
[![Maven Central](https://img.shields.io/maven-central/v/io.cucumber/testng-xml-formatter.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.cucumber%22%20AND%20a:%22testng-xml-formatter%22)
2+
3+
⚠️ This is an internal package; you don't need to install it in order to use the TestNG XML Formatter.
4+
5+
TestNG XML Formatter
6+
===================
7+
8+
Writes Cucumber message into a TestNG XML report.
9+
10+
The TestNG XML report does not come with an XSD and the [TestNG documentations](https://testng-docs.readthedocs.io/testresults/#xml-reports)
11+
only provides a minimal example. Nevertheless, we had this formatter since 2013
12+
with no recent issues. So there is a good your tools will understand it.
13+
14+
If not, please let us know in the issues!
15+
16+
## Features and Limitations
17+
18+
### Test outcome mapping
19+
20+
Cucumber and the TestNG XML Report support a different set of test outcomes.
21+
These are mapped according to the table below.
22+
23+
Additionally, it is advisable to run Cucumber in strict mode. When used in
24+
non-strict mode scenarios with a pending or undefined outcome will not fail
25+
the test run ([#714](https://github.com/cucumber/common/issues/714)). This
26+
can lead to a xml report that contains `failure` outcomes while the build
27+
passes.
28+
29+
| Cucumber Outcome | XML Outcome | Passes in strict mode | Passes in non-strict mode |
30+
|------------------|-------------|-----------------------|---------------------------|
31+
| UNKNOWN | n/a | n/a | n/a |
32+
| PASSED | PASS | yes | yes |
33+
| SKIPPED | SKIP | yes | yes |
34+
| PENDING | FAIL | no | yes |
35+
| UNDEFINED | FAIL | no | yes |
36+
| AMBIGUOUS | FAIL | no | no |
37+
| FAILED | FAIL | no | no |
38+
39+
40+
### Step reporting
41+
42+
The TestNG XML report assumes that a test is a method on a class. Yet a scenario
43+
consists of multiple steps. To provide info about the failing step, the `message`
44+
element will contain a rendition of steps and their result.
45+
46+
```xml
47+
<exception class="AssertionError">
48+
<message><![CDATA[
49+
Given there are 12 cucumbers................................................passed
50+
When I eat 5 cucumbers......................................................passed
51+
Then I should have 7 cucumbers..............................................failed
52+
]]></message>
53+
<full-stacktrace>
54+
..the actual stack trace...
55+
</full-stacktrace>
56+
</exception>
57+
```
58+
59+
### Naming Rules and Examples
60+
61+
Cucumber does not require that scenario names are unique. To disambiguate
62+
between similarly named scenarios and examples the report prefixes the rule
63+
to the scenario or example name.
64+
65+
```feature
66+
Feature: Rules
67+
68+
Rule: a sale cannot happen if change cannot be returned
69+
Example: no change
70+
...
71+
Example: exact change
72+
...
73+
74+
Rule: a sale cannot happen if we're out of stock
75+
Example: no chocolates left
76+
...
77+
```
78+
79+
```xml
80+
<class name="Rules">
81+
<test-method name="a sale cannot happen if change cannot be returned - exact change" status="PASS"
82+
duration-ms="7" started-at="1970-01-01T00:00:00.001Z" finished-at="1970-01-01T00:00:00.008Z"/>
83+
<test-method name="a sale cannot happen if we're out of stock - no chocolates left" status="PASS"
84+
duration-ms="7" started-at="1970-01-01T00:00:00.001Z" finished-at="1970-01-01T00:00:00.008Z"/>
85+
</class>
86+
```
87+
88+
Likewise for example tables, the rule (if any), scenario outline name, example
89+
name, and number are included.
90+
91+
```feature
92+
Feature: Examples Tables
93+
94+
Scenario Outline: Eating cucumbers
95+
Given there are <start> cucumbers
96+
When I eat <eat> cucumbers
97+
Then I should have <left> cucumbers
98+
99+
Examples: These are passing
100+
| start | eat | left |
101+
| 12 | 5 | 7 |
102+
| 20 | 5 | 15 |
103+
104+
Examples: These are failing
105+
| start | eat | left |
106+
| 12 | 20 | 0 |
107+
| 0 | 1 | 0 |
108+
```
109+
110+
```xml
111+
<class name="Examples Tables">
112+
<test-method name="Eating cucumbers - These are passing - Example #1.1" status="PASS" duration-ms="7"
113+
started-at="1970-01-01T00:00:00.001Z" finished-at="1970-01-01T00:00:00.008Z"/>
114+
<test-method name="Eating cucumbers - These are passing - Example #1.2" status="PASS" duration-ms="7"
115+
started-at="1970-01-01T00:00:00.009Z" finished-at="1970-01-01T00:00:00.016Z"/>
116+
<test-method name="Eating cucumbers - These are failing - Example #2.1" status="FAIL" duration-ms="7"
117+
started-at="1970-01-01T00:00:00.017Z" finished-at="1970-01-01T00:00:00.024Z">
118+
<exception class="AssertionError">...</exception>
119+
</test-method>
120+
<test-method name="Eating cucumbers - These are failing - Example #2.2" status="FAIL" duration-ms="7"
121+
started-at="1970-01-01T00:00:00.025Z" finished-at="1970-01-01T00:00:00.032Z">
122+
<exception class="AssertionError">...</exception>
123+
</test-method>
124+
</class>
125+
```
126+
## Contributing
127+
128+
Each language implementation validates itself against the examples in the
129+
`testdata` folder. See the [testdata/README.md](testdata/README.md) for more
130+
information.

java/pom.xml

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>io.cucumber</groupId>
7+
<artifactId>cucumber-parent</artifactId>
8+
<version>4.2.0</version>
9+
</parent>
10+
11+
<artifactId>testng-xml-formatter</artifactId>
12+
<version>0.0.1-SNAPSHOT</version>
13+
<packaging>jar</packaging>
14+
<name>TestNG XML Formatter</name>
15+
<description>Renders Cucumber Messages as TestNG XML</description>
16+
<url>https://github.com/cucumber/testng-xml-formatter</url>
17+
18+
<properties>
19+
<project.Automatic-Module-Name>io.cucumber.testngxmlformatter</project.Automatic-Module-Name>
20+
<project.build.outputTimestamp>1711217894</project.build.outputTimestamp>
21+
</properties>
22+
23+
<scm>
24+
<connection>scm:git:git://github.com/cucumber/testng-xml-formatter.git</connection>
25+
<developerConnection>scm:git:[email protected]:cucumber/testng-xml-formatter.git</developerConnection>
26+
<url>git://github.com/cucumber/testng-xml-formatter.git</url>
27+
<tag>HEAD</tag>
28+
</scm>
29+
30+
<dependencyManagement>
31+
<dependencies>
32+
<dependency>
33+
<groupId>org.junit</groupId>
34+
<artifactId>junit-bom</artifactId>
35+
<version>5.10.2</version>
36+
<type>pom</type>
37+
<scope>import</scope>
38+
</dependency>
39+
40+
<dependency>
41+
<groupId>com.fasterxml.jackson</groupId>
42+
<artifactId>jackson-bom</artifactId>
43+
<version>2.17.0</version>
44+
<type>pom</type>
45+
<scope>import</scope>
46+
</dependency>
47+
</dependencies>
48+
</dependencyManagement>
49+
50+
<dependencies>
51+
<dependency>
52+
<groupId>io.cucumber</groupId>
53+
<artifactId>messages</artifactId>
54+
<version>[24.0.0,25.0.0)</version>
55+
</dependency>
56+
<dependency>
57+
<groupId>io.cucumber</groupId>
58+
<artifactId>query</artifactId>
59+
<version>[12.1.1,13.0.0)</version>
60+
</dependency>
61+
62+
<dependency>
63+
<groupId>com.fasterxml.jackson.core</groupId>
64+
<artifactId>jackson-databind</artifactId>
65+
<scope>test</scope>
66+
</dependency>
67+
68+
<dependency>
69+
<groupId>com.fasterxml.jackson.datatype</groupId>
70+
<artifactId>jackson-datatype-jdk8</artifactId>
71+
<scope>test</scope>
72+
</dependency>
73+
74+
<dependency>
75+
<groupId>com.fasterxml.jackson.module</groupId>
76+
<artifactId>jackson-module-parameter-names</artifactId>
77+
<scope>test</scope>
78+
</dependency>
79+
80+
<dependency>
81+
<groupId>org.hamcrest</groupId>
82+
<artifactId>hamcrest</artifactId>
83+
<version>2.2</version>
84+
<scope>test</scope>
85+
</dependency>
86+
87+
<dependency>
88+
<groupId>org.assertj</groupId>
89+
<artifactId>assertj-core</artifactId>
90+
<version>3.25.3</version>
91+
<scope>test</scope>
92+
</dependency>
93+
94+
<dependency>
95+
<groupId>org.xmlunit</groupId>
96+
<artifactId>xmlunit-assertj</artifactId>
97+
<version>2.9.1</version>
98+
<scope>test</scope>
99+
</dependency>
100+
101+
<dependency>
102+
<groupId>org.junit.jupiter</groupId>
103+
<artifactId>junit-jupiter-engine</artifactId>
104+
<scope>test</scope>
105+
</dependency>
106+
107+
<dependency>
108+
<groupId>org.junit.jupiter</groupId>
109+
<artifactId>junit-jupiter-params</artifactId>
110+
<scope>test</scope>
111+
</dependency>
112+
</dependencies>
113+
</project>

0 commit comments

Comments
 (0)