def fetch_diff_error_from_message(err_message, swap_diff):
    line_with_diff = None
    diff_error_message = None
    lines = err_message.split("\n")
    if err_message.startswith("AssertionError: assert"):
        # Everything in one line
        line_with_diff = lines[0][len("AssertionError: assert "):]
    elif len(err_message.split("\n")) > 1:
        err_line = lines[1]
        line_with_diff = err_line[len("assert "):]
        diff_error_message = lines[0]

    if line_with_diff and line_with_diff.count("==") == 1:
        parts = [x.strip() for x in line_with_diff.split("==")]
        parts = [
            s[1:-1] if s.startswith("'") or s.startswith('"') else s
            for s in parts
        ]
        # Pytest cuts too long lines, no need to check is_too_big
        expected, actual = parts[1], parts[0]

        if swap_diff:
            expected, actual = actual, expected

        expected = unformat_pytest_explanation(expected)
        actual = unformat_pytest_explanation(actual)

        return diff_tools.EqualsAssertionError(expected, actual,
                                               diff_error_message)
    else:
        return None
    def report_test_failure(self, test_id, report, message=None, report_output=True):
        if hasattr(report, 'duration'):
            duration = timedelta(seconds=report.duration)
        else:
            duration = None

        if message is None:
            message = self.format_location(report.location)

        self.ensure_test_start_reported(test_id)
        if report_output:
            self.report_test_output(report, test_id)

        diff_error = None
        try:
            err_message = str(report.longrepr.reprcrash.message)
            diff_name = diff_tools.EqualsAssertionError.__name__
            # There is a string like "foo.bar.DiffError: [serialized_data]"
            if diff_name in err_message:
                serialized_data = err_message[err_message.index(diff_name) + len(diff_name) + 1:]
                diff_error = diff_tools.deserialize_error(serialized_data)

            assertion_tuple = getattr(self.current_test_item, _ASSERTION_FAILURE_KEY, None)
            if assertion_tuple:
                op, left, right = assertion_tuple
                if self.swap_diff:
                    left, right = right, left
                diff_error = diff_tools.EqualsAssertionError(expected=right, actual=left)
        except Exception:
            pass

        if not diff_error:
            from .jb_local_exc_store import get_exception
            diff_error = get_exception()

        if diff_error:
            # Cut everything after postfix: it is internal view of DiffError
            strace = str(report.longrepr)
            data_postfix = "_ _ _ _ _"
            # Error message in pytest must be in "file.py:22 AssertionError" format
            # This message goes to strace
            # With custom error we must add real exception class explicitly
            if data_postfix in strace:
                strace = strace[0:strace.index(data_postfix)].strip()
                if strace.endswith(":") and diff_error.real_exception:
                    strace += " " + type(diff_error.real_exception).__name__
            self.teamcity.testFailed(test_id, diff_error.msg or message, strace,
                                     flowId=test_id,
                                     comparison_failure=diff_error
                                     )
        else:
            self.teamcity.testFailed(test_id, message, str(report.longrepr), flowId=test_id)
        self.report_test_finished(test_id, duration)
예제 #3
0
def fetch_diff_error_from_message(err_message):
    line_with_diff = None
    diff_error_message = None
    lines = err_message.split("\n")
    if err_message.startswith("AssertionError: assert"):
        # Everything in one line
        line_with_diff = lines[0][len("AssertionError: assert "):]
    elif len(err_message.split("\n")) > 1:
        err_line = lines[1]
        line_with_diff = err_line[len("assert "):]
        diff_error_message = lines[0]

    if line_with_diff and line_with_diff.count("==") == 1:
        parts = [x.strip() for x in line_with_diff.split("==")]
        parts = [s[1:-1] if s.startswith("'") or s.startswith('"') else s for s in parts]
        # Pytest cuts too long lines, no need to check is_too_big
        return diff_tools.EqualsAssertionError(parts[0], parts[1], diff_error_message)
    else:
        return None