diff --git a/lib/spack/spack/modules.py b/lib/spack/spack/modules.py
index 5bf003f9ad09c337e7b66291bf5bd9e7cad51577..bcccf2f9b84e922297e0b710f6e6bfd658b3c305 100644
--- a/lib/spack/spack/modules.py
+++ b/lib/spack/spack/modules.py
@@ -132,17 +132,15 @@ def dependencies(spec, request='all'):
     if request == 'none':
         return []
 
-    l = [xx for xx in
-         sorted(spec.traverse(order='post', depth=True, cover='nodes', root=False), reverse=True)]
-
     if request == 'direct':
-        return [xx for ii, xx in l if ii == 1]
+        return [xx for _, xx in spec.dependencies.items()]
 
     # FIXME : during module file creation nodes seem to be visited multiple times even if cover='nodes'
     # FIXME : is given. This work around permits to get a unique list of spec anyhow.
     # FIXME : Possibly we miss a merge step among nodes that refer to the same package.
     seen = set()
     seen_add = seen.add
+    l = [xx for xx in sorted(spec.traverse(order='post', depth=True, cover='nodes', root=False), reverse=True)]
     return [xx for ii, xx in l if not (xx in seen or seen_add(xx))]
 
 
diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py
index 175a49428c4b223f99814b541e71965bd7585dae..b1c91c79034a223aad7d6171e8a1fdc0f6dd7412 100644
--- a/lib/spack/spack/test/__init__.py
+++ b/lib/spack/spack/test/__init__.py
@@ -54,6 +54,7 @@
               'svn_fetch',
               'hg_fetch',
               'mirror',
+              'modules',
               'url_extrapolate',
               'cc',
               'link_tree',
diff --git a/lib/spack/spack/test/modules.py b/lib/spack/spack/test/modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..21afa355e7e1b5be60d6e91193a25fe443e6e73f
--- /dev/null
+++ b/lib/spack/spack/test/modules.py
@@ -0,0 +1,126 @@
+import collections
+from contextlib import contextmanager
+
+import StringIO
+
+FILE_REGISTRY = collections.defaultdict(StringIO.StringIO)
+
+# Monkey-patch open to write module files to a StringIO instance
+@contextmanager
+def mock_open(filename, mode):
+    if not mode == 'w':
+        raise RuntimeError('test.modules : unexpected opening mode for monkey-patched open')
+
+    FILE_REGISTRY[filename] = StringIO.StringIO()
+
+    try:
+        yield FILE_REGISTRY[filename]
+    finally:
+        handle = FILE_REGISTRY[filename]
+        FILE_REGISTRY[filename] = handle.getvalue()
+        handle.close()
+
+import spack.modules
+
+configuration_autoload_direct = {
+    'enable': ['tcl'],
+    'tcl': {
+        'all': {
+            'autoload': 'direct'
+        }
+    }
+}
+
+configuration_autoload_all = {
+    'enable': ['tcl'],
+    'tcl': {
+        'all': {
+            'autoload': 'all'
+        }
+    }
+}
+
+configuration_alter_environment = {
+    'enable': ['tcl'],
+    'tcl': {
+        'all': {
+            'filter': {'environment_blacklist': ['CMAKE_PREFIX_PATH']}
+        },
+        '=x86-linux': {
+            'environment': {'set': ['FOO,foo'], 'unset': ['BAR']}
+        }
+    }
+}
+
+configuration_blacklist = {
+    'enable': ['tcl'],
+    'tcl': {
+        'blacklist': ['callpath'],
+        'all': {
+            'autoload': 'direct'
+        }
+    }
+}
+
+from spack.test.mock_packages_test import MockPackagesTest
+
+
+class TclTests(MockPackagesTest):
+    def setUp(self):
+        super(TclTests, self).setUp()
+        self.configuration_obj = spack.modules.CONFIGURATION
+        spack.modules.open = mock_open
+        spack.modules.CONFIGURATION = None  # Make sure that a non-mocked configuration will trigger an error
+
+    def tearDown(self):
+        del spack.modules.open
+        spack.modules.CONFIGURATION = self.configuration_obj
+        super(TclTests, self).tearDown()
+
+    def get_modulefile_content(self, spec):
+        spec.concretize()
+        generator = spack.modules.TclModule(spec)
+        generator.write()
+        content = FILE_REGISTRY[generator.file_name].split('\n')
+        return content
+
+    def test_simple_case(self):
+        spack.modules.CONFIGURATION = configuration_autoload_direct
+        spec = spack.spec.Spec('mpich@3.0.4=x86-linux')
+        content = self.get_modulefile_content(spec)
+        self.assertTrue('module-whatis "mpich @3.0.4"' in content )
+        self.assertEqual(len([x for x in content if x.startswith('prepend-path CMAKE_PREFIX_PATH')]), 1)
+
+    def test_autoload(self):
+        spack.modules.CONFIGURATION = configuration_autoload_direct
+        spec = spack.spec.Spec('mpileaks=x86-linux')
+        content = self.get_modulefile_content(spec)
+        self.assertEqual(len([x for x in content if 'is-loaded' in x]), 2)
+        self.assertEqual(len([x for x in content if 'module load ' in x]), 2)
+
+        spack.modules.CONFIGURATION = configuration_autoload_all
+        spec = spack.spec.Spec('mpileaks=x86-linux')
+        content = self.get_modulefile_content(spec)
+        self.assertEqual(len([x for x in content if 'is-loaded' in x]), 5)
+        self.assertEqual(len([x for x in content if 'module load ' in x]), 5)
+
+    def test_alter_environment(self):
+        spack.modules.CONFIGURATION = configuration_alter_environment
+        spec = spack.spec.Spec('mpileaks=x86-linux')
+        content = self.get_modulefile_content(spec)
+        self.assertEqual(len([x for x in content if x.startswith('prepend-path CMAKE_PREFIX_PATH')]), 0)
+        self.assertEqual(len([x for x in content if 'setenv FOO "foo"' in x]), 1)
+        self.assertEqual(len([x for x in content if 'unsetenv BAR' in x]), 1)
+
+        spec = spack.spec.Spec('libdwarf=x64-linux')
+        content = self.get_modulefile_content(spec)
+        self.assertEqual(len([x for x in content if x.startswith('prepend-path CMAKE_PREFIX_PATH')]), 0)
+        self.assertEqual(len([x for x in content if 'setenv FOO "foo"' in x]), 0)
+        self.assertEqual(len([x for x in content if 'unsetenv BAR' in x]), 0)
+
+    def test_blacklist(self):
+        spack.modules.CONFIGURATION = configuration_blacklist
+        spec = spack.spec.Spec('mpileaks=x86-linux')
+        content = self.get_modulefile_content(spec)
+        self.assertEqual(len([x for x in content if 'is-loaded' in x]), 1)
+        self.assertEqual(len([x for x in content if 'module load ' in x]), 1)