diff --git a/quickcheck-text.cabal b/quickcheck-text.cabal
--- a/quickcheck-text.cabal
+++ b/quickcheck-text.cabal
@@ -1,5 +1,5 @@
 name:                quickcheck-text
-version:             0.1.0.1
+version:             0.1.1.0
 synopsis:            Alternative arbitrary instance for Text
 description:         The usual Arbitrary instance for Text
                      (in
@@ -13,7 +13,7 @@
 license-file:        LICENSE
 author:              Sharif Olorin
 maintainer:          sio@tesser.org
-copyright:           2015 Sharif Olorin
+copyright:           2015-2016 Sharif Olorin and others
 category:            Text
 build-type:          Simple
 cabal-version:       >=1.10
diff --git a/src/Data/Text/Arbitrary.hs b/src/Data/Text/Arbitrary.hs
--- a/src/Data/Text/Arbitrary.hs
+++ b/src/Data/Text/Arbitrary.hs
@@ -1,3 +1,5 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
 module Data.Text.Arbitrary(
   Text()
 ) where
@@ -9,3 +11,4 @@
 
 instance Arbitrary Text where
   arbitrary = genValidUtf8
+  shrink = shrinkValidUtf8
diff --git a/src/Test/QuickCheck/Utf8.hs b/src/Test/QuickCheck/Utf8.hs
--- a/src/Test/QuickCheck/Utf8.hs
+++ b/src/Test/QuickCheck/Utf8.hs
@@ -1,8 +1,16 @@
 module Test.QuickCheck.Utf8(
     genValidUtf8
+  , shrinkValidUtf8
+
   , utf8BS
+  , shrinkUtf8BS
+
   , genValidUtf81
+  , shrinkValidUtf81
+
   , utf8BS1
+  , shrinkUtf8BS1
+
     -- * Generators for single characters
   , oneByte
   , twoByte
@@ -12,12 +20,10 @@
 import           Control.Monad
 
 import           Data.Binary.Builder
-import           Data.Binary.Get
 
 import           Data.ByteString     (ByteString)
 import qualified Data.ByteString     as BS
 import qualified Data.ByteString.Lazy     as BL
-import           Data.Char
 import           Data.Text           (Text)
 import qualified Data.Text           as T
 import           Data.Text.Encoding
@@ -32,20 +38,41 @@
 genValidUtf8 = fmap decodeUtf8 utf8BS
 
 -- |
+-- Shrink a possible-empty valid UTF-8 'Text' value.
+shrinkValidUtf8 :: Text -> [Text]
+shrinkValidUtf8 = fmap T.pack . shrink . T.unpack
+
+-- |
 -- Generate a possibly-empty sequence of bytes which represent a valid
 -- UTF-8 code point.
 utf8BS :: Gen ByteString
-utf8BS = fmap BS.concat $ elements symbolTypes  >>= listOf
+utf8BS = fmap BS.concat . listOf $ oneof symbolTypes
 
 -- |
+-- Shrink a possible-empty sequence of bytes which represent a valid
+-- UTF-8 code point.
+shrinkUtf8BS :: ByteString -> [ByteString]
+shrinkUtf8BS = fmap encodeUtf8 . shrinkValidUtf8 . decodeUtf8
+
+-- |
 -- Like 'genValidUtf8', but does not allow empty 'Text' values.
 genValidUtf81 :: Gen Text
 genValidUtf81 = fmap decodeUtf8 utf8BS1
 
 -- |
+-- List 'genValidUtf8', bute does not allow empty 'Text' values.
+shrinkValidUtf81 :: Text -> [Text]
+shrinkValidUtf81 = filter (not . T.null) . shrinkValidUtf8
+
+-- |
 -- Like 'utf8BS', but does not allow empty 'ByteString's.
 utf8BS1 :: Gen ByteString
-utf8BS1 = fmap BS.concat $ elements symbolTypes  >>= listOf1
+utf8BS1 = fmap BS.concat . listOf1 $ oneof symbolTypes
+
+-- |
+-- Like 'shrinkUtf8BS', but does not allow empty 'ByteString's.
+shrinkUtf8BS1 :: ByteString -> [ByteString]
+shrinkUtf8BS1 = filter (not . BS.null) . shrinkUtf8BS
 
 symbolTypes :: [Gen ByteString]
 symbolTypes = [ oneByte
diff --git a/test/properties.hs b/test/properties.hs
--- a/test/properties.hs
+++ b/test/properties.hs
@@ -6,6 +6,7 @@
 
 import           Data.Bits
 import qualified Data.ByteString      as BS
+import qualified Data.Text as T
 import           Data.Text.Encoding
 
 import           System.Exit
@@ -14,8 +15,9 @@
 import           Test.QuickCheck.Utf8
 
 prop_decodes_without_exception :: Property
-prop_decodes_without_exception = forAll utf8BS $ \bs ->
-  decodeUtf8 bs === decodeUtf8 bs
+prop_decodes_without_exception = forAllAndShrinks utf8BS shrinkUtf8BS $ \bs ->
+  let t = decodeUtf8 bs in
+  (T.length t >=) 0 === True
 
 prop_oneByte_lsb :: Property
 prop_oneByte_lsb = forAll oneByte $ \bs ->
@@ -37,9 +39,21 @@
   let s = sum $ fmap fromIntegral $ BS.unpack bs
   in (s >= 480 && s <= 16777071)
 
-prop_validUtf81 :: Property
-prop_validUtf81 = forAll utf8BS1 $ \bs ->
+prop_validUtf81_length :: Property
+prop_validUtf81_length = forAllAndShrinks utf8BS1 shrinkUtf8BS1 $ \bs ->
   BS.length bs >= 1
+
+prop_validUtf81_valid :: Property
+prop_validUtf81_valid = forAllAndShrinks utf8BS1 shrinkUtf8BS1 $ \bs ->
+  let t = decodeUtf8 bs in
+  (T.length t >= 1) === True
+
+-- |
+-- Ensure that the shrink applied to the generated value also satisfies the property.
+forAllAndShrinks :: (Show a, Testable prop) => Gen a -> (a -> [a]) -> (a -> prop) -> Property
+forAllAndShrinks gen shr prop =
+  forAll (gen >>= \x -> return (x : shr x)) $ \xs ->
+    conjoin $ fmap prop xs
 
 return []
 props :: IO Bool
