-
Notifications
You must be signed in to change notification settings - Fork 55
Fix: support xcresult node types #503
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
Changes from all commits
1f58c1f
80adf0a
d1143c9
21c7f23
ab1db67
52365ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| __title__ = "codemagic-cli-tools" | ||
| __description__ = "CLI tools used in Codemagic builds" | ||
| __version__ = "0.69.0.dev" | ||
| __version__ = "0.69.1.dev" | ||
| __url__ = "https://github.com/codemagic-ci-cd/cli-tools" | ||
| __licence__ = "GNU General Public License v3.0" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -182,12 +182,17 @@ def convert(self) -> TestSuites: | |
|
|
||
| class Xcode16XcResultConverter(XcResultConverter): | ||
| @classmethod | ||
| def _iter_nodes(cls, root_node: XcTestNode, node_type: XcTestNodeType) -> Iterator[XcTestNode]: | ||
| def _iter_nodes( | ||
| cls, | ||
| root_node: XcTestNode, | ||
| node_type: XcTestNodeType, | ||
| skip_subtree_node_type: Optional[XcTestNodeType] = None, | ||
| ) -> Iterator[XcTestNode]: | ||
| if root_node.node_type is node_type: | ||
| yield root_node | ||
| else: | ||
| elif root_node.node_type is not skip_subtree_node_type: | ||
| for child in root_node.children: | ||
| yield from cls._iter_nodes(child, node_type) | ||
| yield from cls._iter_nodes(child, node_type, skip_subtree_node_type) | ||
|
|
||
| @classmethod | ||
| def _get_run_destination(cls, root_node: XcTestNode) -> Optional[XcDevice]: | ||
|
|
@@ -225,8 +230,15 @@ def _get_test_case_error(cls, xc_test_case: XcTestNode) -> Optional[Error]: | |
| if xc_test_case.result is not XcTestResult.FAILED: | ||
| return None | ||
|
|
||
| failure_messages_nodes = cls._iter_nodes(xc_test_case, XcTestNodeType.FAILURE_MESSAGE) | ||
| failure_messages = [node.name for node in failure_messages_nodes if node.name] | ||
| failure_messages_nodes = cls._iter_nodes( | ||
| xc_test_case, | ||
| XcTestNodeType.FAILURE_MESSAGE, | ||
| skip_subtree_node_type=XcTestNodeType.EXPECTED_FAILURE, | ||
| ) | ||
| unexpected_failure_message_nodes = ( | ||
| node for node in failure_messages_nodes if node.result is not XcTestResult.EXPECTED_FAILURE | ||
| ) | ||
| failure_messages = [node.name for node in unexpected_failure_message_nodes if node.name] | ||
| return Error( | ||
| message=failure_messages[0] if failure_messages else "", | ||
| type="Error" if any("caught error" in m for m in failure_messages) else "Failure", | ||
|
|
@@ -238,11 +250,32 @@ def _get_test_case_skipped(cls, xc_test_case: XcTestNode) -> Optional[Skipped]: | |
| if xc_test_case.result is not XcTestResult.SKIPPED: | ||
| return None | ||
|
|
||
| # Schema 0.1.0 / Xcode 16: skip reason is a Failure Message child with result Skipped. | ||
| failure_messages_nodes = cls._iter_nodes(xc_test_case, XcTestNodeType.FAILURE_MESSAGE) | ||
| skipped_message_nodes = (node for node in failure_messages_nodes if node.result is XcTestResult.SKIPPED) | ||
| skipped_messages = [node.name for node in skipped_message_nodes if node.name] | ||
|
|
||
| return Skipped(message="\n".join(skipped_messages)) | ||
| # Schema 0.2.0+ / Xcode 27: skip reason is a Skip Message child. | ||
| skip_message_nodes = cls._iter_nodes(xc_test_case, XcTestNodeType.SKIP_MESSAGE) | ||
| skipped_messages.extend(node.name for node in skip_message_nodes if node.name) | ||
|
Comment on lines
+259
to
+260
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are now different sources for skipped messages. Is it possible that we can capture duplicate messages? I'd add this to filter out anything that we don't need: unique_skipped_messages = dict.fromkeys(skipped_messages) |
||
|
|
||
| unique_skipped_messages = dict.fromkeys(skipped_messages) | ||
| return Skipped(message="\n".join(unique_skipped_messages)) | ||
|
|
||
| @classmethod | ||
| def _get_test_case_system_out(cls, xc_test_case: XcTestNode) -> Optional[str]: | ||
| expected_failure_nodes = cls._iter_nodes(xc_test_case, XcTestNodeType.EXPECTED_FAILURE) | ||
| reasons = [node.name for node in expected_failure_nodes if node.name] | ||
|
|
||
| failure_messages_nodes = cls._iter_nodes(xc_test_case, XcTestNodeType.FAILURE_MESSAGE) | ||
| expected_failure_message_nodes = ( | ||
| node for node in failure_messages_nodes if node.result is XcTestResult.EXPECTED_FAILURE | ||
| ) | ||
| reasons.extend(node.name for node in expected_failure_message_nodes if node.name) | ||
|
|
||
| if not reasons: | ||
| return None | ||
| return "\n".join(dict.fromkeys(reasons)) | ||
|
artemii-yanushevskyi marked this conversation as resolved.
|
||
|
|
||
| @classmethod | ||
| def parse_xcresult_test_node_duration_value(cls, xc_duration: str) -> float: | ||
|
|
@@ -292,6 +325,7 @@ def _get_test_case(cls, xc_test_case: XcTestNode, xc_test_suite: XcTestNode) -> | |
| time=cls._get_test_node_duration(xc_test_case), | ||
| status=xc_test_case.result.value if xc_test_case.result else None, | ||
| skipped=cls._get_test_case_skipped(xc_test_case), | ||
| system_out=cls._get_test_case_system_out(xc_test_case), | ||
| ) | ||
|
|
||
| @classmethod | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that there is support for expected failures I think this has an effect on our
_get_test_case_errorfunction. It might be that expected-failure messages can leak into theErrorof a failed test. I'm not sure if this is indeed the case, but if so, we should filter out the expected-failures fromfailure_messages. That would have to be verified with an actual test which contains both expected failures and errors.If true, then the error building needs to be made "smarter" to exclude the expected-failures.
Possible patch