diff --git a/htest/Test/Ganeti/Confd/Utils.hs b/htest/Test/Ganeti/Confd/Utils.hs
index 1629f75605a3a801048b91ac4538a89cf53f7121..fea3dd9dfafdee1a99b074e4f43481e386c45a13 100644
--- a/htest/Test/Ganeti/Confd/Utils.hs
+++ b/htest/Test/Ganeti/Confd/Utils.hs
@@ -41,15 +41,11 @@ import qualified Ganeti.Confd.Utils as Confd.Utils
 import qualified Ganeti.Constants as C
 import qualified Ganeti.Hash as Hash
 
-instance Arbitrary Confd.ConfdRequestType where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Confd.ConfdRequestType)
 
-instance Arbitrary Confd.ConfdReqField where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Confd.ConfdReqField)
 
-instance Arbitrary Confd.ConfdReqQ where
-  arbitrary = Confd.ConfdReqQ <$> arbitrary <*> arbitrary <*>
-              arbitrary <*> arbitrary
+$(genArbitrary ''Confd.ConfdReqQ)
 
 instance Arbitrary Confd.ConfdQuery where
   arbitrary = oneof [ pure Confd.EmptyQuery
@@ -57,9 +53,7 @@ instance Arbitrary Confd.ConfdQuery where
                     , Confd.DictQuery <$> arbitrary
                     ]
 
-instance Arbitrary Confd.ConfdRequest where
-  arbitrary = Confd.ConfdRequest <$> arbitrary <*> arbitrary <*> arbitrary
-              <*> arbitrary
+$(genArbitrary ''Confd.ConfdRequest)
 
 -- | Test that signing messages and checking signatures is correct. It
 -- also tests, indirectly the serialisation of messages so we don't
diff --git a/htest/Test/Ganeti/HTools/Types.hs b/htest/Test/Ganeti/HTools/Types.hs
index 34759c50bf6a2640cc64435be213f72dda8e9298..aebcc4ceb1def675f5a68504eb6f1d7612db4319 100644
--- a/htest/Test/Ganeti/HTools/Types.hs
+++ b/htest/Test/Ganeti/HTools/Types.hs
@@ -56,17 +56,13 @@ allDiskTemplates = [minBound..maxBound]
 
 -- * Arbitrary instance
 
-instance Arbitrary Types.AllocPolicy where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Types.AllocPolicy)
 
-instance Arbitrary Types.DiskTemplate where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Types.DiskTemplate)
 
-instance Arbitrary Types.FailMode where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Types.FailMode)
 
-instance Arbitrary Types.EvacMode where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Types.EvacMode)
 
 instance Arbitrary a => Arbitrary (Types.OpResult a) where
   arbitrary = arbitrary >>= \c ->
diff --git a/htest/Test/Ganeti/Jobs.hs b/htest/Test/Ganeti/Jobs.hs
index b9504f7183fa74e29cfba5f93ce9c302a756f233..b6d954678c184da20c40586e1708dc702be43270 100644
--- a/htest/Test/Ganeti/Jobs.hs
+++ b/htest/Test/Ganeti/Jobs.hs
@@ -37,11 +37,9 @@ import qualified Ganeti.Jobs as Jobs
 
 -- * Arbitrary instances
 
-instance Arbitrary Jobs.OpStatus where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Jobs.OpStatus)
 
-instance Arbitrary Jobs.JobStatus where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Jobs.JobStatus)
 
 -- * Test cases
 
diff --git a/htest/Test/Ganeti/Luxi.hs b/htest/Test/Ganeti/Luxi.hs
index e36889fe7388115a6779839828f872b17898244d..dea4d5f103e2749370b36ea32a6c547597aba96b 100644
--- a/htest/Test/Ganeti/Luxi.hs
+++ b/htest/Test/Ganeti/Luxi.hs
@@ -48,11 +48,9 @@ import qualified Ganeti.Luxi as Luxi
 
 -- * Luxi tests
 
-instance Arbitrary Luxi.TagObject where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Luxi.TagObject)
 
-instance Arbitrary Luxi.LuxiReq where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Luxi.LuxiReq)
 
 instance Arbitrary Luxi.LuxiOp where
   arbitrary = do
diff --git a/htest/Test/Ganeti/Objects.hs b/htest/Test/Ganeti/Objects.hs
index 0883e30a45560c1a9762a055bdaff9ff6e358e21..4d94fdb4fbde315c39dff8476256f9408291bd50 100644
--- a/htest/Test/Ganeti/Objects.hs
+++ b/htest/Test/Ganeti/Objects.hs
@@ -45,11 +45,9 @@ import Ganeti.JSON
 
 -- * Arbitrary instances
 
-instance Arbitrary Hypervisor where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Hypervisor)
 
-instance Arbitrary PartialNDParams where
-  arbitrary = PartialNDParams <$> arbitrary <*> arbitrary
+$(genArbitrary ''PartialNDParams)
 
 instance Arbitrary Node where
   arbitrary = Node <$> getFQDN <*> getFQDN <*> getFQDN
@@ -58,14 +56,11 @@ instance Arbitrary Node where
               <*> arbitrary <*> arbitrary <*> getFQDN <*> arbitrary
               <*> (Set.fromList <$> genTags)
 
-instance Arbitrary FileDriver where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''FileDriver)
 
