Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include test message in annotation details #357

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 21 additions & 5 deletions python/publish/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,12 +709,13 @@ def get_long_summary_with_digest_md(stats: UnitTestRunResultsOrDeltaResults,


def get_case_messages(case_results: UnitTestCaseResults) -> CaseMessages:
""" Re-index cases from test+state to test+state+message. """
messages = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
for key in case_results:
for state in case_results[key]:
for case in case_results[key][state]:
for test in case_results:
for state in case_results[test]:
for case in case_results[test][state]:
message = case.message if case.result in ['skipped', 'disabled'] else case.content
messages[key][state][message].append(case)
messages[test][state][message].append(case)
return CaseMessages(messages)


Expand Down Expand Up @@ -791,6 +792,21 @@ def get_case_annotation(messages: CaseMessages,
'notice'
)

def message_is_contained_in_content(message: Optional[str], content: Optional[str]) -> bool:
# ignore new lines and any leading or trailing white spaces
if content and message:
content = re.sub(r'\s+', ' ', content.strip())
message = re.sub(r'\s+', ' ', message.strip())
return content.startswith(message)
return False

# pick details from message and content, but try to avoid redundancy (e.g. when content repeats message)
details = [detail.rstrip()
for detail in ([case.content]
if message_is_contained_in_content(case.message, case.content)
else [case.message, case.content])
if detail and detail.rstrip()]

return Annotation(
path=test_file or class_name or '/',
start_line=line,
Expand All @@ -800,7 +816,7 @@ def get_case_annotation(messages: CaseMessages,
annotation_level=level,
message='\n'.join(sorted(same_result_files)),
title=title,
raw_details=message
raw_details='\n'.join(details) if details else None
)


Expand Down
12 changes: 9 additions & 3 deletions python/publish/unittestresults.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,11 +416,17 @@ def get_test_results(parsed_results: ParsedUnitTestResultsWithCommit,
cases_errors = [case for case in cases if case.result == 'error']
cases_time = sum([case.time or 0 for case in cases])

# group cases by tests
# index cases by tests and state
cases_results = UnitTestCaseResults()
for case in cases:
key = (case.test_file if dedup_classes_by_file_name else None, case.class_name, case.test_name)
cases_results[key][case.result if case.result != 'disabled' else 'skipped'].append(case)
# index by test file name (when de-duplicating by file name), class name and test name
test = (case.test_file if dedup_classes_by_file_name else None, case.class_name, case.test_name)

# second index by state
state = case.result if case.result != 'disabled' else 'skipped'

# collect cases of test and state
cases_results[test][state].append(case)

test_results = dict()
for test, states in cases_results.items():
Expand Down
79 changes: 79 additions & 0 deletions python/test/files/junit-xml/junit.multiresult.annotations
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
[
{
'name': 'Test Results',
'head_sha': 'commit sha',
'status': 'completed',
'conclusion': 'failure',
'output': {
'title': '1 errors, 1 fail, 1 skipped, 1 pass in 1s',
'summary':
'1 files\u2004\u20031 suites\u2004\u2003\u20021s '
'[:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-ac'
'tion/blob/v1.20/README.md#the-symbols "duration of all tests")\n4 '
'tests\u20031 '
'[:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-re'
'sult-action/blob/v1.20/README.md#the-symbols "passed tests")\u20031 '
'[:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/b'
'lob/v1.20/README.md#the-symbols "skipped / disabled tests")\u20031 '
'[:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blo'
'b/v1.20/README.md#the-symbols "failed tests")\u20031 '
'[:fire:](https://github.com/EnricoMi/publish-unit-test-result-action/'
'blob/v1.20/README.md#the-symbols "test errors")\n4 runs\u2006\u2003'
'-2 '
'[:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-re'
'sult-action/blob/v1.20/README.md#the-symbols "passed tests")\u20033 '
'[:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/b'
'lob/v1.20/README.md#the-symbols "skipped / disabled tests")\u20032 '
'[:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blo'
'b/v1.20/README.md#the-symbols "failed tests")\u20031 '
'[:fire:](https://github.com/EnricoMi/publish-unit-test-result-action/'
'blob/v1.20/README.md#the-symbols "test errors")\n\nResults for '
'commit commit s.\n\n'
'[test-results]:data:application/gzip;base64,H4sIAAAAAAAC/1WMOw6AIBAFr'
'0KotfBTeRlCEONGPmYXKuPdlQhEujdvkrn4BkYTX9jQMU4RQoU1ogzgXcZXhKTmsgVFpf'
'5S0AFnc2wSTHNoRI/5wehKL82S68d6fLmpcK5V/48pby2EF/JitEt+P6y+BE/eAAAA\n',
'annotations': [
{
'path': 'test class',
'start_line': 0,
'end_line': 0,
'annotation_level': 'failure',
'message': 'junit.multiresult.xml',
'title': 'test that errors (test class) with error',
'raw_details': 'test teardown failure\nstdout'
},
{
'path': 'test class',
'start_line': 0,
'end_line': 0,
'annotation_level': 'warning',
'message': 'junit.multiresult.xml',
'title': 'test that fails (test class) failed',
'raw_details': 'test failure\nAssertion failed'
},
{
'path': '.github',
'start_line': 0,
'end_line': 0,
'annotation_level': 'notice',
'message':
'There is 1 skipped test, see "Raw output" for the name of the '
'skipped test.',
'title': '1 skipped test found',
'raw_details': 'test class ‑ test that is skipped'
},
{
'path': '.github',
'start_line': 0,
'end_line': 0,
'annotation_level': 'notice',
'message': 'There are 4 tests, see "Raw output" for the full list of tests.',
'title': '4 tests found',
'raw_details':
'test class ‑ test that errors\ntest class ‑ test that fails\ntest '
'class ‑ test that is skipped\ntest class ‑ test that succeeds'
}
]
}
}
]
70 changes: 70 additions & 0 deletions python/test/files/junit-xml/minimal-attributes.annotations
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
[
{
'name': 'Test Results',
'head_sha': 'commit sha',
'status': 'completed',
'conclusion': 'failure',
'output': {
'title': '1 errors, 1 fail, 1 skipped, 1 pass in 0s',
'summary':
'4 tests\u2002\u2003\u20031 '
'[:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-re'
'sult-action/blob/v1.20/README.md#the-symbols "passed tests")\u2003\u2003'
'0s '
'[:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-ac'
'tion/blob/v1.20/README.md#the-symbols "duration of all tests")\n1 '
'suites\u2003\u20031 '
'[:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/b'
'lob/v1.20/README.md#the-symbols "skipped / disabled tests")\n1 files\u2004'
'\u2002\u2003\u20031 '
'[:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blo'
'b/v1.20/README.md#the-symbols "failed tests")\u2003\u20031 '
'[:fire:](https://github.com/EnricoMi/publish-unit-test-result-action/'
'blob/v1.20/README.md#the-symbols "test errors")\n\nResults for '
'commit commit s.\n\n'
'[test-results]:data:application/gzip;base64,H4sIAAAAAAAC/1WMOw6AIBAFr'
'0KoLTSx8jKGIMSNfMwClfHuAoJC92Z2MxeVoISjC5kGQl0A/8EWkHmwJuIYMR58Os11ry'
'5wXn6LOODshGSgOiEQLRaDwdRemm3u5b+WuYllblvcag0+QlnE7YzeD8XajRvdAAAA\n',
'annotations': [
{
'path': 'ClassName',
'start_line': 0,
'end_line': 0,
'annotation_level': 'warning',
'message': 'minimal-attributes.xml',
'title': 'failed_test (ClassName) failed'
},
{
'path': 'ClassName',
'start_line': 0,
'end_line': 0,
'annotation_level': 'failure',
'message': 'minimal-attributes.xml',
'title': 'error_test (ClassName) with error'
},
{
'path': '.github',
'start_line': 0,
'end_line': 0,
'annotation_level': 'notice',
'message':
'There is 1 skipped test, see "Raw output" for the name of the '
'skipped test.',
'title': '1 skipped test found',
'raw_details': 'ClassName ‑ skipped_test'
},
{
'path': '.github',
'start_line': 0,
'end_line': 0,
'annotation_level': 'notice',
'message': 'There are 4 tests, see "Raw output" for the full list of tests.',
'title': '4 tests found',
'raw_details':
'ClassName ‑ error_test\nClassName ‑ failed_test\nClassName ‑ '
'skipped_test\nClassName ‑ test_name'
}
]
}
}
]
31 changes: 31 additions & 0 deletions python/test/files/junit-xml/no-attributes.annotations
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[
{
'name': 'Test Results',
'head_sha': 'commit sha',
'status': 'completed',
'conclusion': 'failure',
'output': {
'title': '1 errors, 1 fail, 1 skipped, 1 pass in 0s',
'summary':
'4 tests\u2002\u2003\u20031 '
'[:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-re'
'sult-action/blob/v1.20/README.md#the-symbols "passed tests")\u2003\u2003'
'0s '
'[:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-ac'
'tion/blob/v1.20/README.md#the-symbols "duration of all tests")\n1 '
'suites\u2003\u20031 '
'[:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/b'
'lob/v1.20/README.md#the-symbols "skipped / disabled tests")\n1 files\u2004'
'\u2002\u2003\u20031 '
'[:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blo'
'b/v1.20/README.md#the-symbols "failed tests")\u2003\u20031 '
'[:fire:](https://github.com/EnricoMi/publish-unit-test-result-action/'
'blob/v1.20/README.md#the-symbols "test errors")\n\nResults for '
'commit commit s.\n\n'
'[test-results]:data:application/gzip;base64,H4sIAAAAAAAC/1WMOw6AIBAFr'
'0KoLTSx8jKGIMSNfMwClfHuAoJC92Z2MxeVoISjC5kGQl0A/8EWkHmwJuIYMR58Os11ry'
'5wXn6LOODshGSgOiEQLRaDwdRemm3u5b+WuYllblvcag0+QlnE7YzeD8XajRvdAAAA\n',
'annotations': []
}
}
]
30 changes: 30 additions & 0 deletions python/test/files/junit-xml/no-cases-but-tests.annotations
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[
{
'name': 'Test Results',
'head_sha': 'commit sha',
'status': 'completed',
'conclusion': 'failure',
'output': {
'title': '1 fail, 2 skipped, 3 pass in 0s',
'summary':
'6 tests\u2002\u2003\u20033 '
'[:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-re'
'sult-action/blob/v1.20/README.md#the-symbols "passed tests")\u2003\u2003'
'0s '
'[:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-ac'
'tion/blob/v1.20/README.md#the-symbols "duration of all tests")\n1 '
'suites\u2003\u20032 '
'[:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/b'
'lob/v1.20/README.md#the-symbols "skipped / disabled tests")\n1 files\u2004'
'\u2002\u2003\u20031 '
'[:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blo'
'b/v1.20/README.md#the-symbols "failed tests")\n\nResults for commit '
'commit s.\n\n'
'[test-results]:data:application/gzip;base64,H4sIAAAAAAAC/02MOw6AIBAFr'
'0KoLfwkFl7GEJS4UcEsUBnv7spH6N7MS+bmCo7V8ol1DePWg/th8SgcGE3YEtLhvmvMe7'
'ZeShJDETtcJPpfKAFHqkWxIhpMQfQ6975Z5yKXWuAqFrhuSXOe4AjSYnYT/HkBNCXSZd0'
'AAAA=\n',
'annotations': []
}
}
]
29 changes: 29 additions & 0 deletions python/test/files/junit-xml/no-cases.annotations
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[
{
'name': 'Test Results',
'head_sha': 'commit sha',
'status': 'completed',
'conclusion': 'success',
'output': {
'title': 'No tests found',
'summary':
'0 tests\u2002\u2003\u20030 '
'[:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-re'
'sult-action/blob/v1.20/README.md#the-symbols "passed tests")\u2003\u2003'
'0s '
'[:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-ac'
'tion/blob/v1.20/README.md#the-symbols "duration of all tests")\n1 '
'suites\u2003\u20030 '
'[:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/b'
'lob/v1.20/README.md#the-symbols "skipped / disabled tests")\n1 files\u2004'
'\u2002\u2003\u20030 '
'[:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blo'
'b/v1.20/README.md#the-symbols "failed tests")\n\nResults for commit '
'commit s.\n\n'
'[test-results]:data:application/gzip;base64,H4sIAAAAAAAC/1WMOw6AIBAFr'
'0K2ttDWyxiCEDfyMbtQGe8uQaNL92ZeMic49JZhVtOggAvmD9ZCOmOKFceK9cgs98LFmF'
'7seHTCafSdsESJXkMlspgy9/BfayxijWXLpBAwV3iX4k3DdQOuuvQ/3QAAAA==\n',
'annotations': []
}
}
]
39 changes: 39 additions & 0 deletions python/test/files/junit-xml/non-junit.annotations
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
[
{
'name': 'Test Results',
'head_sha': 'commit sha',
'status': 'completed',
'conclusion': 'failure',
'output': {
'title': '1 parse errors',
'summary':
'0 tests\u2002\u2003\u20030 '
'[:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-re'
'sult-action/blob/v1.20/README.md#the-symbols "passed tests")\u2003\u2003'
'0s '
'[:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-ac'
'tion/blob/v1.20/README.md#the-symbols "duration of all tests")\n0 '
'suites\u2003\u20030 '
'[:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/b'
'lob/v1.20/README.md#the-symbols "skipped / disabled tests")\n1 files\u2004'
'\u2002\u2003\u20030 '
'[:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blo'
'b/v1.20/README.md#the-symbols "failed tests")\n1 errors\n\nResults '
'for commit commit s.\n\n'
'[test-results]:data:application/gzip;base64,H4sIAAAAAAAC/1WMywqAIBBFf'
'0Vm3aK2/UyIKQ35iBldRf+emNC4u+dcODc49JZhVcukgAvmBnOFvZDOmGLHemSWe+NizC'
'hOvAbhNPpBWKJE3VCJLKbMffzXGotYY9kyKQTMFfpSfGh4XnRU87HdAAAA\n',
'annotations': [
{
'path': 'non-junit.xml',
'start_line': 0,
'end_line': 0,
'annotation_level': 'failure',
'message': 'Invalid format.',
'title': 'Error processing result file',
'raw_details': 'non-junit.xml'
}
]
}
}
]