diff --git a/chuchu.cabal b/chuchu.cabal
--- a/chuchu.cabal
+++ b/chuchu.cabal
@@ -1,5 +1,5 @@
 name: chuchu
-version: 0.3
+version: 0.4.1
 cabal-version: >= 1.8
 build-type: Simple
 license: OtherLicense
@@ -22,7 +22,10 @@
   tests/data/calculator.feature,
   tests/data/prefix.feature,
   tests/data/multiple_scenarios.feature,
-  tests/data/background_and_multiple_scenarios.feature
+  tests/data/background_and_multiple_scenarios.feature,
+  tests/data/multiple_features1.feature,
+  tests/data/multiple_features2.feature,
+  tests/data/should_fail.feature
 
 source-repository head
   type:     git
@@ -36,16 +39,25 @@
     Test.Chuchu.Parser
   other-modules:
     Test.Chuchu.Parsec,
-    Test.Chuchu.Email
+    Test.Chuchu.Email,
+    Test.Chuchu.OutputPrinter
   build-depends:
-    base >= 4 && < 5,
-    text >= 0.11 && < 0.12,
-    transformers >= 0.3 && < 0.4,
-    parsec >= 3.1 && < 3.2,
-    cmdargs >= 0.9 && < 0.10,
-    ansi-wl-pprint == 0.6.*,
-    abacate >= 0.0 && < 0.1
-  extensions: DeriveDataTypeable, GADTs, GeneralizedNewtypeDeriving, OverloadedStrings
+    base               >= 4    && < 5,
+    text               >= 0.11 && < 0.12,
+    transformers       >= 0.3  && < 0.4,
+    parsec             >= 3.1  && < 3.2,
+    cmdargs            >= 0.9  && < 0.10,
+    ansi-wl-pprint     == 0.6.*,
+    abacate            >= 0.0  && < 0.1,
+    monad-control      >= 0.3  && < 0.4,
+    lifted-base        >= 0.2  && < 0.3
+  extensions:
+    DeriveDataTypeable
+    FlexibleContexts
+    GADTs
+    GeneralizedNewtypeDeriving
+    OverloadedStrings
+    ScopedTypeVariables
   ghc-options: -Wall
 
 Test-Suite environment
@@ -54,7 +66,7 @@
   hs-source-dirs: tests
   build-depends:
     base >= 4 && < 5,
-    unix >= 2.5 && < 2.6,
+    unix >= 2.5,
     text,
     chuchu,
     HUnit >= 1.2 && < 1.3
@@ -100,6 +112,30 @@
 Test-Suite background_and_multiple_scenarios
   type: exitcode-stdio-1.0
   main-is: background_and_multiple_scenarios.hs
+  hs-source-dirs: tests
+  build-depends:
+    base >= 4 && < 5,
+    transformers >= 0.3 && < 0.4,
+    chuchu,
+    HUnit >= 1.2 && < 1.3
+  extensions: OverloadedStrings
+  ghc-options: -Wall
+
+Test-Suite multiple_features
+  type: exitcode-stdio-1.0
+  main-is: multiple_features.hs
+  hs-source-dirs: tests
+  build-depends:
+    base >= 4 && < 5,
+    transformers >= 0.3 && < 0.4,
+    chuchu,
+    HUnit >= 1.2 && < 1.3
+  extensions: OverloadedStrings
+  ghc-options: -Wall
+
+Test-Suite should_fail
+  type: exitcode-stdio-1.0
+  main-is: should_fail.hs
   hs-source-dirs: tests
   build-depends:
     base >= 4 && < 5,
diff --git a/src/Test/Chuchu.hs b/src/Test/Chuchu.hs
--- a/src/Test/Chuchu.hs
+++ b/src/Test/Chuchu.hs
@@ -77,56 +77,49 @@
   (chuchuMain, module Test.Chuchu.Types, module Test.Chuchu.Parser)
   where
 
