diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
-## [_Unreleased_](https://github.com/freckle/freckle-app/compare/freckle-app-v1.23.2.0...main)
+## [_Unreleased_](https://github.com/freckle/freckle-app/compare/freckle-app-v1.23.3.0...main)
+
+## [v1.23.3.0](https://github.com/freckle/freckle-app/compare/freckle-app-v1.23.2.0...freckle-app-v1.23.3.0)
+
+- Add to `Freckle.App.Test`: `withFailureDetail`
+- Add to `Freckle.App.Test.Yesod`: `statusIs2xx`
 
 ## [v1.23.2.0](https://github.com/freckle/freckle-app/compare/freckle-app-v1.23.1.0...freckle-app-v1.23.2.0)
 
diff --git a/freckle-app.cabal b/freckle-app.cabal
--- a/freckle-app.cabal
+++ b/freckle-app.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.22
 name:               freckle-app
-version:            1.23.2.0
+version:            1.23.3.0
 license:            MIT
 license-file:       LICENSE
 maintainer:         Freckle Education
diff --git a/library/Freckle/App/Test.hs b/library/Freckle/App/Test.hs
--- a/library/Freckle/App/Test.hs
+++ b/library/Freckle/App/Test.hs
@@ -14,6 +14,7 @@
   , expectJust
   , expectRight
   , expect
+  , withFailureDetail
 
     -- * Re-exports
   , module X
@@ -48,6 +49,7 @@
 import Control.Monad.Random (MonadRandom (..))
 import Control.Monad.Reader
 import Control.Monad.Trans.Control
+import Data.List (intercalate)
 import Database.Persist.Sql (SqlPersistT, runSqlPool)
 import Freckle.App.Database
   ( HasSqlPool (..)
@@ -58,6 +60,7 @@
 import Freckle.App.Dotenv qualified as Dotenv
 import Freckle.App.Exception.MonadThrow qualified as MonadThrow
 import Freckle.App.OpenTelemetry
+import Test.HUnit.Lang (FailureReason (..), HUnitFailure (..))
 import Test.Hspec qualified as Hspec hiding (expectationFailure)
 import Test.Hspec.Core.Spec (Arg, Example, SpecWith, evaluateExample)
 import Test.Hspec.Expectations.Lifted qualified as Hspec (expectationFailure)
@@ -193,3 +196,21 @@
 expect f a = case f a of
   Nothing -> expectationFailure $ "predicate failed on: " <> show a
   Just b -> pure b
+
+-- | Prepend a message to any 'HUnitFailure' thrown by an action
+--
+-- This can be useful when you have additional information that was generated during
+-- the execution of a test that would be helpful in understanding why the test failed.
+withFailureDetail
+  :: (HasCallStack, MonadUnliftIO m) => (HasCallStack => m a) -> String -> m a
+withFailureDetail action message =
+  catch action $ \(HUnitFailure l r) ->
+    throwM $ HUnitFailure l $ case r of
+      Reason reason -> Reason $ intercalate "\n\n" [message, reason]
+      ExpectedButGot maybeReason expected got ->
+        ExpectedButGot
+          (Just $ intercalate "\n\n" $ message : maybeToList maybeReason)
+          expected
+          got
+
+infix 0 `withFailureDetail`
diff --git a/library/Freckle/App/Test/Yesod.hs b/library/Freckle/App/Test/Yesod.hs
--- a/library/Freckle/App/Test/Yesod.hs
+++ b/library/Freckle/App/Test/Yesod.hs
@@ -47,6 +47,7 @@
 
     -- ** Status
   , statusIs
+  , statusIs2XX
 
     -- ** Header fields
   , assertHeader
@@ -89,6 +90,7 @@
 import Data.Csv qualified as CSV
 import Data.Text qualified as T
 import Data.Vector qualified as V
+import Freckle.App.Http (statusIsSuccessful)
 import Freckle.App.Test (expectationFailure)
 import Network.HTTP.Types.Header (hAccept, hAcceptLanguage, hContentType)
 import Network.Wai.Test (SResponse (..))
@@ -237,6 +239,13 @@
 statusIs
   :: forall m site. (MonadYesodExample site m, HasCallStack) => Int -> m ()
 statusIs = liftYesodExample . Yesod.Test.statusIs
+
+statusIs2XX :: MonadYesodExample site m => m ()
+statusIs2XX = liftYesodExample $ withResponse $ \response -> do
+  let status = simpleStatus response
+  unless (statusIsSuccessful status) $ do
+    expectationFailure $
+      "Response status " <> show status <> " should have been 2xx"
 
 -- | Assert that the given header field's value satisfied some predicate
 assertHeaderSatisfies
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: freckle-app
-version: 1.23.2.0
+version: 1.23.3.0
 
 maintainer: Freckle Education
 category: Utils
