diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -86,7 +86,7 @@
                         replace those with the same name under `app/assets/`.
     dev/modules/    --> Works just like `app/modules/`.
     public/         --> Built files when developing. Not committed to source
-    test/           --> Test files go here
+    tests/          --> Test files go here
 
 
 ## Development
@@ -121,21 +121,27 @@
 
 ```
 root
-|-- app/modules
+|-- app/modules/
     |-- a.js
     |-- b.js
-|-- test/modules
+    |-- c/
+        |- d.js
+|-- tests/
     |-- test-a.js
     |-- test-b.js
+    |-- c/
+        |-- d.js
 ```
 
-When testing your codebase, structure your project like the above. And then, we
-take a look at how to write a test file in directory `test/modules`:
+When testing your codebase, structure your project like the above. Note that
+the path relative to `tests/` should correspond to the path relative to
+`app/modules/`.
 
+An example of a test suite:
+
 ```js
-define('name this to whatever but do not conflict with your module (e.g. test-a)',
-['moduleA'],
-function (a) {
+define('name this to whatever but do not conflict with your module (e.g. `test-a`)',
+['moduleA'], function (a) {
 
   describe('some text', function () {
     it('should ...', function () {
@@ -148,14 +154,12 @@
 });
 ```
 
-Duplo's test suite includes [mocha](http://mochajs.org/) and
-[chai.js](http://chaijs.com/).
-
-By the way, it supports another powerful testing tool,
+Duplo's test suite uses [mocha](http://mochajs.org/) and
+[chai.js](http://chaijs.com/). It also supports another powerful testing tool,
 [SinonJS](http://sinonjs.org/), so you may fake/mock any functions, ajax
-requests and timers yourself.
+requests, and timers yourself.
 
-As so far, Duplo's test environment includes these 3 modules:
+You may therefore use these functions:
 
 - mocha: `describe`, `it` and etc.
 - chai.js: `expect` and `assert`.
@@ -386,6 +390,10 @@
 3. `$ util/publish.sh`
 4. `$ npm publish`
 5. [Publish to Hackage](http://hackage.haskell.org/upload)
+
+Note: *ALWAYS* always use [Stackage](http://www.stackage.org/) while do not
+specify versions in the Cabal file. Just specify the dependencies by name and
+let Stackage manage the versions.
 
 
 ## Copyright and License
diff --git a/duplo.cabal b/duplo.cabal
--- a/duplo.cabal
+++ b/duplo.cabal
@@ -1,5 +1,5 @@
 name:               duplo
-version:            1.6.19
+version:            1.8.0
 synopsis:           Frontend development build tool
 description:        Intuitive, simple building blocks for building composable, completely self-managed web applications
 license:            MIT
@@ -16,101 +16,101 @@
   location: https://github.com/pixbi/duplo.git
 
 library
-  ghc-options        : -Wall
-  hs-source-dirs     : src
-  default-language   : Haskell2010
-  default-extensions : OverloadedStrings
-  exposed-modules    : Development.Duplo
-                     , Development.Duplo.Component
-                     , Development.Duplo.FileList
-                     , Development.Duplo.Files
-                     , Development.Duplo.Git
-                     , Development.Duplo.JavaScript.Order
-                     , Development.Duplo.Markups
-                     , Development.Duplo.Scripts
-                     , Development.Duplo.Server
-                     , Development.Duplo.Static
-                     , Development.Duplo.Styles
-                     , Development.Duplo.Types.AppInfo
-                     , Development.Duplo.Types.Builder
-                     , Development.Duplo.Types.Config
-                     , Development.Duplo.Types.JavaScript
-                     , Development.Duplo.Types.Options
-                     , Development.Duplo.Utilities
-                     , Development.Duplo.Watcher
-  build-depends      : base                               == 4.7.*
-                     , aeson                              == 0.8.*
-                     , aeson-pretty                       == 0.7.*
-                     , ansi-terminal                      == 0.6.*
-                     , bytestring                         == 0.10.*
-                     , containers                         == 0.5.*
-                     , directory                          == 1.2.*
-                     , executable-path                    == 0.0.*
-                     , filepath                           == 1.3.*
-                     , fsnotify                           == 0.1.*
-                     , http-types                         == 0.8.*
-                     , language-javascript                == 0.5.*
-                     , lens                               == 4.6.*
-                     , mtl                                == 2.1.*
-                     , regex-compat                       == 0.95.*
-                     , scotty                             == 0.9.*
-                     , shake                              == 0.14.*
-                     , system-fileio                      == 0.3.*
-                     , text                               == 1.2.*
-                     , text-format                        == 0.3.*
-                     , transformers                       == 0.3.*
-                     , unordered-containers               == 0.2.*
-                     , utf8-string                        == 0.3.*
-                     , wai                                == 3.0.*
-                     , warp                               == 3.0.*
-                     , MissingH                           == 1.3.*
+  ghc-options:          -Wall
+  hs-source-dirs:       src
+  default-language:     Haskell2010
+  default-extensions:   OverloadedStrings
+  exposed-modules:      Development.Duplo
+                      , Development.Duplo.Component
+                      , Development.Duplo.FileList
+                      , Development.Duplo.Files
+                      , Development.Duplo.Git
+                      , Development.Duplo.JavaScript.Order
+                      , Development.Duplo.Markups
+                      , Development.Duplo.Scripts
+                      , Development.Duplo.Server
+                      , Development.Duplo.Static
+                      , Development.Duplo.Styles
+                      , Development.Duplo.Types.AppInfo
+                      , Development.Duplo.Types.Builder
+                      , Development.Duplo.Types.Config
+                      , Development.Duplo.Types.JavaScript
+                      , Development.Duplo.Types.Options
+                      , Development.Duplo.Utilities
+                      , Development.Duplo.Watcher
+  build-depends:        base == 4.7.*
+                      , aeson
+                      , aeson-pretty
+                      , ansi-terminal
+                      , bytestring
+                      , containers
+                      , directory
+                      , executable-path
+                      , filepath
+                      , fsnotify
+                      , http-types
+                      , language-javascript
+                      , lens
+                      , mtl
+                      , regex-compat
+                      , scotty
+                      , shake
+                      , system-fileio
+                      , text
+                      , text-format
+                      , transformers
+                      , unordered-containers
+                      , utf8-string
+                      , wai
+                      , warp
+                      , MissingH
 
 executable duplo
-  main-is            : CLI.hs
-  ghc-options        : -rtsopts
-  hs-source-dirs     : src
-  default-language   : Haskell2010
-  default-extensions : OverloadedStrings
-  build-depends      : base                 == 4.7.*
-                     , aeson                == 0.8.*
-                     , aeson                == 0.8.*
-                     , aeson-pretty         == 0.7.*
-                     , ansi-terminal        == 0.6.*
-                     , base64-bytestring    == 1.0.*
-                     , bytestring           == 0.10.*
-                     , containers           == 0.5.*
-                     , directory            == 1.2.*
-                     , duplo
-                     , filepath             == 1.3.*
-                     , fsnotify             == 0.1.*
-                     , http-types           == 0.8.*
-                     , language-javascript  == 0.5.*
-                     , lens                 == 4.6.*
-                     , mtl                  == 2.1.*
-                     , process              == 1.2.*
-                     , regex-compat         == 0.95.*
-                     , scotty               == 0.9.*
-                     , shake                == 0.14.*
-                     , system-filepath      == 0.4.*
-                     , text                 == 1.2.*
-                     , text-format          == 0.3.*
-                     , transformers         == 0.3.*
-                     , unordered-containers == 0.2.*
-                     , wai                  == 3.0.*
-                     , warp                 == 3.0.*
-                     , MissingH             == 1.3.*
+  main-is:              CLI.hs
+  ghc-options:          -rtsopts
+  hs-source-dirs:       src
+  default-language:     Haskell2010
+  default-extensions:   OverloadedStrings
+  build-depends:        base == 4.7.*
+                      , aeson
+                      , aeson
+                      , aeson-pretty
+                      , ansi-terminal
+                      , base64-bytestring
+                      , bytestring
+                      , containers
+                      , directory
+                      , duplo
+                      , filepath
+                      , fsnotify
+                      , http-types
+                      , language-javascript
+                      , lens
+                      , mtl
+                      , process
+                      , regex-compat
+                      , scotty
+                      , shake
+                      , system-filepath
+                      , text
+                      , text-format
+                      , transformers
+                      , unordered-containers
+                      , wai
+                      , warp
+                      , MissingH
 
 test-suite tests
-  main-is          : Tests.hs
-  ghc-options      : -Wall
-  hs-source-dirs   : tests
-  default-language : Haskell2010
-  type             : exitcode-stdio-1.0
-  build-depends    : base
-                   , duplo
-                   , HUnit              == 1.2.5.2
-                   , MissingH           == 1.3.*
-                   , QuickCheck         == 2.7.*
-                   , tasty              == 0.10.1
-                   , tasty-hunit        == 0.9.0.1
-                   , tasty-quickcheck   == 0.8.3.2
+  main-is:            Tests.hs
+  ghc-options:        -Wall
+  hs-source-dirs:     tests
+  default-language:   Haskell2010
+  type:               exitcode-stdio-1.0
+  build-depends:      base == 4.7.*
+                    , duplo
+                    , HUnit
+                    , MissingH
+                    , QuickCheck
+                    , tasty
+                    , tasty-hunit
+                    , tasty-quickcheck
diff --git a/src/CLI.hs b/src/CLI.hs
--- a/src/CLI.hs
+++ b/src/CLI.hs
@@ -80,7 +80,7 @@
   let defaultsPath    = miscPath </> "static/"
   let appPath         = cwd </> "app/"
   let devPath         = cwd </> "dev/"
-  let testPath        = cwd </> "test/"
+  let testPath        = cwd </> "tests/"
   let assetsPath      = appPath </> "assets/"
   let depsPath        = cwd </> "components/"
   let targetPath      = cwd </> "public/"
@@ -90,7 +90,7 @@
                     -- `build` is a special case. It takes `production` as the
                     -- default.
                     "build" -> fromMaybe "production" duploEnvMB
-                    -- By default, `dev` is the default.
+                    -- `dev` is the default.
                     _ -> fromMaybe "development" duploEnvMB
 
   -- Internal command translation
@@ -108,7 +108,7 @@
           "live"       -> ( "build"   , ""      , "production"  , True  )
           "production" -> ( "build"   , ""      , "production"  , True  )
           "build"      -> ( "build"   , ""      , duploEnv      , False )
-          "test"       -> ( "build"   , ""      , "test"        , False )
+          "test"       -> ( "test"    , ""      , "test"        , False )
           _            -> ( cmdName   , ""      , duploEnv      , False )
 
   -- Certain flags turn into commands.
@@ -143,11 +143,7 @@
   appVersion <- ignoreManifestError $ fmap AI.version CM.readManifest
   appId <- ignoreManifestError $ fmap CM.appId CM.readManifest
 
-  -- We may need custom builds with mode
-  let depManifestPath = cwd </> "component.json"
-
-  -- TODO(Yorkie): to be remove if verified by @Kenneth
-  -- because the depIds is unnecessary in config
+  -- Get all dependencies' names in dash-ified form
   dependencies <- CM.getDependencies $ case duploMode of
                                          "" -> Nothing
                                          a  -> Just a
@@ -212,8 +208,12 @@
   when makefileExists $ void $ createProcess $ proc "make" [duploEnv]
 
   -- Construct the Shake command.
-  let shake' = build  cmdNameWithFlags cmdArgs buildConfig options
+  let shake' = build cmdNameWithFlags cmdArgs buildConfig options
   let shake  = shake' `catch` handleExc
+
+  -- We should start with a clean slate.
+  let noCleanActions = [ "clean", "bump", "init", "version" ]
+  unless (cmdNameWithFlags `elem` noCleanActions) $ build "clean" [] buildConfig options
 
   -- Watch or just build.
   unless toWatch shake
diff --git a/src/Development/Duplo.hs b/src/Development/Duplo.hs
--- a/src/Development/Duplo.hs
+++ b/src/Development/Duplo.hs
@@ -14,7 +14,8 @@
 import qualified Development.Duplo.Types.Builder as BD
 import qualified Development.Duplo.Types.Config  as TC
 import qualified Development.Duplo.Types.Options as OP
-import           Development.Duplo.Utilities     (createStdEnv,
+import           Development.Duplo.Utilities     (createIntermediaryDirectories,
+                                                  createStdEnv,
                                                   headerPrintSetter, logStatus,
                                                   successPrintSetter)
 import           Development.Shake
@@ -57,6 +58,7 @@
       let actions = [ "static"
                     , "clean"
                     , "build"
+                    , "test"
                     , "bump"
                     , "init"
                     , "version"
@@ -91,9 +93,6 @@
       successPrinter "Clean completed"
 
     "build" ~> do
-      -- Always rebuild if we're building for production.
-      unless (TC.isInDev config) $ need ["clean"]
-
       -- Make sure all static files and dependencies are there.
       need ["static", "deps"]
       -- Then compile, in parallel.
@@ -101,8 +100,48 @@
 
       successPrinter "Build completed"
 
-      when (TC.isInTest config) $ need ["test"]
+    "test" ~> do
+      envOpt              <- createStdEnv config
+      let appPath         =  config ^. TC.appPath
+      let targetPath      =  config ^. TC.targetPath </> "tests"
+      let utilPath        =  config ^. TC.utilPath
+      let testPath        =  config ^. TC.testPath
+      let testCompiler    =  utilPath </> "scripts-test.sh"
+      let find path pttrn =  command [Cwd path] (utilPath </> "find.sh") [".", pttrn]
 
+      -- There must be a test directory.
+      testsExist <- doesDirectoryExist testPath
+      unless testsExist $ throw BD.MissingTestDirectory
+
+      -- Do a semi-full build
+      need ["static", "deps"]
+      need [targetScript, targetStyle]
+
+      let prepareFile path =
+            do
+              let absPath = targetPath </> path
+              -- Create intermediary directories
+              createIntermediaryDirectories absPath
+              -- Inject into each app file dependencies, AMD, etc in
+              -- preparation for testing.
+              Stdout compiled <- command [envOpt] testCompiler [path]
+              -- Then write to the respective path in the output directory.
+              writeFileChanged absPath compiled
+
+      -- Each path is relative to the application root (most likely
+      -- `app/`).
+      Stdout codePaths' <- find testPath "*.js"
+      mapM_ prepareFile $ lines codePaths'
+
+      -- Build the markup once we have the script files in target.
+      need [targetMarkup]
+
+      -- Run the test suite
+      command_ [envOpt] (utilPath </> "run-test.sh") []
+
+      -- Copy over
+      successPrinter "Tests completed"
+
     "bump" ~> do
       (oldVersion, newVersion) <- Git.commit config bumpLevel
 
@@ -112,7 +151,7 @@
       let user = cmdArgs ^. element 0
       let repo = cmdArgs ^. element 1
       let name = user ++ "/" ++ repo
-      let src = miscPath </> "boilerplate/"
+      let src  = miscPath </> "boilerplate/"
       let dest = cwd ++ "/"
 
       -- Check prerequisites
@@ -136,10 +175,6 @@
       command_ [] (utilPath </> "init-git.sh") [name]
 
       successPrinter $ "Project created at " ++ dest
-
-    "test" ~> do
-      envOpt <- createStdEnv config
-      command_ [envOpt] (utilPath </> "run-test.sh") [duploPath]
 
     -- Version should have already been displayed if requested
     "version" ~> return ()
diff --git a/src/Development/Duplo/Component.hs b/src/Development/Duplo/Component.hs
--- a/src/Development/Duplo/Component.hs
+++ b/src/Development/Duplo/Component.hs
@@ -4,7 +4,7 @@
 
 import           Control.Exception               (throw)
 import           Control.Lens.Operators
-import           Control.Monad                   (liftM)
+import           Control.Monad                   (liftM, unless)
 import           Data.Aeson                      (decode, encode)
 import           Data.Aeson.Encode.Pretty        (encodePretty)
 import           Data.ByteString.Lazy.Char8      (ByteString)
@@ -78,15 +78,14 @@
 -- | Given a path, find all the `component.json` and return a JSON string
 extractCompVersions :: TC.BuildConfig -> Action String
 extractCompVersions config = do
-    let path     = config ^. TC.cwd
-    let utilPath = config ^. TC.utilPath
+    let path = config ^. TC.cwd
     -- Get all the relevant paths
-    paths <- getAllManifestPaths utilPath path
+    paths <- getAllManifestPaths config path
     -- Construct the pipeline
     let toVersion path'   = appInfoToVersion . decodeManifest path' . BS.pack
     let takeVersion path' = liftM (toVersion path') (readFile path')
     -- Go through it
-    manifests <- mapM (liftIO . takeVersion) paths
+    manifests <- mapM (liftIO . takeVersion) (paths ++ ["./component.json"])
     -- Marshalling
     return $ BS.unpack $ encode $ fromList manifests
 
@@ -102,10 +101,17 @@
 appInfoToVersion appInfo = (AI.name appInfo, AI.version appInfo)
 
 -- | Given a path, find all the `component.json`s
-getAllManifestPaths :: FilePath -> FilePath -> Action [FilePath]
-getAllManifestPaths utilPath root = do
-    Stdout out <- command [] (utilPath </> "find.sh") [root, manifestName]
-    return $ lines out
+getAllManifestPaths :: TC.BuildConfig -> FilePath -> Action [FilePath]
+getAllManifestPaths config root = do
+    let cwd      = config ^. TC.cwd
+    let utilPath = config ^. TC.utilPath
+    let depsPath = config ^. TC.depsPath
+    -- Find all dependencies' manifests
+    Stdout out <- command [] (utilPath </> "find.sh") [depsPath, manifestName]
+    -- Get the current repo's manifest
+    let currentRepoManifest = cwd </> "component.json"
+    -- These should be all `component.json`s
+    return $ lines out ++ [currentRepoManifest]
 
 -- | Get the component dependency list by providing a mode, or not.
 getDependencies :: Maybe String -> IO [FilePath]
diff --git a/src/Development/Duplo/Git.hs b/src/Development/Duplo/Git.hs
--- a/src/Development/Duplo/Git.hs
+++ b/src/Development/Duplo/Git.hs
@@ -91,26 +91,26 @@
 -- | Read from the given directory and update the app manifest object.
 updateFileRegistry :: TC.BuildConfig -> AI.AppInfo -> Action AI.AppInfo
 updateFileRegistry config appInfo = do
-    let cwd = config ^. TC.cwd
-    let utilPath = config ^. TC.utilPath
-    let appPath = cwd </> "app"
+    let cwd       = config ^. TC.cwd
+    let utilPath  = config ^. TC.utilPath
+    let appPath   = cwd </> "app"
     let assetPath = appPath </> "assets"
     let imagePath = assetPath </> "images"
-    let fontPath = assetPath </> "fonts"
+    let fontPath  = assetPath </> "fonts"
 
     -- Helper functions
     let find path pttrn = command [] (utilPath </> "find.sh") [path, pttrn]
-    let split = fmap unpack . splitOn "\n" . pack
-    let makeRelative' = makeRelative cwd
-    let filterNames = filter ((> 0) . length)
+    let split           = fmap unpack . splitOn "\n" . pack
+    let makeRelative'   = makeRelative cwd
+    let filterNames     = filter ((> 0) . length)
     let prepareFileList = filterNames . fmap (makeRelative cwd) . split
 
     -- Collect eligible files
     Stdout scripts <- find appPath "*.js"
-    Stdout styles <- find appPath "*.styl"
+    Stdout styles  <- find appPath "*.styl"
     Stdout markups <- find appPath "*.jade"
-    Stdout images <- find imagePath "*"
-    Stdout fonts <- find fontPath "*"
+    Stdout images  <- find imagePath "*"
+    Stdout fonts   <- find fontPath "*"
 
     -- Convert to arrays and make relative to cwd
     let scripts' = prepareFileList scripts
diff --git a/src/Development/Duplo/JavaScript/Order.hs b/src/Development/Duplo/JavaScript/Order.hs
--- a/src/Development/Duplo/JavaScript/Order.hs
+++ b/src/Development/Duplo/JavaScript/Order.hs
@@ -17,9 +17,6 @@
 import           Language.JavaScript.Parser         (JSNode (..), Node (..),
                                                      TokenPosn (..))
 
-import           Debug.Trace
-trace' a = trace (show a) a
-
 makeLenses ''Module
 
 -- | Reorder modules within the root node.
diff --git a/src/Development/Duplo/Markups.hs b/src/Development/Duplo/Markups.hs
--- a/src/Development/Duplo/Markups.hs
+++ b/src/Development/Duplo/Markups.hs
@@ -51,7 +51,6 @@
   let devAssetsPath = devPath </> "assets"
   let devCodePath   = devPath </> "modules/index"
   let depIds        = config ^. TC.dependencies
-  let inTest        = TC.isInTest config
 
   -- Preconditions
   lift $ createIntermediaryDirectories devCodePath
@@ -89,26 +88,16 @@
   -- Inject compiled code into the index
   let indexWithMarkup = replace "<body>" ("<body>" ++ compiled) compiledIndex
 
-  -- Inject CSS/JS references
-  refTags <- lift $ readFile' refTagsPath
-  let indexWithRefs = replace "</head>" (refTags ++ "</head>") indexWithMarkup
-
-  -- Inject CSS/JS references if in testing
-  refTagsInTest <- lift $ readFile' (duploPath </> "etc/test/head.html")
-  scriptsPaths  <- lift $ expandPaths cwd ".js" [] [ testPath </> "modules"
-                                                   , appPath  </> "modules"
-                                                   ]
+  -- Inject CSS/JS references, if we're NOT in testing
+  refTagsNormal <- lift $ readFile' refTagsPath
 
-  let buildScriptTag path = "<script defer=\"defer\" src=\"" ++ makeRelative cwd path ++ "\"></script>"
-  let scriptsTags         = concatMap buildScriptTag scriptsPaths
-  let indexWithTestRefs   = if   inTest
-                            then replace "</head>" (refTagsInTest ++ scriptsTags ++ "</head>") indexWithRefs
-                            else indexWithRefs
+  -- Inject CSS/JS references
+  let indexWithTags = replace "</head>" (refTagsNormal ++ "</head>") indexWithMarkup
 
   -- Path to the minifier
   let minifier = utilPath </> "markups-minify.sh"
   -- Minify it
-  let postMinify _ = return indexWithTestRefs
+  let postMinify _ = return indexWithTags
   minified <- compile config minifier [] paths return postMinify
 
   -- Write it to disk
diff --git a/src/Development/Duplo/Scripts.hs b/src/Development/Duplo/Scripts.hs
--- a/src/Development/Duplo/Scripts.hs
+++ b/src/Development/Duplo/Scripts.hs
@@ -56,8 +56,6 @@
   let devPath     = config ^. TC.devPath
   let depsPath    = config ^. TC.depsPath
   let devCodePath = devPath </> "modules/index.js"
-  let inDev       = TC.isInDev config
-  let inTest      = TC.isInTest config
   let depIds      = config ^. TC.dependencies
 
   -- Preconditions
@@ -74,7 +72,7 @@
   -- These paths don't need to be expanded.
   let staticPaths = case buildMode of
                       "development" -> [ "dev/index" ]
-                      "test"        -> [ "test/index" ]
+                      "test"        -> [ "dev/index" ]
                       _             -> []
                  ++ [ "app/index" ]
 
@@ -107,7 +105,7 @@
   -- Configure the compiler
   let compiler = (util </>) $ case buildMode of
                                 "development" -> "scripts-dev.sh"
-                                "test"        -> "scripts-test.sh"
+                                "test"        -> "scripts-dev.sh"
                                 _             -> "scripts-optimize.sh"
 
   -- Create a pseudo file that contains the environment variables and
diff --git a/src/Development/Duplo/Static.hs b/src/Development/Duplo/Static.hs
--- a/src/Development/Duplo/Static.hs
+++ b/src/Development/Duplo/Static.hs
@@ -87,12 +87,13 @@
 deps config = do
   liftIO $ logStatus headerPrintSetter "Copying static files"
 
-  let assetsPath = config ^. TC.assetsPath
-  let depsPath   = config ^. TC.depsPath
-  let targetPath = config ^. TC.targetPath
-  let devPath    = config ^. TC.devPath
-  let devAssetsPath = devPath </> "assets/"
+  let assetsPath     = config ^. TC.assetsPath
+  let depsPath       = config ^. TC.depsPath
+  let targetPath     = config ^. TC.targetPath
+  let devPath        = config ^. TC.devPath
+  let devAssetsPath  = devPath </> "assets/"
   let testAssetsPath = config ^. TC.duploPath </> "etc/test"
+  let buildMode      = config ^. TC.buildMode
 
   -- Make sure all these directories exist
   createPathDirectories [assetsPath, depsPath, targetPath, devAssetsPath]
@@ -103,10 +104,10 @@
   depAssetFiles <- getDepAssets depsPath
   -- Add dev files to the mix, if we're in dev mode
   devFiles'     <- getDirectoryFiles devAssetsPath ["//*"]
-  let devFiles   = if TC.isInDev config then devFiles' else []
+  let devFiles   = if buildMode == "development" then devFiles' else []
   -- Add test files to the mix, if we're in test mode
   testFiles'    <- getDirectoryFiles testAssetsPath ["vendor//*"]
-  let testFiles  = if TC.isInTest config then testFiles' else []
+  let testFiles  = if buildMode == "test" then testFiles' else []
   -- Mix them together
   let allFiles   = nub $ concat [depAssetFiles, assetFiles, devFiles, testFiles]
   -- We do NOT want index
diff --git a/src/Development/Duplo/Styles.hs b/src/Development/Duplo/Styles.hs
--- a/src/Development/Duplo/Styles.hs
+++ b/src/Development/Duplo/Styles.hs
@@ -22,6 +22,7 @@
   let devCodePath = devPath </> "modules/index.styl"
   let depIds      = config ^. TC.dependencies
   let expandDeps' = expandDeps depIds
+  let buildMode   = config ^. TC.buildMode
 
   -- Preconditions
   lift $ createIntermediaryDirectories devCodePath
@@ -46,7 +47,7 @@
   let dynamicPaths = [ "app/modules" ]
                   ++ expandDeps' expandDepsDynamic
                   -- Compile dev files in dev mode as well.
-                  ++ [ "dev/modules" | TC.isInDev config ]
+                  ++ [ "dev/modules" | buildMode == "development" ]
 
   -- Merge both types of paths
   paths <- lift $ expandPaths cwd ".styl" staticPaths dynamicPaths
diff --git a/src/Development/Duplo/Types/Builder.hs b/src/Development/Duplo/Types/Builder.hs
--- a/src/Development/Duplo/Types/Builder.hs
+++ b/src/Development/Duplo/Types/Builder.hs
@@ -9,6 +9,7 @@
                       | MissingGithubRepoException
                       | MalformedManifestException String
                       | MissingManifestException String
+                      | MissingTestDirectory
   deriving (Typeable)
 
 instance Exception BuilderException
@@ -22,3 +23,5 @@
       "The manifest file `" ++ path ++ "` is not a valid duplo JSON."
     show (MissingManifestException path) =
       "`" ++ path ++ "` is expected at the current location."
+    show MissingTestDirectory =
+      "There must be a `tests/` directory in order to run tests."
diff --git a/src/Development/Duplo/Types/Config.hs b/src/Development/Duplo/Types/Config.hs
--- a/src/Development/Duplo/Types/Config.hs
+++ b/src/Development/Duplo/Types/Config.hs
@@ -38,9 +38,3 @@
                                } deriving (Show)
 
 makeLenses ''BuildConfig
-
-isInDev :: BuildConfig -> Bool
-isInDev config = config ^. buildMode == "development"
-
-isInTest :: BuildConfig -> Bool
-isInTest config = config ^. buildMode == "test"
diff --git a/src/Development/Duplo/Utilities.hs b/src/Development/Duplo/Utilities.hs
--- a/src/Development/Duplo/Utilities.hs
+++ b/src/Development/Duplo/Utilities.hs
@@ -18,7 +18,8 @@
                                                  ColorIntensity (..),
                                                  ConsoleLayer (..), SGR (..),
                                                  setSGR)
-import           System.FilePath.Posix          (joinPath, splitPath)
+import           System.FilePath.Posix          (dropTrailingPathSeparator,
+                                                 joinPath, splitPath)
 
 type CompiledContent = MaybeT DS.Action
 type FileProcessor = [File] -> CompiledContent [File]
@@ -53,20 +54,22 @@
 -- paths, in order.
 getDirectoryFilesInOrder :: FilePath -> String -> [DS.FilePattern] -> DS.Action [FilePath]
 getDirectoryFilesInOrder base extension patterns = do
+    -- Make sure we have a clean base.
+    let base' = dropTrailingPathSeparator base
     -- We need to terminate the infinite list.
     let listSize = length patterns
     -- Make extension a list of itself.
     let exts = replicate listSize extension
     -- Turn file patterns into absolute patterns.
-    let absPatterns = fmap (base </>) patterns
+    let absPatterns = fmap (base' </>) patterns
     -- Make sure we get all valid file patterns for dynamic paths.
     validPatterns <- makeFilePatterns absPatterns exts
     -- Remove the prefix that was needed for file pattern construction.
-    let relPatterns = fmap (drop (length base + 1)) validPatterns
+    let relPatterns = fmap (drop (length base' + 1)) validPatterns
     -- We need to turn all elements into lists for each to be run independently.
     let patternLists = fmap (replicate 1) relPatterns
     -- Curry the function that gets the files given a list of paths.
-    let getFiles = getDirectoryFiles base
+    let getFiles = getDirectoryFiles base'
     -- Map over the list monadically to get the paths in order.
     allFiles <- mapM getFiles patternLists
     -- Re-package the contents into the list of paths that we've wanted.
@@ -206,10 +209,20 @@
   let nodejs = config ^. TC.nodejsPath
   let misc   = config ^. TC.miscPath
   let target = config ^. TC.targetPath
+  let duplo  = config ^. TC.duploPath
+  let test   = config ^. TC.testPath
+  let app    = config ^. TC.appPath
+  let deps   = config ^. TC.depsPath
+  let dev    = config ^. TC.devPath
 
   DS.addEnv [ ("DUPLO_UTIL", util)
             , ("DUPLO_NODEJS", nodejs)
             , ("DUPLO_CWD", cwd)
             , ("DUPLO_MISC", misc)
             , ("DUPLO_TARGET", target)
+            , ("DUPLO_PATH", duplo)
+            , ("DUPLO_TEST", test)
+            , ("DUPLO_APP", app)
+            , ("DUPLO_DEPS", deps)
+            , ("DUPLO_DEV", dev)
             ]
diff --git a/tests/Tests.hs b/tests/Tests.hs
--- a/tests/Tests.hs
+++ b/tests/Tests.hs
@@ -14,8 +14,11 @@
 main :: IO ()
 main = defaultMain tests
 
+setMaxSuccess :: TestTree -> TestTree
+setMaxSuccess = localOption $ QuickCheckTests 5000
+
 tests :: TestTree
-tests = testGroup "Tests"
+tests = setMaxSuccess $ testGroup "Tests"
   [ testGroup "Component support"
     [ QC.testProperty "slash is transformed into dash" $ \appInfo ->
         let