--- base
-import Control.Applicative
-import Control.Monad
-import System.Environment
-import System.Exit
-import System.IO
-import qualified Data.IORef as I
-
--- text
-import qualified Data.Text as T
-
--- transformers
-import Control.Monad.IO.Class
-import Control.Monad.Trans.Class
-import Control.Monad.Trans.Reader
-
--- parsec
-import Text.Parsec
-import Text.Parsec.Text
-
--- cmdargs
-import System.Console.CmdArgs
-
--- ansi-wl-pprint
-import qualified Text.PrettyPrint.ANSI.Leijen as D
-
--- abacate
+import Control.Applicative ((<$>), Applicative((<*>)))
+import Control.Monad (unless)
+import Control.Monad.IO.Class (MonadIO(liftIO))
+import Control.Monad.Trans.Class (lift)
+import Control.Monad.Trans.Control (MonadBaseControl)
+import Control.Monad.Trans.Reader (ReaderT(..), ask)
+import Data.Either (partitionEithers)
 import Language.Abacate hiding (StepKeyword (..))
+import System.Console.CmdArgs
+import System.Environment (getProgName)
+import System.Exit (exitFailure, exitWith, ExitCode(ExitFailure))
+import qualified Control.Exception.Lifted as E
+import qualified Data.IORef as I
+import qualified Text.Parsec as P
 
--- chuchu
 import Test.Chuchu.Types
 import Test.Chuchu.Parser
+import Test.Chuchu.OutputPrinter
 
 
 ----------------------------------------------------------------------
 
 
--- | The main function for the test file.  It expects the @.feature@ file as the
--- first parameter on the command line.  If you want to use it inside a library,
--- consider using 'withArgs'.
-chuchuMain :: (MonadIO m, Applicative m) => Chuchu m -> (m () -> IO ()) -> IO ()
-chuchuMain cc runMIO
-  = do
-    path <- getPath
-    parsed <- parseFile path
-    case parsed of
-      Right abacate -> do
-        ret <- processAbacate cc runMIO abacate
-        unless ret exitFailure
-      Left e -> error $ "Could not parse " ++ path ++ ": " ++ show e
+-- | The main function for the test file. It expects one or more
+-- @.feature@ file as parameters on the command line. If you want to
+-- use it inside a library, consider using 'withArgs'.
+chuchuMain :: (MonadBaseControl IO m, MonadIO m, Applicative m) =>
+              Chuchu m -> (m () -> IO ()) -> IO ()
+chuchuMain stepDefinitions runMIO = do
+  listOfPaths <- getPaths
+  parsedFiles <- mapM parseFile listOfPaths
+  let result = partitionEithers parsedFiles
+  case result of
+    -- no error in parsing, execute all files
+    ([], filesToExecute) -> do
+      rets <- concat <$> mapM (processAbacate stepDefinitions runMIO) filesToExecute
+      let n = length $ filter not rets
+      unless (n == 0) $ exitWith (ExitFailure (min 255 n)) -- the size of a Unix error code is 1 byte
+    -- there were errors, print them and execute nothing
+    (filesWithError, _)  -> do
+      warn "Could not parse the following files: "
+      mapM_ (warn . flip (++) "\n" . show) filesWithError
+      exitFailure
 
 
 ----------------------------------------------------------------------
@@ -153,23 +146,19 @@
 
 -- | Monad used when executing a feature's scenario.  'ReaderT'
 -- is used to carry along the step parser.
-type Execution m a = ReaderT (Parser (m ())) m a
-
-
--- | Print a 'D.Doc' describing what we're currently processing.
-putDoc :: (MonadIO m, Applicative m) => D.Doc -> m ()
-putDoc = liftIO . D.putDoc . (D.<> D.linebreak)
+type Execution m a = ReaderT (ParseStep m) m a
 
 
--- | Same as 'D.text' but using 'T.Text'.
-t2d :: T.Text -> D.Doc
-t2d = D.text . T.unpack
+-- | A function that parses a step and, if successful, returns
+-- the corresponding action to be executed.
+type ParseStep m = Step -> Either P.ParseError (m ())
 
 
 -- | Run the 'Execution' monad.
 runExecution :: (MonadIO m, Applicative m) =>
                 Chuchu m -> (m () -> IO ()) -> Execution m () -> IO ()
-runExecution cc runMIO act = runMIO $ runReaderT act $ runChuchu cc
+runExecution stepDefinitions runMIO act = runMIO $ runReaderT act parseStep
+  where parseStep = P.parse (runChuchu stepDefinitions) "Step definitions" . stBody
 
 
 ----------------------------------------------------------------------
