diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # ChangeLog for yesod-test
 
+## 1.6.6.2
+
+addPostParam will now URL-encode keys and values to prevent corruption
+when special characters such as `&` are used
+[#1617](https://github.com/yesodweb/yesod/pull/1617)
+
 ## 1.6.6.1
 
 * Documentation fixes
diff --git a/Yesod/Test.hs b/Yesod/Test.hs
--- a/Yesod/Test.hs
+++ b/Yesod/Test.hs
@@ -1266,14 +1266,14 @@
                           ([ ("Cookie", cookieValue) ] ++ headersForPostData rbdPostData)
                           method extraHeaders urlPath urlQuery)
         simpleRequestBody' (MultipleItemsPostData x) =
-          BSL8.fromChunks $ return $ TE.encodeUtf8 $ T.intercalate "&"
-          $ map singlepartPart x
+          BSL8.fromChunks $ return $ H.renderSimpleQuery False
+          $ concatMap singlepartPart x
         simpleRequestBody' (BinaryPostData x) = x
         cookieValue = Builder.toByteString $ Cookie.renderCookies cookiePairs
         cookiePairs = [ (Cookie.setCookieName c, Cookie.setCookieValue c)
                       | c <- map snd $ M.toList cookies ]
-        singlepartPart (ReqFilePart _ _ _ _) = ""
-        singlepartPart (ReqKvPart k v) = T.concat [k,"=",v]
+        singlepartPart (ReqFilePart _ _ _ _) = []
+        singlepartPart (ReqKvPart k v) = [(TE.encodeUtf8 k, TE.encodeUtf8 v)]
 
         -- If the request appears to be submitting a form (has key-value pairs) give it the form-urlencoded Content-Type.
         -- The previous behavior was to always use the form-urlencoded Content-Type https://github.com/yesodweb/yesod/issues/1063
diff --git a/test/main.hs b/test/main.hs
--- a/test/main.hs
+++ b/test/main.hs
@@ -145,9 +145,11 @@
                 request $ do
                     setMethod "POST"
                     setUrl $ LiteAppRoute ["post"]
-                    addPostParam "foo" "foobarbaz"
+                    -- If value uses special characters,
+                    addPostParam "foo" "foo+bar%41<&baz"
                 statusIs 200
-                bodyEquals "foobarbaz"
+                -- They pass through the server correctly.
+                bodyEquals "foo+bar%41<&baz"
             yit "labels" $ do
                 get ("/form" :: Text)
                 statusIs 200
@@ -155,11 +157,13 @@
                 request $ do
                     setMethod "POST"
                     setUrl ("/form" :: Text)
-                    byLabel "Some Label" "12345"
+                    byLabel "Some Label" "foo+bar%41<&baz"
                     fileByLabel "Some File" "test/main.hs" "text/plain"
                     addToken
                 statusIs 200
-                bodyEquals "12345"
+                -- The '<' and '&' get encoded to HTML entities because
+                -- "/form" (unlike "/post") uses toHtml.
+                bodyEquals "foo+bar%41&lt;&amp;baz"
             yit "labels WForm" $ do
                 get ("/wform" :: Text)
                 statusIs 200
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.6.6.1
+version:            1.6.6.2
 license:            MIT
 license-file:       LICENSE
 author:             Nubis <nubis@woobiz.com.ar>
