diff --git a/snap.cabal b/snap.cabal
--- a/snap.cabal
+++ b/snap.cabal
@@ -1,5 +1,5 @@
 name:           snap
-version:        0.13.2.7
+version:        0.13.2.8
 synopsis:       Top-level package for the Snap Web Framework
 description:
     This is the top-level package for the official Snap Framework libraries.
@@ -151,7 +151,7 @@
     cereal                    >= 0.3      && < 0.5,
     clientsession             >= 0.8      && < 0.10,
     comonad                   >= 1.1      && < 4.3,
-    configurator              >= 0.1      && < 0.3,
+    configurator              >= 0.1      && < 0.4,
     containers                >= 0.3      && < 0.6,
     directory                 >= 1.0      && < 1.3,
     directory-tree            >= 0.11     && < 0.13,
diff --git a/src/Snap/Snaplet/Test.hs b/src/Snap/Snaplet/Test.hs
--- a/src/Snap/Snaplet/Test.hs
+++ b/src/Snap/Snaplet/Test.hs
@@ -4,7 +4,12 @@
   (
     -- ** Testing handlers
     evalHandler
+  , evalHandler'
   , runHandler
+  , runHandler'
+  , getSnaplet
+  , closeSnaplet
+  , InitializerState
   , withTemporaryFile
   )
   where
@@ -15,7 +20,8 @@
 import           Control.Exception.Base (finally)
 import qualified Control.Exception as E
 import           Control.Monad.IO.Class
-import           Data.Maybe (fromMaybe) 
+import           Control.Monad (join)
+import           Data.Maybe (fromMaybe)
 import           Data.IORef
 import           Data.Text
 import           System.Directory
@@ -52,7 +58,7 @@
 
 ------------------------------------------------------------------------------
 -- | Helper to keep "runHandler" and "evalHandler" DRY.
-execHandlerComputation :: MonadIO m 
+execHandlerComputation :: MonadIO m
                        => (RequestBuilder m () -> Snap v -> m a)
                        -> Maybe String
                        -> RequestBuilder m ()
@@ -63,15 +69,25 @@
     app <- getSnaplet env s
     case app of
       (Left e) -> return $ Left e
-      (Right (a, is)) -> do
-          res <- f rq $ runPureBase h a
-          -- Run the cleanup action
-          liftIO $ do
-              cleanupAction <- readIORef $ _cleanup is
-              cleanupAction
-          return $ Right res
+      (Right (a, is)) -> execHandlerSnaplet a is f rq h
 
+
 ------------------------------------------------------------------------------
+-- | Helper to allow multiple calls to "runHandler" or "evalHandler" without
+-- multiple initializations.
+execHandlerSnaplet :: MonadIO m
+                   => Snaplet b
+                   -> InitializerState b
+                   -> (RequestBuilder m () -> Snap v -> m a)
+                   -> RequestBuilder m ()
+                   -> Handler b b v
+                   -> m (Either Text a)
+execHandlerSnaplet a is f rq h = do
+  res <- f rq $ runPureBase h a
+  closeSnaplet is
+  return $ Right res
+
+------------------------------------------------------------------------------
 -- | Given a Snaplet Handler and a 'RequestBuilder' defining
 -- a test request, runs the Handler, producing an HTTP 'Response'.
 --
@@ -86,7 +102,19 @@
            -> m (Either Text Response)
 runHandler = execHandlerComputation ST.runHandler
 
+------------------------------------------------------------------------------
+-- | A variant of runHandler that takes the Snaplet and InitializerState as
+-- produced by getSnaplet, so those can be re-used across requests. It does not
+-- run cleanup actions, so closeSnaplet should be used when finished.
+runHandler' :: MonadIO m
+            => Snaplet b
+            -> InitializerState b
+            -> RequestBuilder m ()
+            -> Handler b b v
+            -> m (Either Text Response)
+runHandler' a is = execHandlerSnaplet a is ST.runHandler
 
+
 ------------------------------------------------------------------------------
 -- | Given a Snaplet Handler, a 'SnapletInit' specifying the initial state,
 --  and a 'RequestBuilder' defining a test request, runs the handler,
@@ -99,7 +127,7 @@
 -- 'evalHandler defined in Snap.Test, because due to the fact running
 -- the initializer inside 'SnapletInit' can throw an exception.
 evalHandler :: MonadIO m
-            => Maybe String 
+            => Maybe String
             -> RequestBuilder m ()
             -> Handler b b a
             -> SnapletInit b b
@@ -108,11 +136,23 @@
 
 
 ------------------------------------------------------------------------------
