diff --git a/ci/generate_test_data.sh b/ci/generate_test_data.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8e55efd8b8eecc82d65c8bc7ef32bcd788028d50
--- /dev/null
+++ b/ci/generate_test_data.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+cd test/data
+for filename in *.py; do
+  ./$filename
+done
+cd ../..
diff --git a/nifty/spaces/hp_space/hp_space.py b/nifty/spaces/hp_space/hp_space.py
index cf8ae570fe50da34617f98fc592a8b146e240758..e5012c60cda62ea1866602778d0a209173328a17 100644
--- a/nifty/spaces/hp_space/hp_space.py
+++ b/nifty/spaces/hp_space/hp_space.py
@@ -149,7 +149,7 @@ class HPSpace(Space):
                               dtype=self.dtype)
 
     def weight(self, x, power=1, axes=None, inplace=False):
-        weight = ((4*np.pi) / (12 * self.nside**2)) ** power
+        weight = ((4 * np.pi) / (12 * self.nside**2))**power
 
         if inplace:
             x *= weight
diff --git a/test/common.py b/test/common.py
index 5908aef4ccdeb35f33fe37bdd25675baa0059f82..cb711e8556ab7aebeb249e463d54f700327039f4 100644
--- a/test/common.py
+++ b/test/common.py
@@ -1,10 +1,39 @@
+import d2o
+import numpy as np
 from nose_parameterized import parameterized
+from nifty import RGSpace, LMSpace, HPSpace, GLSpace
+from string import strip
+
+
+def pretty_str(obj):
+    if type(obj) == list:
+        return " ".join(pretty_str(x) for x in obj)
+    if type(obj) == RGSpace:
+        return type(obj).__name__
+    elif type(obj) == LMSpace:
+        return type(obj).__name__
+    elif type(obj) == HPSpace:
+        return type(obj).__name__
+    elif type(obj) == GLSpace:
+        return type(obj).__name__
+    elif isinstance(obj, d2o.distributed_data_object):
+        return 'd2o'
+    elif type(obj) == dict:
+        if 'error' in obj:
+            return 'error_' + obj['error'].__name__
+        else:
+            return ''
+    elif type(obj) == np.ndarray:
+        return 'DATA'
+    else:
+        return str(obj)
 
 
 def custom_name_func(testcase_func, param_num, param):
     return "%s_%s" % (
         testcase_func.__name__,
-        parameterized.to_safe_name("_".join(str(x) for x in param.args)),
+        strip(parameterized.to_safe_name(
+            " ".join(pretty_str(x) for x in param.args)), '_')
     )
 
 
