From 2367e6e9bf4cf021510ed212e2e9f05cf35b8697 Mon Sep 17 00:00:00 2001 From: David Szotten Date: Thu, 19 Aug 2021 11:24:51 +0000 Subject: [PATCH 1/2] refactor ci helper to prepare for re-use --- src/_pytest/assertion/truncate.py | 10 ++-------- src/_pytest/assertion/util.py | 8 +++++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/_pytest/assertion/truncate.py b/src/_pytest/assertion/truncate.py index 5ba9ddca7..ce148dca0 100644 --- a/src/_pytest/assertion/truncate.py +++ b/src/_pytest/assertion/truncate.py @@ -3,10 +3,10 @@ Current default behaviour is to truncate assertion explanations at ~8 terminal lines, unless running in "-vv" mode or running on CI. """ -import os from typing import List from typing import Optional +from _pytest.assertion import util from _pytest.nodes import Item @@ -27,13 +27,7 @@ def truncate_if_required( def _should_truncate_item(item: Item) -> bool: """Whether or not this test item is eligible for truncation.""" verbose = item.config.option.verbose - return verbose < 2 and not _running_on_ci() - - -def _running_on_ci() -> bool: - """Check if we're currently running on a CI system.""" - env_vars = ["CI", "BUILD_NUMBER"] - return any(var in os.environ for var in env_vars) + return verbose < 2 and not util.running_on_ci() def _truncate_explanation( diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index d29a2a010..493ab9142 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -1,5 +1,6 @@ """Utilities for assertion debugging.""" import collections.abc +import os import pprint from typing import AbstractSet from typing import Any @@ -17,7 +18,6 @@ from _pytest._io.saferepr import safeformat from _pytest._io.saferepr import saferepr from _pytest.config import Config - # The _reprcompare attribute on the util module is used by the new assertion # interpretation code and assertion rewriter to detect this plugin was # loaded and in turn call the hooks defined here as part of the @@ -490,3 +490,9 @@ def _notin_text(term: str, text: str, verbose: int = 0) -> List[str]: else: newdiff.append(line) return newdiff + + +def running_on_ci() -> bool: + """Check if we're currently running on a CI system.""" + env_vars = ["CI", "BUILD_NUMBER"] + return any(var in os.environ for var in env_vars) From d5c020d8c5958e14fb401f4e4c706ccc612d41af Mon Sep 17 00:00:00 2001 From: David Szotten Date: Thu, 19 Aug 2021 16:27:07 +0000 Subject: [PATCH 2/2] always show full diff in ci follow-up to #1314, for similar reasons closes #9023 --- changelog/9023.feature.rst | 4 ++++ src/_pytest/assertion/util.py | 2 +- testing/test_assertion.py | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 changelog/9023.feature.rst diff --git a/changelog/9023.feature.rst b/changelog/9023.feature.rst new file mode 100644 index 000000000..86a819a84 --- /dev/null +++ b/changelog/9023.feature.rst @@ -0,0 +1,4 @@ + +Full diffs are now always shown for equality assertions of iterables when +`CI` or ``BUILD_NUMBER`` is found in the environment, even when ``-v`` isn't +used. diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 493ab9142..19f1089c2 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -287,7 +287,7 @@ def _surrounding_parens_on_own_lines(lines: List[str]) -> None: def _compare_eq_iterable( left: Iterable[Any], right: Iterable[Any], verbose: int = 0 ) -> List[str]: - if not verbose: + if not verbose and not running_on_ci(): return ["Use -v to get the full diff"] # dynamic import to speedup pytest import difflib diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 289fe5b08..e8717590d 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -13,6 +13,7 @@ import pytest from _pytest import outcomes from _pytest.assertion import truncate from _pytest.assertion import util +from _pytest.monkeypatch import MonkeyPatch from _pytest.pytester import Pytester @@ -448,6 +449,25 @@ class TestAssert_reprcompare: assert verbose_expl is not None assert "\n".join(verbose_expl).endswith(textwrap.dedent(expected).strip()) + def test_iterable_full_diff_ci( + self, monkeypatch: MonkeyPatch, pytester: Pytester + ) -> None: + pytester.makepyfile( + r""" + def test_full_diff(): + left = [0, 1] + right = [0, 2] + assert left == right + """ + ) + monkeypatch.setenv("CI", "true") + result = pytester.runpytest() + result.stdout.fnmatch_lines(["E Full diff:"]) + + monkeypatch.delenv("CI", raising=False) + result = pytester.runpytest() + result.stdout.fnmatch_lines(["E Use -v to get the full diff"]) + def test_list_different_lengths(self) -> None: expl = callequal([0, 1], [0, 1, 2]) assert expl is not None