+-- | A variant of evalHandler that takes the Snaplet and InitializerState as
+-- produced by getSnaplet, so those can be re-used across requests. It does not
+-- run cleanup actions, so closeSnaplet should be used when finished.
+evalHandler' :: MonadIO m
+             => Snaplet b
+             -> InitializerState b
+             -> RequestBuilder m ()
+             -> Handler b b a
+             -> m (Either Text a)
+evalHandler' a is = execHandlerSnaplet a is ST.evalHandler
+
+------------------------------------------------------------------------------
 -- | Run the given initializer, yielding a tuple where the first element is
 -- a @Snaplet b@, or an error message whether the initializer threw an
--- exception.                                                       
+-- exception. This is only needed for runHandler'/evalHandler'.
 getSnaplet :: MonadIO m
-           => Maybe String  
+           => Maybe String
            -> SnapletInit b b
            -> m (Either Text (Snaplet b, InitializerState b))
 getSnaplet env (SnapletInit initializer) = liftIO $ do
@@ -120,3 +160,11 @@
     let resetter f = modifyMVar_ mvar (return . f)
     runInitializer resetter (fromMaybe "devel" env) initializer
 
+------------------------------------------------------------------------------
+-- | Run cleanup for an initializer. Should be run after finished using the
+-- state that getSnaplet returned. Only needed if using getSnaplet and
+-- evalHandler'/runHandler'.
+closeSnaplet :: MonadIO m
+             => InitializerState b
+             -> m ()
+closeSnaplet is = liftIO $ join (readIORef $ _cleanup is)
diff --git a/test/runTestsAndCoverage.sh b/test/runTestsAndCoverage.sh
--- a/test/runTestsAndCoverage.sh
+++ b/test/runTestsAndCoverage.sh
@@ -43,6 +43,8 @@
 Snap.Snaplet.Internal.RST.Tests
 Snap.Snaplet.Internal.Tests
 Snap.TestCommon
+Snap.Snaplet.Test.App
+Snap.Snaplet.Test.Tests
 '
 
 EXCL=""
diff --git a/test/snap-testsuite.cabal b/test/snap-testsuite.cabal
--- a/test/snap-testsuite.cabal
+++ b/test/snap-testsuite.cabal
@@ -32,7 +32,7 @@
     cereal                     >= 0.3      && < 0.5,
     clientsession              >= 0.8      && < 0.10,
     comonad                    >= 1.1      && < 4.3,
-    configurator               >= 0.1      && < 0.3,
+    configurator               >= 0.1      && < 0.4,
     containers                 >= 0.3      && < 0.6,
     directory                  >= 1.0      && < 1.3,
     directory-tree             >= 0.10     && < 0.13,
@@ -104,7 +104,7 @@
     cereal                     >= 0.3      && < 0.5,
     clientsession              >= 0.8      && < 0.10,
     comonad                    >= 1.1      && < 4.3,
-    configurator               >= 0.1      && < 0.3,
+    configurator               >= 0.1      && < 0.4,
     containers                 >= 0.3      && < 0.6,
     directory                  >= 1.0      && < 1.3,
     directory-tree             >= 0.10     && < 0.13,
@@ -186,7 +186,7 @@
     cereal                     >= 0.3      && < 0.5,
     clientsession              >= 0.8      && < 0.10,
     comonad                    >= 1.1      && < 4.3,
-    configurator               >= 0.1      && < 0.3,
+    configurator               >= 0.1      && < 0.4,
     containers                 >= 0.3      && < 0.6,
     directory                  >= 1.0      && < 1.3,
     directory-tree             >= 0.10     && < 0.13,
diff --git a/test/suite/TestSuite.hs b/test/suite/TestSuite.hs
--- a/test/suite/TestSuite.hs
+++ b/test/suite/TestSuite.hs
@@ -29,6 +29,7 @@
 import qualified Snap.Snaplet.Internal.RST.Tests
 import qualified Snap.Snaplet.Internal.Tests
 import qualified Snap.Snaplet.Auth.Tests
+import qualified Snap.Snaplet.Test.Tests
 import           Snap.TestCommon
 
 import           SafeCWD
@@ -52,6 +53,7 @@
   where tests = mutuallyExclusive $
                 testGroup "snap" [ internalServerTests
                                  , Snap.Snaplet.Auth.Tests.tests
+                                 , Snap.Snaplet.Test.Tests.tests
                                  , testDefault
                                  , testBarebones
                                  , testTutorial
@@ -140,5 +142,3 @@
     testIt = do
         body <- get (S.pack $ "http://127.0.0.1:"++(show port)++"/hello") concatHandler
         assertEqual "server not up" "hello world" body
-
-