diff --git a/test/data/gen_gl_space_data.py b/test/data/gen_gl_space_data.py
new file mode 100644
index 0000000000000000000000000000000000000000..79efce8467a38d0938454f17d3a946305022d685
--- /dev/null
+++ b/test/data/gen_gl_space_data.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+import itertools
+import numpy as np
+import libsharp_wrapper_gl as gl
+
+# deterministic
+np.random.seed(42)
+
+
+def distance_array(nlat, nlon, latitude, longitude):
+    lat = latitude * (np.pi / (nlat - 1))
+    lon = longitude * (2 * np.pi / (nlon - 1))
+    # Vincenty formula: https://en.wikipedia.org/wiki/Great-circle_distance
+    # phi_1, lambda_1 = lat, lon
+    # phi_2, lambda_2 = 0
+    numerator = np.sqrt((np.cos(0) * np.sin(lon - 0))**2 +
+                        ((np.cos(lat) * np.sin(0)) -
+                         (np.sin(lat) * np.cos(0) * np.cos(lon - 0)))**2)
+    denominator = (
+        np.sin(lat) * np.sin(0)) + (np.cos(lat) * np.cos(0) * np.cos(lon - 0))
+    return np.arctan(numerator/denominator)
+
+
+# for GLSpace(nlat=2, nlon=3)
+da_0 = np.array(
+        [distance_array(2, 3, *divmod(idx, 3)) for idx in np.arange(6)])
+
+# for GLSpace(nlat=2, nlon=3)
+weight_0 = np.array(list(itertools.chain.from_iterable(
+    itertools.repeat(x, 3) for x in gl.vol(2))))
+w_0_x = np.random.rand(6)
+w_0_res = w_0_x * weight_0
+
+weight_1 = np.array(list(itertools.chain.from_iterable(
+    itertools.repeat(x, 3) for x in gl.vol(2))))
+weight_1 = weight_1.reshape([1, 1, 6])
+w_1_x = np.random.rand(32, 16, 6)
+w_1_res = w_1_x * weight_1
+
+# write everything to disk
+np.savez(
+    'gl_space', da_0=da_0, w_0_x=w_0_x, w_0_res=w_0_res, w_1_x=w_1_x,
+    w_1_res=w_1_res)
diff --git a/test/data/gen_hp_space_data.py b/test/data/gen_hp_space_data.py
new file mode 100755
index 0000000000000000000000000000000000000000..b3e6a804fd4122a91242a7a5cbb18bfde6002d19
--- /dev/null
+++ b/test/data/gen_hp_space_data.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+import numpy as np
+import healpy as hp
+
+# deterministic
+np.random.seed(42)
+
+# for HPSpace(nside=2)
+da_0 = np.array([np.arccos(hp.pix2vec(2, idx)[0]) for idx in np.arange(48)])
+
+# for HPSpace(nside=2)
+w_0_x = np.random.rand(48)
+w_0_res = w_0_x * ((4 * np.pi) / 48)
+w_1_res = w_0_x * (((4 * np.pi) / 48)**2)
+
+# write everything to disk
+np.savez('hp_space', da_0=da_0, w_0_x=w_0_x, w_0_res=w_0_res, w_1_x=w_0_x,
+         w_1_res=w_1_res)
diff --git a/test/data/gl_space.npz b/test/data/gl_space.npz
new file mode 100644
index 0000000000000000000000000000000000000000..dca748e000573e798df7083a536383a075385646
Binary files /dev/null and b/test/data/gl_space.npz differ
diff --git a/test/data/hp_space.npz b/test/data/hp_space.npz
new file mode 100644
index 0000000000000000000000000000000000000000..944116e089962472f11a6b9cc4739d2e0557228c
Binary files /dev/null and b/test/data/hp_space.npz differ
diff --git a/test/test_nifty.py b/test/test_nifty.py
deleted file mode 100644
index eb9109689e2ffa429939fec6d6939b062a9de8bc..0000000000000000000000000000000000000000
--- a/test/test_nifty.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import nifty as nt
-import numpy as np
-
-import unittest
-
-def weighted_np_transform(val, domain, codomain, axes=None):
-    if codomain.harmonic:
-        # correct for forward fft
-        val = domain.weight(val, power=1, axes=axes)
-        # Perform the transformation
-
-    Tval = np.fft.fftn(val, axes=axes)
-
-    if not codomain.harmonic:
-        # correct for inverse fft
-        Tval = codomain.weight(Tval, power=-1, axes=axes)
-
-    return Tval
-
-def test_simple_fft():
-    x = nt.RGSpace((16,))
-    x_p = nt.FFTOperator.get_default_codomain(x)
-    f = nt.Field((x, x), val=1)
-    val_p = np.ones((16,16))
-    fft = nt.FFTOperator(x)
-
-    assert np.allclose(
-        fft(f, spaces=(1,)).val,
-        weighted_np_transform(val_p, x, x_p, axes=(1,))
-    )
diff --git a/test/test_spaces/test_gl_space.py b/test/test_spaces/test_gl_space.py
new file mode 100644
index 0000000000000000000000000000000000000000..5ed5cf27caf2e065afda7ef80419c3118dd0ec28
--- /dev/null
+++ b/test/test_spaces/test_gl_space.py
@@ -0,0 +1,87 @@
+import unittest
+import numpy as np
+
+from numpy.testing import assert_, assert_equal, assert_raises,\
+        assert_almost_equal
+from nose.plugins.skip import SkipTest
+from nifty import GLSpace
+from nifty.config import dependency_injector as di
+from test.common import expand
+
+# [nlat, nlon, dtype, expected]
+CONSTRUCTOR_CONFIGS = [
+        [2, None, None, {
+            'nlat': 2,
+            'nlon': 3,
+            'harmonic': False,
+            'shape': (6,),
+            'dim': 6,
+            'total_volume': 4 * np.pi,
+            'dtype': np.dtype('float64')
+            }],
+        [1, None, None, {
+            'error': ValueError
+            }],
+        [5, None, None, {
+            'error': ValueError
+            }]
+    ]
+
+
+def get_distance_array_configs():
+    npzfile = np.load('test/data/gl_space.npz')
+    return [[2, None, None, npzfile['da_0']]]
+
+
+def get_weight_configs():
+    npzfile = np.load('test/data/gl_space.npz')
+    return [
+        [npzfile['w_0_x'], 1, None, False, npzfile['w_0_res']],
+        [npzfile['w_0_x'], 1, None, True, npzfile['w_0_res']],
+        [npzfile['w_1_x'], 1, None, True, npzfile['w_1_res']],
+        ]
+
+
+class GLSpaceInterfaceTests(unittest.TestCase):
+    @expand([['nlat', int],
+            ['nlon', int]])
+    def test_property_ret_type(self, attribute, expected_type):
+        try:
+            g = GLSpace()
+        except ImportError:
+            raise SkipTest
+        assert_(isinstance(getattr(g, attribute), expected_type))
+
+
+class GLSpaceFunctionalityTests(unittest.TestCase):
+    @expand(CONSTRUCTOR_CONFIGS)
+    def test_constructor(self, nlat, nlon, dtype, expected):
+        if 'libsharp_wrapper_gl' not in di:
+            raise SkipTest
+        else:
+            if 'error' in expected:
+                with assert_raises(expected['error']):
+                    GLSpace(nlat, nlon, dtype)
+            else:
+                g = GLSpace(nlat, nlon, dtype)
+                for key, value in expected.iteritems():
+                    assert_equal(getattr(g, key), value)
+
+    @expand(get_weight_configs())
+    def test_weight(self, x, power, axes, inplace, expected):
+        if 'libsharp_wrapper_gl' not in di:
+            raise SkipTest
+        else:
+            g = GLSpace(2)
+            res = g.weight(x, power, axes, inplace)
+            assert_almost_equal(res, expected)
+            if inplace:
+                assert_(x is res)
+
+    @expand(get_distance_array_configs())
+    def test_distance_array(self, nlat, nlon, dtype, expected):
+        if 'libsharp_wrapper_gl' not in di:
+            raise SkipTest
+        else:
+            g = GLSpace(nlat, nlon, dtype)
+            assert_almost_equal(g.get_distance_array('not').data, expected)
diff --git a/test/test_spaces/test_hp_space.py b/test/test_spaces/test_hp_space.py
new file mode 100644
index 0000000000000000000000000000000000000000..fa7555cb531e3433f7197bdd17a0b6862d7bd4f1
--- /dev/null
+++ b/test/test_spaces/test_hp_space.py
@@ -0,0 +1,85 @@
+import unittest
+import numpy as np
+
+from numpy.testing import assert_, assert_equal, assert_raises,\
+                          assert_almost_equal
+from nose.plugins.skip import SkipTest
+from nifty import HPSpace
+from nifty.config import dependency_injector as di
+from test.common import expand
+
+# [nside, dtype, expected]
+CONSTRUCTOR_CONFIGS = [
+        [2, None, {
+            'nside': 2,
+            'harmonic': False,
+            'shape': (48,),
+            'dim': 48,
+            'total_volume': 4 * np.pi,
+            'dtype': np.dtype('float64')
+            }],
+        [5, None, {
+            'error': ValueError
+            }],
+        [1, None, {
+            'error': ValueError
+            }]
+    ]
+
+
+def get_distance_array_configs():
+    npzfile = np.load('test/data/hp_space.npz')
+    return [[2, None, npzfile['da_0']]]
+
+
+def get_weight_configs():
+    npzfile = np.load('test/data/hp_space.npz')
+    return [
+        [npzfile['w_0_x'], 1, None, False, npzfile['w_0_res']],
+        [npzfile['w_0_x'], 1, None, True, npzfile['w_0_res']],
+        [npzfile['w_1_x'], 2, None, False, npzfile['w_1_res']],
+        ]
+
+
+class HPSpaceInterfaceTests(unittest.TestCase):
+    @expand([['nside', int]])
+    def test_property_ret_type(self, attribute, expected_type):
+        try:
+            x = HPSpace()
+        except ImportError:
+            raise SkipTest
+        assert_(isinstance(getattr(x, attribute), expected_type))
+
+
+class HPSpaceFunctionalityTests(unittest.TestCase):
+    @expand(CONSTRUCTOR_CONFIGS)
+    def test_constructor(self, nside, dtype, expected):
+        if 'healpy' not in di:
+            raise SkipTest
+        else:
+            if 'error' in expected:
+                with assert_raises(expected['error']):
+                    HPSpace(nside, dtype)
+            else:
+                h = HPSpace(nside, dtype)
+                for key, value in expected.iteritems():
+                    assert_equal(getattr(h, key), value)
+
+    @expand(get_weight_configs())
+    def test_weight(self, x, power, axes, inplace, expected):
+        if 'healpy' not in di:
+            raise SkipTest
+        else:
+            h = HPSpace(2)
+            res = h.weight(x, power, axes, inplace)
+            assert_almost_equal(res, expected)
+            if inplace:
+                assert_(x is res)
+
+    @expand(get_distance_array_configs())
+    def test_distance_array(self, nside, dtype, expected):
+        if 'healpy' not in di:
+            raise SkipTest
+        else:
+            h = HPSpace(nside, dtype)
+            assert_almost_equal(h.get_distance_array('not').data, expected)
diff --git a/test/test_spaces/test_interface.py b/test/test_spaces/test_interface.py
index fd6d7cbef90d3ddd5697bfbece623016b5c91f66..03be5c80edfda612e57d57030bee94b36d9006d4 100644
--- a/test/test_spaces/test_interface.py
+++ b/test/test_spaces/test_interface.py
@@ -2,20 +2,62 @@ import unittest
 import numpy as np
 
 from itertools import product