@@ -178,137 +167,99 @@
 -- | Process a whole Abacate file, that is, a whole feature.
 -- Runs each background+scenario combination on a different
 -- instance of the 'Execution' monad.
-processAbacate :: (MonadIO m, Applicative m) =>
+processAbacate :: (MonadBaseControl IO m, MonadIO m, Applicative m) =>
                   Chuchu m
                -> (m () -> IO ())
                -> Abacate
-               -> IO Bool
-processAbacate cc runMIO feature = do
+               -> IO [Bool]
+processAbacate stepDefinitions runMIO feature = do
   -- Print feature description.
   putDoc $ describeAbacate feature
 
   -- Execute features.
   let plans = createExecutionPlans feature
-  retVar <- liftIO $ I.newIORef True
-  let checkRet ret = unless ret $ liftIO $ I.writeIORef retVar False
-  mapM_ (runExecution cc runMIO . (>>= checkRet) . processExecutionPlan) plans
-  liftIO $ I.readIORef retVar
+  retVar <- liftIO $ I.newIORef []
+  let addRet ret = liftIO $ I.modifyIORef retVar (ret:)
+  mapM_ (runExecution stepDefinitions runMIO . (>>= addRet) . processExecutionPlan) plans
+  reverse <$> liftIO (I.readIORef retVar)
 
 
 -- | Process a single execution plan, a combination of
 -- background+scenario, inside the 'Execution' monad.
-processExecutionPlan :: (MonadIO m, Applicative m) => ExecutionPlan -> Execution m Bool
+processExecutionPlan :: (MonadBaseControl IO m, MonadIO m, Applicative m) =>
+                        ExecutionPlan -> Execution m Bool
 processExecutionPlan (ExecutionPlan mbackground scenario) = do
-  putDoc D.empty -- empty line
+  liftIO $ putStrLn "" -- empty line (TODO: move into OutputPrinter somehow)
   (&&) <$> maybe (return True) (processBasicScenario BackgroundKind) mbackground
        <*> processFeatureElement scenario
 
 
--- | Creates a pretty description of the feature.
-describeAbacate :: Abacate -> D.Doc
-describeAbacate feature =
-  D.vsep $
-  describeTags (fTags feature) ++ [D.white $ t2d $ fHeader feature]
-
-
--- | Creates a vertical list of tags.
-describeTags :: Tags -> [D.Doc]
-describeTags = map (D.dullcyan . ("@" D.<>) . t2d)
-
-
 ----------------------------------------------------------------------
 
 
-processFeatureElement :: (MonadIO m, Applicative m) => FeatureElement -> Execution m Bool
+processFeatureElement :: (MonadBaseControl IO m, MonadIO m, Applicative m) =>
+                         FeatureElement -> Execution m Bool
 processFeatureElement (FESO _)
-  = liftIO (hPutStrLn stderr "Scenario Outlines are not supported yet.")
-    >> return False
+  = warn "Scenario Outlines are not supported yet." >> return False
 processFeatureElement (FES sc) =
   processBasicScenario (ScenarioKind $ scTags sc) $ scBasicScenario sc
 
 
-data BasicScenarioKind = BackgroundKind | ScenarioKind Tags
-
-
-processBasicScenario :: (MonadIO m, Applicative m) => BasicScenarioKind -> BasicScenario -> Execution m Bool
+processBasicScenario :: (MonadBaseControl IO m, MonadIO m, Applicative m) =>
+                        BasicScenarioKind -> BasicScenario -> Execution m Bool
 processBasicScenario kind scenario = do
   putDoc $ describeBasicScenario kind scenario
   processSteps (bsSteps scenario)
 
 
--- | Creates a pretty description of the basic scenario's header.
-describeBasicScenario :: BasicScenarioKind -> BasicScenario -> D.Doc
-describeBasicScenario kind scenario =
-  D.indent 2 $
-  prettyTags kind $
-  D.bold ((describeBasicScenarioKind kind) D.<+> t2d (bsName scenario))
-    where describeBasicScenarioKind BackgroundKind   = "Background:"
-          describeBasicScenarioKind (ScenarioKind _) = "Scenario:"
-
-          prettyTags BackgroundKind      = id
-          prettyTags (ScenarioKind tags) = D.vsep . (describeTags tags ++) . (:[])
-
-
 ----------------------------------------------------------------------
 
 
