diff --git a/example-explicit.hs b/example-explicit.hs
new file mode 100644
--- /dev/null
+++ b/example-explicit.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE TemplateHaskell #-}
+module Main where
+
+import Test.Tasty
+import Test.Tasty.TH
+import Test.Tasty.QuickCheck
+import Test.Tasty.HUnit
+
+main :: IO ()
+main = $(defaultMainGeneratorFor "explicit" ["prop_length_append", "case_length_1", "test_plus"])
+
+prop_length_append :: [Int] -> [Int] -> Bool
+prop_length_append as bs = length (as ++ bs) == length as + length bs
+
+case_length_1 :: Assertion
+case_length_1 = 1 @=? length [()]
+
+case_add :: Assertion
+case_add = 7 @=? (3 + 4)
+
+test_plus :: [TestTree]
+test_plus =
+  [ $(testGroupGeneratorFor "case_add" ["case_add"])
+    -- ...
+  ]
diff --git a/example-literate.lhs b/example-literate.lhs
new file mode 100644
--- /dev/null
+++ b/example-literate.lhs
@@ -0,0 +1,36 @@
+This is an example of using tasty-th with literate haskell files.
+First, we need to import the library and enable template haskell:
+
+> {-# LANGUAGE TemplateHaskell #-}
+> import Test.Tasty
+> import Test.Tasty.TH
+> import Test.Tasty.QuickCheck
+> import Test.Tasty.HUnit
+
+Now, we can write some quickcheck properties:
+
+> prop_length_append :: [Int] -> [Int] -> Bool
+> prop_length_append as bs = length (as ++ bs) == length as + length bs
+
+Or write a HUnit test case:
+
+> case_length_1 :: Assertion
+> case_length_1 = 1 @=? length [()]
+
+Properties in comments are not run:
+
+prop_comment :: Assertion
+prop_comment = assertFailure "property in comment should not be run"
+
+We can also create test trees:
+
+> test_plus :: [TestTree]
+> test_plus =
+>   [ testCase "3 + 4" (7 @=? (3 + 4))
+>     --  ...
+>   ]
+
+We only need a main now that collects all our tests:
+
+> main :: IO ()
+> main = $(defaultMainGenerator)
diff --git a/example.hs b/example.hs
new file mode 100644
--- /dev/null
+++ b/example.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE TemplateHaskell #-}
+module Main where
+
+import Test.Tasty
+import Test.Tasty.TH
+import Test.Tasty.QuickCheck
+import Test.Tasty.HUnit
+
+main :: IO ()
+main = $(defaultMainGenerator)
+
+{-
+Properties in comments are not run:
+
+prop_comment :: Assertion
+prop_comment = assertFailure "property in comment should not be run"
+-}
+
+prop_length_append :: [Int] -> [Int] -> Bool
+prop_length_append as bs = length (as ++ bs) == length as + length bs
+
+case_length_1 :: Assertion
+case_length_1 = 1 @=? length [()]
+
+test_plus :: [TestTree]
+test_plus =
+  [ testCase "3 + 4" (7 @=? (3 + 4))
+    -- ...
+  ]
diff --git a/src/Test/Tasty/TH.hs b/src/Test/Tasty/TH.hs
--- a/src/Test/Tasty/TH.hs
+++ b/src/Test/Tasty/TH.hs
@@ -33,8 +33,11 @@
 import Language.Haskell.Exts.Parser (ParseResult(..), defaultParseMode, parseFilename)
 import qualified Language.Haskell.Exts.Syntax as S
 import Language.Haskell.TH
-import Data.List
 import Data.Maybe
+import Data.Data (gmapQ, Data)
+import Data.Typeable (cast)
+import Data.List (nub, isPrefixOf, find)
+import qualified Data.Foldable as F
 
 import Test.Tasty
 import Prelude
@@ -94,10 +97,25 @@
   parsed file = case parseFileContentsWithMode (defaultParseMode { parseFilename = filePath }) file of
     ParseOk parsedModule -> Just (declarations parsedModule)
     ParseFailed _ _ -> Nothing
-  declarations (S.Module _ _ _ _ decls) = mapMaybe testFunName decls
+  declarations (S.Module _ _ _ _ decls) = concatMap testFunName decls
   declarations _ = []
-  testFunName (S.PatBind _ (S.PVar _ (S.Ident _ n)) _ _) = Just n
-  testFunName _ = Nothing
+  testFunName (S.PatBind _ pat _ _) = patternVariables pat
+  testFunName (S.FunBind _ clauses) = nub (map clauseName clauses)
+  testFunName _ = []
+  clauseName (S.Match _ name _ _ _) = nameString name
+  clauseName (S.InfixMatch _ _ name _ _ _) = nameString name
+
+-- | Convert a 'Name' to a 'String'
+nameString :: S.Name l -> String
+nameString (S.Ident _ n) = n
+nameString (S.Symbol _ n) = n
+
+-- | Find all variables that are bound in the given pattern.
+patternVariables :: Data l => S.Pat l -> [String]
+patternVariables = go
+ where
+  go (S.PVar _ name) = [nameString name]
+  go pat = concat $ gmapQ (F.foldMap go . cast) pat
 
 -- | Extract the name of the current module.
 locationModule :: ExpQ
diff --git a/tasty-th.cabal b/tasty-th.cabal
--- a/tasty-th.cabal
+++ b/tasty-th.cabal
@@ -1,6 +1,6 @@
 name: tasty-th
-version: 0.1.6
-cabal-version: >= 1.6
+version: 0.1.7
+cabal-version: >= 1.8
 build-type: Simple
 license: BSD3
 license-file: BSD3.txt
@@ -11,12 +11,28 @@
 
 category: Testing
 author: Oscar Finnsson & Emil Nordling & Benno Fünfstück
+extra-source-files:
+  example.hs
+  example-explicit.hs
+  example-literate.lhs
 
 library
   exposed-modules: Test.Tasty.TH
   build-depends: base >= 4 && < 5, haskell-src-exts >= 1.18.0, tasty, template-haskell
   hs-source-dirs: src
+  ghc-options: -Wall
   other-extensions: TemplateHaskell
+
+test-suite tasty-th-tests
+  hs-source-dirs: tests
+  main-is: Main.hs
+  build-depends:
+    base >= 4 && < 5,
+    tasty-hunit,
+    tasty-th
+  ghc-options: -Wall
+  default-language:    Haskell2010
+  type: exitcode-stdio-1.0
 
 source-repository head
   type:     git
diff --git a/tests/Main.hs b/tests/Main.hs
new file mode 100644
--- /dev/null
+++ b/tests/Main.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE TemplateHaskell #-}
+import Test.Tasty.TH
+import Test.Tasty.HUnit
+import Data.List (sort)
+
+main :: IO ()
+main = $(defaultMainGenerator)
+
+case_example_test_functions :: Assertion
+case_example_test_functions = do
+  functions <- extractTestFunctions "example.hs"
+  let expected = [ "prop_length_append", "case_length_1", "test_plus" ]
+  sort expected @=? sort functions
+
+case_example_explicit_test_functions :: Assertion
+case_example_explicit_test_functions = do
+  functions <- extractTestFunctions "example-explicit.hs"
+  let expected = [ "case_add", "prop_length_append", "case_length_1", "test_plus" ]
+  sort expected @=? sort functions
+
+case_example_literate_test_functions :: Assertion
+case_example_literate_test_functions = do
+  functions <- extractTestFunctions "example-literate.lhs"
+  let expected = [ "prop_length_append", "case_length_1", "test_plus" ]
+  sort expected @=? sort functions
