--- /dev/null
+++ b/tests/DataFamilies/Instances.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE FlexibleInstances, TemplateHaskell, TypeFamilies #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module DataFamilies.Instances where
+
+import Control.Applicative
+import Data.Aeson.TH
+import DataFamilies.Types
+import Test.QuickCheck (Arbitrary(..), elements, oneof)
+import Prelude
+
+instance (Arbitrary a) => Arbitrary (Approx a) where
+    arbitrary = Approx <$> arbitrary
+
+instance Arbitrary (Nullary Int) where
+    arbitrary = elements [C1, C2, C3]
+
+instance Arbitrary a => Arbitrary (SomeType c () a) where
+    arbitrary = oneof [ pure Nullary
+                      , Unary   <$> arbitrary
+                      , Product <$> arbitrary <*> arbitrary <*> arbitrary
+                      , Record  <$> arbitrary <*> arbitrary <*> arbitrary
+                      ]
+
+deriveJSON defaultOptions 'C1
+deriveJSON defaultOptions 'Nullary
+deriveJSON defaultOptions 'Approx
--- /dev/null
+++ b/tests/DataFamilies/Properties.hs
@@ -0,0 +1,72 @@
+module DataFamilies.Properties (tests) where
+
+import DataFamilies.Encoders
+import DataFamilies.Instances ()
+
+import Properties hiding (tests)
+
+import Test.Framework (Test, testGroup)
+import Test.Framework.Providers.QuickCheck2 (testProperty)
+
+--------------------------------------------------------------------------------
+
+tests :: Test
+tests = testGroup "data families" [
+  testGroup "template-haskell" [
+      testGroup "toJSON" [
+        testGroup "Nullary" [
+            testProperty "string" (isString . thNullaryToJSONString)
+          , testProperty "2ElemArray" (is2ElemArray . thNullaryToJSON2ElemArray)
+          , testProperty "TaggedObject" (isTaggedObjectValue . thNullaryToJSONTaggedObject)
+          , testProperty "ObjectWithSingleField" (isObjectWithSingleField . thNullaryToJSONObjectWithSingleField)
+
+          , testGroup "roundTrip" [
+              testProperty "string" (toParseJSON thNullaryParseJSONString thNullaryToJSONString)
+            , testProperty "2ElemArray" (toParseJSON thNullaryParseJSON2ElemArray thNullaryToJSON2ElemArray)
+            , testProperty "TaggedObject" (toParseJSON thNullaryParseJSONTaggedObject thNullaryToJSONTaggedObject)
+            , testProperty "ObjectWithSingleField" (toParseJSON thNullaryParseJSONObjectWithSingleField thNullaryToJSONObjectWithSingleField)
+            ]
+        ]
+      , testGroup "SomeType" [
+          testProperty "2ElemArray" (is2ElemArray . thSomeTypeToJSON2ElemArray)
+        , testProperty "TaggedObject" (isTaggedObject . thSomeTypeToJSONTaggedObject)
+        , testProperty "ObjectWithSingleField" (isObjectWithSingleField . thSomeTypeToJSONObjectWithSingleField)
+        , testGroup "roundTrip" [
+            testProperty "2ElemArray" (toParseJSON thSomeTypeParseJSON2ElemArray thSomeTypeToJSON2ElemArray)
+          , testProperty "TaggedObject" (toParseJSON thSomeTypeParseJSONTaggedObject thSomeTypeToJSONTaggedObject)
+          , testProperty "ObjectWithSingleField" (toParseJSON thSomeTypeParseJSONObjectWithSingleField thSomeTypeToJSONObjectWithSingleField)
+          ]
+       , testGroup "Approx" [
+            testProperty "string"                (isString                . thApproxToJSONUnwrap)
+          , testProperty "ObjectWithSingleField" (isObjectWithSingleField . thApproxToJSONDefault)
+          , testGroup "roundTrip" [
+                testProperty "string"                (toParseJSON thApproxParseJSONUnwrap  thApproxToJSONUnwrap)
+              , testProperty "ObjectWithSingleField" (toParseJSON thApproxParseJSONDefault thApproxToJSONDefault)
+            ]
+          ]
+        ]
+      ]
+    , testGroup "toEncoding" [
+        testProperty "NullaryString" $
+        thNullaryToJSONString `sameAs` thNullaryToEncodingString
+      , testProperty "Nullary2ElemArray" $
+        thNullaryToJSON2ElemArray `sameAs` thNullaryToEncoding2ElemArray
+      , testProperty "NullaryTaggedObject" $
+        thNullaryToJSONTaggedObject `sameAs` thNullaryToEncodingTaggedObject
+      , testProperty "NullaryObjectWithSingleField" $
+        thNullaryToJSONObjectWithSingleField `sameAs`
+        thNullaryToEncodingObjectWithSingleField
+      , testProperty "ApproxUnwrap" $
+        thApproxToJSONUnwrap `sameAs` thApproxToEncodingUnwrap
+      , testProperty "ApproxDefault" $
+        thApproxToJSONDefault `sameAs` thApproxToEncodingDefault
+      , testProperty "SomeType2ElemArray" $
+        thSomeTypeToJSON2ElemArray `sameAsV` thSomeTypeToEncoding2ElemArray
+      , testProperty "SomeTypeTaggedObject" $
+        thSomeTypeToJSONTaggedObject `sameAsV` thSomeTypeToEncodingTaggedObject
+      , testProperty "SomeTypeObjectWithSingleField" $
+        thSomeTypeToJSONObjectWithSingleField `sameAsV`
+        thSomeTypeToEncodingObjectWithSingleField
+      ]
+    ]
+  ]
