Skip to content

Commit 2f81943

Browse files
authored
Merge pull request #32 from BintLopez/add_option_to_display_file_path_vs_classname
Add optional input to use file path vs classname in annotation summary
2 parents 5857a3c + f03f10c commit 2f81943

File tree

4 files changed

+119
-7
lines changed

4 files changed

+119
-7
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,22 @@ The artifact glob path to find the JUnit XML files.
2727
Example: `tmp/junit-*.xml`
2828

2929
### `job-uuid-file-pattern` (optional)
30+
Default: `-(.*).xml`
3031

3132
The regular expression (with capture group) that matches the job UUID in the junit file names. This is used to create the job links in the annotation.
3233

3334
To use this, configure your test reporter to embed the `$BUILDKITE_JOB_ID` environment variable into your junit file names. For example `"junit-buildkite-job-$BUILDKITE_JOB_ID.xml"`.
3435

35-
Default: `-(.*).xml`
36+
### `failure-format` (optional)
37+
Default: `classname`
38+
39+
This setting controls the format of your failed test in the main annotation summary.
40+
41+
There are two options for this:
42+
* `classname`
43+
* displays: `MyClass::UnderTest text of the failed expectation in path.to.my_class.under_test`
44+
* `file`
45+
* displays: `MyClass::UnderTest text of the failed expectation in path/to/my_class/under_test.file_ext`
3646

3747
## Developing
3848

plugin.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ configuration:
99
type: string
1010
job-uuid-file-pattern:
1111
type: string
12+
failure-format:
13+
type: string
14+
enum:
15+
- classname
16+
- file
1217
required:
1318
- artifacts
14-
additionalProperties: false
19+
additionalProperties: false

ruby/bin/annotate

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@ abort("#{junits_dir} does not exist") unless Dir.exist?(junits_dir)
1212
job_pattern = ENV['BUILDKITE_PLUGIN_JUNIT_ANNOTATE_JOB_UUID_FILE_PATTERN']
1313
job_pattern = '-(.*).xml' if !job_pattern || job_pattern.empty?
1414

15-
class Failure < Struct.new(:name, :classname, :body, :job, :type)
15+
failure_format = ENV['BUILDKITE_PLUGIN_JUNIT_ANNOTATE_FAILURE_FORMAT']
16+
failure_format = 'classname' if !failure_format || failure_format.empty?
17+
18+
# TODO -- remove this validation once https://github.com/buildkite/agent/pull/748 is merged
19+
if !%w(classname file).include?(failure_format)
20+
abort("Invalid failure-format #{failure_format} provided -- leave this setting blank or specify `file` or `classname`")
21+
end
22+
23+
class Failure < Struct.new(:name, :failed_test, :body, :job, :type)
1624
end
1725

1826
junit_report_files = Dir.glob(File.join(junits_dir, "**", "*"))
@@ -28,12 +36,12 @@ junit_report_files.sort.each do |file|
2836