-processSteps :: (MonadIO m, Applicative m) => Steps -> Execution m Bool
-processSteps steps
-  = do
-    codes <- mapM processStep steps
-    return $ and codes
-
-
-processStep :: (MonadIO m, Applicative m) => Step -> Execution m Bool
-processStep step
-  = do
-    cc <- ask
-    case parse cc "processStep" $ stBody step of
-      Left e
-        -> do
-          putDoc $ describeStep UnknownStep step
-          liftIO
-            $ hPutStrLn stderr
-            $ "The step "
-              ++ show (stBody step)
-              ++ " doesn't match any step definitions I know."
-              ++ show e
-          return False
-      Right m -> do
-        -- TODO: Catch failures and treat them nicely.
-        putDoc $ describeStep SuccessfulStep step
-        lift m
-        return True
+processSteps :: (MonadBaseControl IO m, MonadIO m, Applicative m) => Steps -> Execution m Bool
+processSteps steps = mapShortCircuitM processStep steps
 
 
-data StepResult = SuccessfulStep | UnknownStep
+mapShortCircuitM :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
+mapShortCircuitM _ []     = return True
+mapShortCircuitM f (x:xs) = do
+  ret <- f x
+  if ret then mapShortCircuitM f xs
+         else return False
 
 
--- | Pretty-prints a step that has already finished executing.
-describeStep :: StepResult -> Step -> D.Doc
-describeStep result step =
-  D.indent 4 $
-  color result (D.text (show $ stStepKeyword step) D.<+> t2d (stBody step))
-    where
-      color SuccessfulStep = D.green
-      color UnknownStep    = D.yellow
+-- | Executes the parser of each step and prints the result on the
+-- screen.
+processStep :: (MonadBaseControl IO m, MonadIO m, Applicative m) => Step -> Execution m Bool
+processStep step = do
+  parseStep <- ask
+  case parseStep step of
+    Left e -> do
+      putDoc $ describeStep UnknownStep step
+      liftIO $ warn $ concat [ "The step "
+                             , show (stBody step)
+                             , " doesn't match any step definitions I know."
+                             , show e ]
+      return False
+    Right m -> do
+      r <- E.catches (lift m >> return SuccessfulStep)
+             [ E.Handler $ \(e :: E.AsyncException) -> E.throw (e :: E.AsyncException)
+             , E.Handler $ \(_ :: E.SomeException)  -> return FailedStep ]
+      putDoc (describeStep r step)
+      return (r == SuccessfulStep)
 
 
 ----------------------------------------------------------------------
 
 
 data Options
-  = Options {file_ :: FilePath}
+  = Options {file_ :: [FilePath]}
     deriving (Eq, Show, Typeable, Data)
 
 
-getPath :: IO FilePath
-getPath
-  = do
-    progName <- getProgName
-    file_
-      <$> cmdArgs
-        (Options (def &= typ "PATH" &= argPos 0)
-          &= program progName
-          &= details
-            ["Run test scenarios specified on the abacate file at PATH."])
+-- Gets the feature files as arguments from the command-line.
+getPaths :: IO [FilePath]
+getPaths = do
+  progName <- getProgName
+  file_ <$> cmdArgs (Options (def &= typ "PATH" &= args)
+                     &= program progName
+                     &= details ["Run one or more abacate files."])
diff --git a/src/Test/Chuchu/Email.hs b/src/Test/Chuchu/Email.hs
--- a/src/Test/Chuchu/Email.hs
+++ b/src/Test/Chuchu/Email.hs
@@ -13,12 +13,10 @@
 -- <http://porg.es/blog/email-address-validation-simpler-faster-more-correct>.
 module Test.Chuchu.Email (addrSpecSimple) where
 
--- base
-import Control.Applicative hiding ((<|>), many, optional)
+import Control.Applicative ((<$>), (<|>))
+import Text.Parsec (oneOf, many1, string, alphaNum)
+import Text.Parsec.Text (Parser)
 