-instance Arbitrary BlockDriver where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''BlockDriver)
 
-instance Arbitrary DiskMode where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''DiskMode)
 
 instance Arbitrary DiskLogicalId where
   arbitrary = oneof [ LIDPlain <$> arbitrary <*> arbitrary
@@ -83,26 +78,19 @@ instance Arbitrary Disk where
   arbitrary = Disk <$> arbitrary <*> (pure []) <*> arbitrary
                    <*> arbitrary <*> arbitrary
 
-instance Arbitrary PartialBeParams where
-  -- FIXME: we should generate proper values, >=0, etc., but this is
-  -- hard for partial ones, where all must be wrapped in a 'Maybe'
-  arbitrary = PartialBeParams <$> arbitrary <*> arbitrary
-                              <*> arbitrary <*> arbitrary
+-- FIXME: we should generate proper values, >=0, etc., but this is
+-- hard for partial ones, where all must be wrapped in a 'Maybe'
+$(genArbitrary ''PartialBeParams)
 
-instance Arbitrary DiskTemplate where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''DiskTemplate)
 
-instance Arbitrary AdminState where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''AdminState)
 
-instance Arbitrary NICMode where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''NICMode)
 
-instance Arbitrary PartialNicParams where
-  arbitrary = PartialNicParams <$> arbitrary <*> arbitrary
+$(genArbitrary ''PartialNicParams)
 
-instance Arbitrary PartialNic where
-  arbitrary = PartialNic <$> arbitrary <*> arbitrary <*> arbitrary
+$(genArbitrary ''PartialNic)
 
 instance Arbitrary Instance where
   arbitrary =
diff --git a/htest/Test/Ganeti/OpCodes.hs b/htest/Test/Ganeti/OpCodes.hs
index 39396cb86ce1ad4306adae4b318939f14ddee700..93abaf18367e4274716742af42e0a626e9b2cf1f 100644
--- a/htest/Test/Ganeti/OpCodes.hs
+++ b/htest/Test/Ganeti/OpCodes.hs
@@ -46,8 +46,7 @@ import qualified Ganeti.OpCodes as OpCodes
 
 -- * Arbitrary instances
 
-instance Arbitrary OpCodes.ReplaceDisksMode where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''OpCodes.ReplaceDisksMode)
 
 instance Arbitrary OpCodes.DiskIndex where
   arbitrary = choose (0, C.maxDisks - 1) >>= OpCodes.mkDiskIndex
diff --git a/htest/Test/Ganeti/Query/Language.hs b/htest/Test/Ganeti/Query/Language.hs
index 15ff94ebb098a4c325b98e8319a412062708194e..c38fe5ee08ff3c1013a8f79e8d743c6031af6840 100644
--- a/htest/Test/Ganeti/Query/Language.hs
+++ b/htest/Test/Ganeti/Query/Language.hs
@@ -72,8 +72,7 @@ genFilter' n = do
         n'' = max n' 2 -- but we don't want empty or 1-element lists,
                        -- so use this for and/or filter list length
 
-instance Arbitrary Qlang.ItemType where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Qlang.ItemType)
 
 instance Arbitrary Qlang.FilterRegex where
   arbitrary = getName >>= Qlang.mkRegex -- a name should be a good regex
@@ -81,8 +80,7 @@ instance Arbitrary Qlang.FilterRegex where
 -- | Tests that serialisation/deserialisation of filters is
 -- idempotent.
 prop_Serialisation :: Property
-prop_Serialisation =
-  forAll genFilter testSerialisation
+prop_Serialisation = forAll genFilter testSerialisation
 
 prop_FilterRegex_instances :: Qlang.FilterRegex -> Property
 prop_FilterRegex_instances rex =
diff --git a/htest/Test/Ganeti/Ssconf.hs b/htest/Test/Ganeti/Ssconf.hs
index 0b8695026ed3b2c8d4c8528aa8bfae308d7f83b4..98f66080a427db4db9145b4a4e520791bf867a35 100644
--- a/htest/Test/Ganeti/Ssconf.hs
+++ b/htest/Test/Ganeti/Ssconf.hs
@@ -38,8 +38,7 @@ import qualified Ganeti.Ssconf as Ssconf
 
 -- * Ssconf tests
 
-instance Arbitrary Ssconf.SSKey where
-  arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Ssconf.SSKey)
 
 prop_filename :: Ssconf.SSKey -> Property
 prop_filename key =
diff --git a/htest/Test/Ganeti/TestHTools.hs b/htest/Test/Ganeti/TestHTools.hs
index 07f1cae7e503899cef5b920701ef3626e56e71b0..8dbaceac0a1076d531434b842bd548fc58af1d91 100644
--- a/htest/Test/Ganeti/TestHTools.hs
+++ b/htest/Test/Ganeti/TestHTools.hs
@@ -28,10 +28,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
 module Test.Ganeti.TestHTools where
 
-import Test.QuickCheck
-
 import qualified Data.Map as Map
 
+import Test.Ganeti.TestHelper
 import Test.Ganeti.TestCommon
 
 import qualified Ganeti.Constants as C
@@ -120,5 +119,4 @@ setInstanceSmallerThanNode node inst =
 
 -- * Arbitrary instances
 
-instance Arbitrary Types.InstanceStatus where
-    arbitrary = elements [minBound..maxBound]
+$(genArbitrary ''Types.InstanceStatus)