diff --git a/System/IO/Cautious.hs b/System/IO/Cautious.hs
--- a/System/IO/Cautious.hs
+++ b/System/IO/Cautious.hs
@@ -11,11 +11,11 @@
 
 import Prelude hiding (writeFile)
 
-import System.Directory (renameFile)
+import System.Directory (canonicalizePath, renameFile)
 import System.FilePath (splitFileName)
 import System.IO (openTempFile)
 #ifdef _POSIX
-import Control.Monad (when)
+import Control.Monad (unless)
 import Data.Function (fix)
 import Data.List (genericDrop)
 import System.Posix.IO (closeFd, FdOption (SynchronousWrites), fdWrite, handleToFd, setFdOption)
@@ -27,7 +27,7 @@
 
 -- | Write the entire contents of a string to a file descriptor. Assumes blocking mode.
 writeAll :: Fd -> String -> IO ()
-writeAll fd = fix $ \me s -> when (not $ null s) $ do
+writeAll fd = fix $ \me s -> unless (null s) $ do
     count <- fdWrite fd s
     me $ genericDrop count s
 #else
@@ -41,7 +41,8 @@
 -- old version of the file.
 writeFileWithBackup :: IO () -> FilePath -> String -> IO ()
 writeFileWithBackup backup fp text = do
-    (tempFP, handle) <- uncurry openTempFile $ splitFileName fp
+    cfp <- canonicalizePath fp
+    (tempFP, handle) <- uncurry openTempFile $ splitFileName cfp
 #ifdef _POSIX
     fd <- handleToFd handle
     let writeSync = (setFdOption fd SynchronousWrites True >>) . writeAll fd
@@ -54,4 +55,4 @@
     hClose handle
 #endif
     backup
-    renameFile tempFP fp
+    renameFile tempFP cfp
diff --git a/Test.hs b/Test.hs
new file mode 100644
--- /dev/null
+++ b/Test.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE CPP #-}
+module Main where
+
+import System.IO.Cautious (writeFile)
+
+import Prelude hiding (writeFile)
+import Control.Monad (replicateM, zipWithM_, unless)
+import System.Directory (removeFile)
+import System.Environment (getArgs)
+#ifdef _POSIX
+import System.Posix.Files (createSymbolicLink, readSymbolicLink)
+#endif
+import System.Random (mkStdGen, randomRIO, setStdGen)
+
+-- Remember that because we are using zipWithM_ below, the lengths of testLengths and outputFilePaths need to be the same!
+testLengths :: [Int]
+testLengths = [ 0      -- Extreme value
+              , 1      -- Extreme value
+              , 65530  -- Normal value below split limit
+              , 65536  -- Split limit
+              , 128000 -- Normal value above split limit
+              ]
+
+outputFilePaths :: [FilePath]
+outputFilePaths = ["foo", "foo.txt", "./bar.txt", ".dotfile", "./.dot.dot"]
+
+defaultSeed :: Int
+defaultSeed = 1234
+
+stdTestCase :: Int -> FilePath -> IO ()
+stdTestCase dataLen outputFile = do
+    testData <- replicateM dataLen $ randomRIO ('\0', '\255')
+    writeFile outputFile testData
+    testData' <- readFile outputFile
+    unless (testData == testData') . fail $ "stdTestCase: failed with " ++ show dataLen ++ " " ++ show outputFile
+    removeFile outputFile
+
+#ifdef _POSIX
+symlinkTestCase :: IO ()
+symlinkTestCase = do
+    let linkTarget = "link-dest"
+        linkSrc    = "link"
+        testData   = "hi"
+    writeFile linkTarget ""
+    createSymbolicLink linkTarget linkSrc
+    writeFile linkSrc testData
+    newTarget <- readSymbolicLink linkSrc
+    testData' <- readFile linkTarget
+    unless (testData == testData') $ fail "symlinkTestCase failed: data read back not the same as data written out!"
+    unless (newTarget == linkTarget) $ fail "symlinkTestCase failed: symlink clobbered"
+    mapM_ removeFile [linkSrc, linkTarget]
+#endif
+
+main :: IO ()
+main = do
+    args <- getArgs
+    setStdGen . mkStdGen $ if null args then defaultSeed else read (head args)
+    zipWithM_ stdTestCase testLengths outputFilePaths
+#ifdef _POSIX
+    symlinkTestCase
+#else
+    putStrLn "Warning: POSIX tests not run! If you are on a POSIX platform, then to run them type 'runhaskell -D_POSIX Test.hs'"
+#endif
+    putStrLn "All cautious-file tests completed successfully!"
diff --git a/cautious-file.cabal b/cautious-file.cabal
--- a/cautious-file.cabal
+++ b/cautious-file.cabal
@@ -1,5 +1,5 @@
 name:                cautious-file
-version:             0.1.1
+version:             0.1.2
 Cabal-Version:	     >= 1.6
 synopsis:            Ways to write a file cautiously, to reduce the chances of problems such as data loss due to crashes or power failures
 description:         If the posix flag is enabled, posix-specific functions are used to reduce the chance of data loss further
@@ -13,6 +13,7 @@
 stability:	     experimental
 bug-reports:	     mailto:greenrd@greenrd.org
 tested-with:	     GHC == 6.10.3
+extra-source-files:      Test.hs
 
 source-repository head
   type:     darcs
