On Fri, Jun 30, 2006 at 02:52:54PM -0700, Ashley Yakeley wrote: > I'm currently considering possible unit tests, since right now I rely > solely on code inspection. One possibility would be to simply time the > function to show that it didn't have time to do anything really long at > least. But that's not very satisfactory, since that is strictly a > performance test, not a functionality test. It's like any other Haskell > function: I want to implement it as efficiently as possible, but I don't > guarantee any particular performance. > > Ideally I would have tests like these: > > * Verify noop does nothing with the file system. > > * Verify noop does no networking activity. > > * Verify noop makes no use of stdin/stdout/stderr. > > * Verify noop does not modify any external IORefs. > > etc.
I think the best approach for this kind of verification would be to break the IO monad up into classes, and then write a polymorphic function, as this would allow you to verify that your noop function behaves as expected, class Monad m => FileWriteMonad m where writeFile :: FilePath -> String -> m () ... class Monad m => FileReadMonad m where readFile :: FilePath -> m String openFileRead :: FilePath -> M Handle -- would be more general with AT ... class Monad m => NetworkMonad m where withSocketsDo :: m a -> m a ... class Monad m => RefMonad m where -- note, this could be more general with AT newIORef :: a -> m (IORef a) And then we could catch bugs in the noop function simply by looking at its type. e.g. when we saw noop :: FileReadMonad m => m () we'd have a strong suspicion that noop is actually trying to read from the filesystem, but if the type is just noop :: m () we'd have a high degree of confidence (assuming no unsafePerformIO is going on) that noop is bug-free. Unfortunately, even this isn't sufficient to show that noop will never return bottom... -- David Roundy _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
