diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 1.5.3
+
+* Added bodyNotContains [#1271](https://github.com/yesodweb/yesod/pull/1271)
+
 ## 1.5.2
 
 * Added assertEq, deprecated assertEqual [#1259](https://github.com/yesodweb/yesod/pull/1259)
@@ -5,7 +9,7 @@
 ## 1.5.1.1
 
 * Fix `addToken_` needing a trailing space and allows multiples spaces in css selector.
-	
+
 ## 1.5.1.0
 
 * Better error provenance for stuff invoking withResponse' [#1191](https://github.com/yesodweb/yesod/pull/1191)
diff --git a/Yesod/Test.hs b/Yesod/Test.hs
--- a/Yesod/Test.hs
+++ b/Yesod/Test.hs
@@ -93,6 +93,7 @@
     , statusIs
     , bodyEquals
     , bodyContains
+    , bodyNotContains
     , htmlAllContain
     , htmlAnyContain
     , htmlNoneContain
@@ -394,6 +395,14 @@
 bodyContains text = withResponse $ \ res ->
   liftIO $ HUnit.assertBool ("Expected body to contain " ++ text) $
     (simpleBody res) `contains` text
+
+-- | Assert the last response doesn't have the given text. The check is performed using the response
+-- body in full text form.
+-- @since 1.5.3
+bodyNotContains :: String -> YesodExample site ()
+bodyNotContains text = withResponse $ \ res ->
+  liftIO $ HUnit.assertBool ("Expected body not to contain " ++ text) $
+    not $ contains (simpleBody res) text
 
 contains :: BSL8.ByteString -> String -> Bool
 contains a b = DL.isInfixOf b (TL.unpack $ decodeUtf8 a)
diff --git a/yesod-test.cabal b/yesod-test.cabal
--- a/yesod-test.cabal
+++ b/yesod-test.cabal
@@ -1,5 +1,5 @@
 name:               yesod-test
-version:            1.5.2
+version:            1.5.3
 license:            MIT
 license-file:       LICENSE
 author:             Nubis <nubis@woobiz.com.ar>