-from numpy.testing import assert_
+from d2o import distributed_data_object
+from types import LambdaType
+from numpy.testing import assert_, assert_raises, assert_equal
 from nifty import RGSpace, LMSpace, GLSpace, HPSpace
+from nifty.config import dependency_injector as di
 from test.common import expand
 
 
-SPACES = [RGSpace((4,)), LMSpace(5), GLSpace(4), HPSpace(4)]
+def generate_spaces():
+    spaces = [RGSpace(4)]
 
+    if 'healpy' in di:
+        spaces.append(HPSpace(4))
+    if 'libsharp_wrapper_gl' in di:
+        spaces.append(GLSpace(4))
+    if 'healpy' in di or 'libsharp_wrapper_gl' in di:
+        spaces.append(LMSpace(5))
 
-class SpaceInterfaceTestCase(unittest.TestCase):
-    @expand(product(SPACES, [['dtype', np.dtype],
-            ['harmonic', bool],
-            ['shape', tuple],
-            ['dim', int],
-            ['total_volume', np.float]]))
-    def test_return_types(self, space, attr_expected_type):
-        assert_(isinstance(getattr(
-                space, attr_expected_type[0]), attr_expected_type[1]))
+    return spaces
+
+
+class SpaceInterfaceTests(unittest.TestCase):
+    def test_dependency_handling(self):
+        if 'healpy' not in di and 'libsharp_wrapper_gl' not in di:
+            with assert_raises(ImportError):
+                LMSpace(5)
+        elif 'healpy' not in di:
+            with assert_raises(ImportError):
+                HPSpace(4)
+        elif 'libsharp_wrapper_gl' not in di:
+            with assert_raises(ImportError):
+                GLSpace(4)
+
+    @expand(product(generate_spaces(), [['dtype', np.dtype],
+                    ['harmonic', bool],
+                    ['shape', tuple],
+                    ['dim', int],
+                    ['total_volume', np.float]]))
+    def test_property_ret_type(self, space, attr_expected_type):
+        assert_(
+            isinstance(getattr(
+                space,
+                attr_expected_type[0]
+            ), attr_expected_type[1])
+        )
+
+    @expand(product(generate_spaces(), [
+        ['get_fft_smoothing_kernel_function', None, LambdaType],
+        ['get_fft_smoothing_kernel_function', 2.0, LambdaType],
+        ]))
+    def test_method_ret_type(self, space, method_expected_type):
+
+        assert_equal(
+            type(getattr(
+                space,
+                method_expected_type[0])(*method_expected_type[1:-1])
+            ),
+            method_expected_type[-1]
+        )
diff --git a/test/test_spaces/test_lm_space.py b/test/test_spaces/test_lm_space.py
new file mode 100644
index 0000000000000000000000000000000000000000..e4fa08597673aea51889ff689d7eb5957dcd27ad
--- /dev/null
+++ b/test/test_spaces/test_lm_space.py
@@ -0,0 +1,69 @@
+import unittest
+import numpy as np
+
+from numpy.testing import assert_, assert_equal, assert_raises
+from nose.plugins.skip import SkipTest
+from nifty import LMSpace
+from nifty.config import dependency_injector as di
+from test.common import expand
+
+# [lmax, dtype, expected]
+INIT_CONFIGS = [
+        [5, None, {
+            'lmax': 5,
+            'mmax': 5,
+            'shape': (36,),
+            'harmonic': True,
+            'dim': 36,
+            'total_volume': 36.0,
+            'dtype': np.dtype('float64')
+            }],
+        [7, np.dtype('float64'), {
+            'lmax': 7,
+            'mmax': 7,
+            'shape': (64,),
+            'harmonic': True,
+            'dim': 64,
+            'total_volume': 64.0,
+            'dtype': np.dtype('float64')
+            }],
+        [-1, None, {
+            'error': ValueError
+            }]
+    ]
+
+
+class LMSpaceIntefaceTests(unittest.TestCase):
+    @expand([['lmax', int],
+            ['mmax', int],
+            ['dim', int]])
+    def test_properties(self, attribute, expected_type):
+        try:
+            x = LMSpace(7)
+        except ImportError:
+            raise SkipTest
+        assert_(isinstance(getattr(x, attribute), expected_type))
+
+
+class LMSpaceFunctionalityTests(unittest.TestCase):
+    @expand(INIT_CONFIGS)
+    def test_constructor(self, lmax, dtype, expected):
+        if 'libsharp_wrapper_gl' not in di or 'healpy' not in di:
+            raise SkipTest
+        else:
+            if 'error' in expected:
+                with assert_raises(expected['error']):
+                    LMSpace(lmax, dtype)
+            else:
+                l = LMSpace(lmax, dtype)
+                for key, value in expected.iteritems():
+                    assert_equal(getattr(l, key), value)
+
+    def test_hermitian_decomposition(self):
+        pass
+
+    def test_weight(self):
+        pass
+
+    def test_distance_array(self):
+        pass
diff --git a/test/test_spaces/test_rg_space.py b/test/test_spaces/test_rg_space.py
new file mode 100644
index 0000000000000000000000000000000000000000..423d5c8e72ff5b95d10c74497fd4831c9455619a
--- /dev/null
+++ b/test/test_spaces/test_rg_space.py
@@ -0,0 +1,99 @@
+from __future__ import division
+
+import unittest
+import numpy as np
+
+from numpy.testing import assert_, assert_equal
+from nifty import RGSpace
+from test.common import expand
+
+# [shape, zerocenter, distances, harmonic, dtype, expected]
+INIT_CONFIGS = [
+        [(8,), False, None, False, None,
+            {
+                'shape': (8,),
+                'zerocenter': (False,),
+                'distances': (0.125,),
+                'harmonic': False,
+                'dtype': np.dtype('float'),
+                'dim': 8,
+                'total_volume': 1.0
+            }],
+        [(8,), True, None, False, None,
+            {
+                'shape': (8,),
+                'zerocenter': (True,),
+                'distances': (0.125,),
+                'harmonic': False,
+                'dtype': np.dtype('float'),
+                'dim': 8,
+                'total_volume': 1.0
+            }],
+        [(8,), False, None, True, None,
+            {
+                'shape': (8,),
+                'zerocenter': (False,),
+                'distances': (1.0,),
+                'harmonic': True,
+                'dtype': np.dtype('complex'),
+                'dim': 8,
+                'total_volume': 8.0
+            }],
+        [(8,), False, (12,), True, None,
+            {
+                'shape': (8,),
+                'zerocenter': (False,),
+                'distances': (12.0,),
+                'harmonic': True,
+                'dtype': np.dtype('complex'),
+                'dim': 8,
+                'total_volume': 96.0
+            }],
+        [(11, 11), (False, True), None, False, None,
+            {
+                'shape': (11, 11),
+                'zerocenter': (False, True),
+                'distances': (1/11, 1/11),
+                'harmonic': False,
+                'dtype': np.dtype('float'),
+                'dim': 121,
+                'total_volume': 1.0
+            }],
+        [(11, 11), True, (1.3, 1.3), True, None,
+            {
+                'shape': (11, 11),
+                'zerocenter': (True, True),
+                'distances': (1.3, 1.3),
+                'harmonic': True,
+                'dtype': np.dtype('complex'),
+                'dim': 121,
+                'total_volume': 204.49
+            }]
+
+    ]
+
+
+class RGSpaceInterfaceTests(unittest.TestCase):
+    @expand([['distances', tuple],
+            ['zerocenter', tuple]])
+    def test_properties(self, attribute, expected_type):
+        x = RGSpace()
+        assert_(isinstance(getattr(x, attribute), expected_type))
+
+
+class RGSpaceFunctionalityTests(unittest.TestCase):
+    @expand(INIT_CONFIGS)
+    def test_constructor(self, shape, zerocenter, distances,
+                         harmonic, dtype, expected):
+        x = RGSpace(shape, zerocenter, distances, harmonic, dtype)
+        for key, value in expected.iteritems():
+            assert_equal(getattr(x, key), value)
+
+    def test_hermitian_decomposition(self):
+        pass
+
+    def test_weight(self):
+        pass
+
+    def test_distance_array(self):
+        pass