Ver Fonte

Fixed #34658 -- Added SimpleTestCase.assertNotInHTML().

Nicolas Lupien há 1 ano atrás
pai
commit
2bf46c3825

+ 14 - 8
django/test/testcases.py

@@ -922,14 +922,17 @@ class SimpleTestCase(unittest.TestCase):
             msg_prefix += ": "
         haystack_repr = safe_repr(haystack)
         if count is not None:
-            self.assertEqual(
-                real_count,
-                count,
-                (
-                    f"{msg_prefix}Found {real_count} instances of {needle!r} (expected "
-                    f"{count}) in the following response\n{haystack_repr}"
-                ),
-            )
+            if count == 0:
+                msg = (
+                    f"{needle!r} unexpectedly found in the following response\n"
+                    f"{haystack_repr}"
+                )
+            else:
+                msg = (
+                    f"Found {real_count} instances of {needle!r} (expected {count}) in "
+                    f"the following response\n{haystack_repr}"
+                )
+            self.assertEqual(real_count, count, f"{msg_prefix}{msg}")
         else:
             self.assertTrue(
                 real_count != 0,
@@ -939,6 +942,9 @@ class SimpleTestCase(unittest.TestCase):
                 ),
             )
 
+    def assertNotInHTML(self, needle, haystack, msg_prefix=""):
+        self.assertInHTML(needle, haystack, count=0, msg_prefix=msg_prefix)
+
     def assertJSONEqual(self, raw, expected_data, msg=None):
         """
         Assert that the JSON fragments raw and expected_data are equal.

+ 3 - 0
docs/releases/5.1.txt

@@ -238,6 +238,9 @@ Tests
      self.client.post("/items/1", query_params={"action": "delete"})
      await self.async_client.post("/items/1", query_params={"action": "delete"})
 
+* The new :meth:`.SimpleTestCase.assertNotInHTML` assertion allows testing that
+  an HTML fragment is not contained in the given HTML haystack.
+
 URLs
 ~~~~
 

+ 10 - 0
docs/topics/testing/tools.txt

@@ -1905,6 +1905,16 @@ your test suite.
 
         In older versions, error messages didn't contain the ``haystack``.
 
+.. method:: SimpleTestCase.assertNotInHTML(needle, haystack, msg_prefix="")
+
+    .. versionadded:: 5.1
+
+    Asserts that the HTML fragment ``needle`` is *not* contained in the
+    ``haystack``.
+
+    Whitespace in most cases is ignored, and attribute ordering is not
+    significant. See :meth:`~SimpleTestCase.assertHTMLEqual` for more details.
+
 .. method:: SimpleTestCase.assertJSONEqual(raw, expected_data, msg=None)
 
     Asserts that the JSON fragments ``raw`` and ``expected_data`` are equal.

+ 10 - 0
tests/test_utils/tests.py

@@ -1053,6 +1053,16 @@ class InHTMLTests(SimpleTestCase):
         with self.assertRaisesMessage(AssertionError, msg):
             self.assertInHTML("<b>This</b>", haystack, 3)
 
+    def test_assert_not_in_html(self):
+        haystack = "<p><b>Hello</b> <span>there</span>! Hi <span>there</span>!</p>"
+        self.assertNotInHTML("<b>Hi</b>", haystack=haystack)
+        msg = (
+            "'<b>Hello</b>' unexpectedly found in the following response"
+            f"\n{haystack!r}"
+        )
+        with self.assertRaisesMessage(AssertionError, msg):
+            self.assertNotInHTML("<b>Hello</b>", haystack=haystack)
+
 
 class JSONEqualTests(SimpleTestCase):
     def test_simple_equal(self):