--- parsec
-import Text.Parsec
-import Text.Parsec.Text
 
 -- | Parses a simplified e-mail address and return everything that was parsed as
 -- a simple 'String'.
diff --git a/src/Test/Chuchu/OutputPrinter.hs b/src/Test/Chuchu/OutputPrinter.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Chuchu/OutputPrinter.hs
@@ -0,0 +1,74 @@
+module Test.Chuchu.OutputPrinter
+  ( putDoc
+  , warn
+  , describeAbacate
+  , describeBasicScenario
+  , BasicScenarioKind(..)
+  , describeStep
+  , StepResult(..)
+  ) where
+
+import Control.Monad.IO.Class (MonadIO(liftIO))
+import Language.Abacate hiding (StepKeyword (..))
+import System.IO (hPutStrLn, stderr)
+import qualified Data.Text as T
+import qualified Text.PrettyPrint.ANSI.Leijen as D
+
+
+-- | Print a 'D.Doc' describing what we're currently processing.
+putDoc :: MonadIO m => D.Doc -> m ()
+putDoc = liftIO . D.putDoc . (D.<> D.linebreak)
+
+
+-- | Print a warning message.
+warn :: MonadIO m => String -> m ()
+warn = liftIO . hPutStrLn stderr
+
+
+----------------------------------------------------------------------
+
+
+-- | Same as 'D.text' but using 'T.Text'.
+t2d :: T.Text -> D.Doc
+t2d = D.text . T.unpack
+
+
+-- | Creates a pretty description of the feature.
+describeAbacate :: Abacate -> D.Doc
+describeAbacate feature =
+  D.vsep $
+  describeTags (fTags feature) ++ [D.white $ t2d $ fHeader feature]
+
+
+-- | Creates a vertical list of tags.
+describeTags :: Tags -> [D.Doc]
+describeTags = map (D.dullcyan . ("@" D.<>) . t2d)
+
+
+-- | Creates a pretty description of the basic scenario's header.
+describeBasicScenario :: BasicScenarioKind -> BasicScenario -> D.Doc
+describeBasicScenario kind scenario =
+  D.indent 2 $
+  prettyTags kind $
+  D.bold ((describeBasicScenarioKind kind) D.<+> t2d (bsName scenario))
+    where describeBasicScenarioKind BackgroundKind   = "Background:"
+          describeBasicScenarioKind (ScenarioKind _) = "Scenario:"
+
+          prettyTags BackgroundKind      = id
+          prettyTags (ScenarioKind tags) = D.vsep . (describeTags tags ++) . (:[])
+
+
+data BasicScenarioKind = BackgroundKind | ScenarioKind Tags
+
+
+-- | Pretty-prints a step that has already finished executing.
+describeStep :: StepResult -> Step -> D.Doc
+describeStep result step =
+  D.indent 4 $
+  color result (D.text (show $ stStepKeyword step) D.<+> t2d (stBody step))
+    where
+      color SuccessfulStep = D.green
+      color FailedStep     = D.red
+      color UnknownStep    = D.yellow
+
+data StepResult = SuccessfulStep | FailedStep | UnknownStep deriving (Eq)
diff --git a/src/Test/Chuchu/Parsec.hs b/src/Test/Chuchu/Parsec.hs
--- a/src/Test/Chuchu/Parsec.hs
+++ b/src/Test/Chuchu/Parsec.hs
@@ -37,12 +37,12 @@
 
 module Test.Chuchu.Parsec (stringLiteral, natFloat, int) where
 
--- base
-import Data.Char
-
--- parsec
+import Control.Applicative ((<|>), many)
+import Data.Char (digitToInt)
 import Text.Parsec
-import Text.Parsec.Text
+       ( (<?>), between, choice, digit, char, hexDigit, many1
+       , octDigit, oneOf, option, satisfy, space, string, try, upper )
+import Text.Parsec.Text (Parser)
 
 {-# ANN module ("HLint: ignore" :: String) #-}
 -- | 'lexeme' removed.
diff --git a/src/Test/Chuchu/Parser.hs b/src/Test/Chuchu/Parser.hs
--- a/src/Test/Chuchu/Parser.hs
+++ b/src/Test/Chuchu/Parser.hs
@@ -19,20 +19,19 @@
   , try
   ) where
 