2937
REXML::XPath.each(doc, '//testsuite//testcase') do |testcase|
3038
name = testcase.attributes['name'].to_s
31-
classname = testcase.attributes['classname'].to_s
39+
failed_test = testcase.attributes[failure_format].to_s
3240
testcase.elements.each("failure") do |failure|
33-
failures << Failure.new(name, classname, failure.text, job, :failure)
41+
failures << Failure.new(name, failed_test, failure.text, job, :failure)
3442
end
3543
testcase.elements.each("error") do |error|
36-
failures << Failure.new(name, classname, error.text, job, :error)
44+
failures << Failure.new(name, failed_test, error.text, job, :error)
3745
end
3846
end
3947
end
@@ -59,7 +67,7 @@ puts [
5967

6068
failures.each do |failure|
6169
puts "<details>"
62-
puts "<summary><code>#{failure.name} in #{failure.classname}</code></summary>\n\n"
70+
puts "<summary><code>#{failure.name} in #{failure.failed_test}</code></summary>\n\n"
6371
if failure.body
6472
puts "<code><pre>#{failure.body.chomp.strip}</pre></code>\n\n"
6573
end

ruby/tests/annotate_test.rb

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,95 @@
215215
assert_equal 0, status.exitstatus
216216
end
217217

218+
it "uses the file path instead of classname for annotation content when specified" do
219+
output, status = Open3.capture2e("env", "BUILDKITE_PLUGIN_JUNIT_ANNOTATE_FAILURE_FORMAT=file", "#{__dir__}/../bin/annotate", "#{__dir__}/test-failure-and-error/")
220+
221+
assert_equal <<~OUTPUT, output
222+
Parsing junit-1.xml
223+
Parsing junit-2.xml
224+
Parsing junit-3.xml
225+
--- ❓ Checking failures
226+
There are 4 failures/errors 😭
227+
--- ✍️ Preparing annotation
228+
2 failures and 2 errors:
229+
230+
<details>
231+
<summary><code>Account#maximum_jobs_added_by_pipeline_changer returns 250 by default in ./spec/models/account_spec.rb</code></summary>
232+
233+
<code><pre>Failure/Error: expect(account.maximum_jobs_added_by_pipeline_changer).to eql(250)
234+
235+
expected: 250
236+
got: 500
237+
238+
(compared using eql?)
239+
./spec/models/account_spec.rb:78:in `block (3 levels) in <top (required)>'
240+
./spec/support/database.rb:16:in `block (2 levels) in <top (required)>'
241+
./spec/support/log.rb:17:in `run'
242+
./spec/support/log.rb:66:in `block (2 levels) in <top (required)>'</pre></code>
243+
244+
in <a href="#1">Job #1</a>
245+
</details>
246+
247+
<details>
248+
<summary><code>Account#maximum_jobs_added_by_pipeline_changer returns 700 if the account is XYZ in ./spec/models/account_spec.rb</code></summary>
249+
250+
<code><pre>Failure/Error: expect(account.maximum_jobs_added_by_pipeline_changer).to eql(250)
251+
252+
expected: 700
253+
got: 500
254+
255+
(compared using eql?)
256+
./spec/models/account_spec.rb:78:in `block (3 levels) in <top (required)>'
257+
./spec/support/database.rb:16:in `block (2 levels) in <top (required)>'
258+
./spec/support/log.rb:17:in `run'
259+
./spec/support/log.rb:66:in `block (2 levels) in <top (required)>'</pre></code>
260+
261+
in <a href="#2">Job #2</a>
262+
</details>
263+
264+
<details>
265+
<summary><code>Account#maximum_jobs_added_by_pipeline_changer returns 700 if the account is XYZ in ./spec/models/account_spec.rb</code></summary>
266+
267+
<code><pre>Failure/Error: expect(account.maximum_jobs_added_by_pipeline_changer).to eql(250)
268+
269+
expected: 700
270+
got: 500
271+
272+
(compared using eql?)
273+
./spec/models/account_spec.rb:78:in `block (3 levels) in <top (required)>'
274+
./spec/support/database.rb:16:in `block (2 levels) in <top (required)>'
275+
./spec/support/log.rb:17:in `run'
276+
./spec/support/log.rb:66:in `block (2 levels) in <top (required)>'</pre></code>
277+
278+
in <a href="#3">Job #3</a>
279+
</details>
280+
281+
<details>
282+
<summary><code>Account#maximum_jobs_added_by_pipeline_changer returns 250 by default in ./spec/models/account_spec.rb</code></summary>
283+
284+
<code><pre>Failure/Error: expect(account.maximum_jobs_added_by_pipeline_changer).to eql(250)
285+
286+
expected: 250
287+
got: 500
288+
289+
(compared using eql?)
290+
./spec/models/account_spec.rb:78:in `block (3 levels) in <top (required)>'
291+
./spec/support/database.rb:16:in `block (2 levels) in <top (required)>'
292+
./spec/support/log.rb:17:in `run'
293+
./spec/support/log.rb:66:in `block (2 levels) in <top (required)>'</pre></code>
294+
295+
in <a href="#3">Job #3</a>
296+
</details>
297+
OUTPUT
298+
299+
assert_equal 0, status.exitstatus
300+
end
301+
302+
it "raises an error when an invalid failure-format is provided" do
303+
output, status = Open3.capture2e("env", "BUILDKITE_PLUGIN_JUNIT_ANNOTATE_FAILURE_FORMAT=kittens", "#{__dir__}/../bin/annotate", "#{__dir__}/test-failure-and-error/")
304+
assert_equal false, status.success?
305+
end
306+
218307
it "handles failures across multiple files in sub dirs" do
219308
output, status = Open3.capture2e("#{__dir__}/../bin/annotate", "#{__dir__}/tests-in-sub-dirs/")
220309

0 commit comments

Comments
 (0)