-import Control.Applicative hiding ((<|>))
-import Text.Parsec hiding (try)
+import Control.Applicative ((<$>))
 import qualified Data.Text as T
-import qualified Text.Parsec as Parsec
+import qualified Text.Parsec as P
 
 import Test.Chuchu.Types (ChuchuParser(..))
 import Test.Chuchu.Email
-import qualified Test.Chuchu.Parsec as P
+import qualified Test.Chuchu.Parsec as P'
 
 
 -- | Parses a floating point number, with the same syntax as accepted by
 -- Haskell.
 number :: ChuchuParser Double
-number = ChuchuParser $ nofToDouble <$> P.natFloat
+number = ChuchuParser $ nofToDouble <$> P'.natFloat
 
 
 nofToDouble :: Either Integer Double -> Double
@@ -42,17 +41,17 @@
 
 -- | Parses an integer.
 int :: ChuchuParser Integer
-int = ChuchuParser P.int
+int = ChuchuParser P'.int
 
 
 -- | Parses a quoted string, with the same syntax as accepted by Haskell.
 text :: ChuchuParser T.Text
-text = T.pack <$> ChuchuParser P.stringLiteral
+text = T.pack <$> ChuchuParser P'.stringLiteral
 
 
 -- | Parses anything until the string passed as parameter, and also the string.
 wildcard :: T.Text -> ChuchuParser T.Text
-wildcard = fmap T.pack . ChuchuParser . manyTill anyChar . Parsec.try . string . T.unpack
+wildcard = fmap T.pack . ChuchuParser . P.manyTill P.anyChar . P.try . P.string . T.unpack
 
 
 -- | Parses a simplified e-mail address and return everything that was parsed as
@@ -65,4 +64,4 @@
 
 -- | Same as Parsec's 'Parsec.try' but for 'ChuchuParser'.
 try :: ChuchuParser a -> ChuchuParser a
-try (ChuchuParser x) = ChuchuParser (Parsec.try x)
+try (ChuchuParser x) = ChuchuParser (P.try x)
diff --git a/src/Test/Chuchu/Types.hs b/src/Test/Chuchu/Types.hs
--- a/src/Test/Chuchu/Types.hs
+++ b/src/Test/Chuchu/Types.hs
@@ -11,24 +11,21 @@
   (ChuchuParser (..), Chuchu, ChuchuM (Given, When, Then, And, But), runChuchu)
   where
 
--- base
-import Control.Applicative hiding ((<|>))
+import Control.Applicative (Applicative((<*)), Alternative((<|>)), (<$>))
 import Control.Monad (MonadPlus)
-import Data.String
-
--- parsec
-import Text.Parsec
-import Text.Parsec.Text
+import Data.String (IsString(..))
+import qualified Text.Parsec as P
+import qualified Text.Parsec.Text as P (Parser)
 
 
 -- | @newtype@ for Parsec's 'Parser' used on this library.  The
 -- main reason for not using 'Parser' directly is to be able to
 -- define the 'IsString' instance.
-newtype ChuchuParser a = ChuchuParser (Parser a)
+newtype ChuchuParser a = ChuchuParser (P.Parser a)
   deriving (Functor, Applicative, Alternative, Monad, MonadPlus)
 
 instance (a ~ ()) => IsString (ChuchuParser a) where
-  fromString s = ChuchuParser (try (string s) >> return ())
+  fromString s = ChuchuParser (P.try (P.string s) >> return ())
 
 
 -- | The most common use case where the return value of the Monad is ignored.
@@ -54,8 +51,8 @@
 -- | Converts the Monad into a single 'Parser' that executes the specified
 -- action if the parser is executed correctly.  It includes an 'eof' on the
 -- parser of each step to avoid it from accepting prefixes of the desired rule.
-runChuchu :: ChuchuM m a -> Parser (m ())
-runChuchu Nil = unexpected "Unknown step"
+runChuchu :: ChuchuM m a -> P.Parser (m ())
+runChuchu Nil = P.unexpected "Unknown step"
 runChuchu (Cons cc1 cc2) = runChuchu cc1 <|> runChuchu cc2
 runChuchu (Given p f) = apply p f
 runChuchu (When p f) = apply p f
@@ -63,5 +60,5 @@
 runChuchu (And p f) = apply p f
 runChuchu (But p f) = apply p f
 
-apply :: ChuchuParser a -> (a -> m ()) -> Parser (m ())
-apply (ChuchuParser p) f = try $ f <$> p <* eof
+apply :: ChuchuParser a -> (a -> m ()) -> P.Parser (m ())
+apply (ChuchuParser p) f = P.try $ f <$> p <* P.eof
diff --git a/tests/data/multiple_features1.feature b/tests/data/multiple_features1.feature
new file mode 100644
--- /dev/null
+++ b/tests/data/multiple_features1.feature
@@ -0,0 +1,7 @@
+Feature: Multiple features 1
+
+  This feature is intended to be used with another one to test if
+  Chuchu executes more than one feature file.
+
+  Scenario: Anybody can use the bathroom
+    Given that "Bob" has entered the bathroom and locked the door
diff --git a/tests/data/multiple_features2.feature b/tests/data/multiple_features2.feature
new file mode 100644
--- /dev/null
+++ b/tests/data/multiple_features2.feature
@@ -0,0 +1,7 @@
+Feature: Multiple features 2
+
+  This feature is intended to be used with another one to test if
+  Chuchu executes more than one feature file.
+
+  Scenario: Anybody can use the bathroom
+    Given that "Alice" has entered the bathroom and locked the door
diff --git a/tests/data/should_fail.feature b/tests/data/should_fail.feature
new file mode 100644
--- /dev/null
+++ b/tests/data/should_fail.feature
@@ -0,0 +1,7 @@
+Feature: Chuchu should know how to catch failure
+
+  Scenario: Unknown step definition must stop execution
+    Given non-existent step
+
+  Scenario: Step that fails must stop execution
+    Given failing step
diff --git a/tests/multiple_features.hs b/tests/multiple_features.hs
new file mode 100644
--- /dev/null
+++ b/tests/multiple_features.hs
@@ -0,0 +1,26 @@
+import Control.Applicative
+import Control.Monad.Trans.State
+import System.Environment
+import Test.Chuchu
+
+
+type Bathroom = StateT Door IO
+
+
+data Door = Open | Locked
+
+
+defs :: Chuchu Bathroom
+defs = do
+
+  Given ("that " *> text <* " has entered the bathroom and locked the door") $ \_ -> do
+    door <- get
+    case door of
+      Open -> put Locked
+      Locked -> fail "Door was already locked."
+
+
+main :: IO ()
+main = withArgs [ "tests/data/multiple_features1.feature"
+                , "tests/data/multiple_features2.feature" ] $
+       chuchuMain defs (`evalStateT` Open)
diff --git a/tests/should_fail.hs b/tests/should_fail.hs
new file mode 100644
--- /dev/null
+++ b/tests/should_fail.hs
@@ -0,0 +1,36 @@
+import Control.Exception (handle)
+import System.Environment (withArgs)
+import System.Exit (exitWith, ExitCode(ExitSuccess, ExitFailure))
+import Test.Chuchu
+
+
+defs :: Chuchu IO
+defs = do
+  Given "failing step" $ \() -> do
+    fail "Error"
+
+
+-- | This functions verifies if the behaviour of Chuchu was
+-- correct. The correct behaviour is to have 'n' number of failed
+-- scenarios (this number comes from the exit code). If no scenarios
+-- fail or the number of failed scenarios is different than 'n' then
+-- Chuchu failed.
+scenariosShouldFail :: Int -> IO () -> IO ()
+scenariosShouldFail n = handle exit
+    where exit ExitSuccess                  = failWith 255
+          exit (ExitFailure n') | n /= n'   = failWith n'
+                                | otherwise = putStrLn "Okay, everything failed!"
+          failWith n' = do
+            putStrLn $ concat
+              [ "\n"
+              , show n
+              , " `scenariosShouldFail` _: failure, exiting with code "
+              , show n'
+              , "." ]
+            exitWith (ExitFailure n')
+
+
+main :: IO ()
+main = withArgs [ "tests/data/should_fail.feature" ] $
+         2 `scenariosShouldFail` chuchuMain defs id
+
