diff --git a/Gruntfile.js b/Gruntfile.js
index a09c9420416f71ff2b50d2716758b93723d90e6b..0a4a8615a0225ada1f743b0e11c128426679a55f 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -6,16 +6,12 @@ module.exports = function (grunt) {
   config.tasks.forEach(grunt.loadNpmTasks);
   grunt.initConfig(config);
 
-  grunt.registerTask('lint', [
-    'flake8'
-  ]);
-
   grunt.registerTask('test', [
     'nose:main'
   ]);
 
   grunt.registerTask('default', [
-    'lint',
+    'flake8',
     'jshint',
     'test',
     'watch'
diff --git a/geomagio/iaga2002/MagWebFactory.py b/geomagio/iaga2002/MagWebFactory.py
index 11adb2487760f55c0ead0c6efb2a24fd4ac9b140..6f7f6375504b9900860ef21978628e1fd34883de 100644
--- a/geomagio/iaga2002/MagWebFactory.py
+++ b/geomagio/iaga2002/MagWebFactory.py
@@ -19,3 +19,6 @@ class MagWebFactory(IAGA2002Factory):
         IAGA2002Factory.__init__(self, MAGWEB_URL_TEMPLATE,
             observatory=observatory, channels=channels, type=type,
             interval=interval)
+
+
+MagWebFactory.MAGWEB_URL_TEMPLATE = MAGWEB_URL_TEMPLATE
diff --git a/gruntconfig/config.js b/gruntconfig/config.js
index 8eb077ad7d1229fe3591db7fc570d47120ddc6ae..d14a9eff03ea528062df57f3babdb6b5d3dded97 100644
--- a/gruntconfig/config.js
+++ b/gruntconfig/config.js
@@ -1,4 +1,6 @@
 'use strict';
 
 module.exports = {
+  bin: 'bin',
+  test: 'test'
 };
diff --git a/gruntconfig/flake8.js b/gruntconfig/flake8.js
index 2c0075c8b636dcf1a508152b0b52f873e4d6f22b..38805efbd05aa1b1c2d7db5355e8bdaace30cfbc 100644
--- a/gruntconfig/flake8.js
+++ b/gruntconfig/flake8.js
@@ -1,11 +1,22 @@
 'use strict';
 
 module.exports = {
-  options: {
-    ignore: ['E122', 'E126', 'E127', 'E128', 'E131']
+  src: {
+    options: {
+      ignore: ['E122', 'E126', 'E127', 'E128', 'E131']
+    },
+    src: [
+      'bin/*.py',
+      'geomagio/**/*.py'
+    ]
   },
-  src: [
-    'geomagio/**/*.py',
-    'bin/*.py'
-  ]
+
+  test: {
+    options: {
+      ignore: ['E122', 'E126', 'E127', 'E128', 'E131']
+    },
+    src: [
+      'test/**/*.py'
+    ]
+  }
 };
diff --git a/gruntconfig/nose.js b/gruntconfig/nose.js
index bb8b1799d3b1c05225b064cb1b85c87d0000e6ac..33f27c51b552e47d665ba5d7d26fefda1384393e 100644
--- a/gruntconfig/nose.js
+++ b/gruntconfig/nose.js
@@ -4,7 +4,8 @@ module.exports = {
   main: {
     options: {
       match: '[Tt]est',
-      verbose: true
+      verbose: true,
+      include: 'test/*/*.py'
     }
   }
 };
diff --git a/gruntconfig/watch.js b/gruntconfig/watch.js
index 991036642f0fc9ed3948c6bcbe1b4272ee407a4e..5d360cb4a2eac8f61c89387cdd23889ac12c19e6 100644
--- a/gruntconfig/watch.js
+++ b/gruntconfig/watch.js
@@ -1,12 +1,32 @@
 'use strict';
 
 module.exports = {
+  gruntfile: {
+    files: [
+      'Gruntfile.js',
+      'gruntconfig/**/*.js'
+    ],
+    tasks: [
+      'jshint:gruntfile'
+    ]
+  },
   scripts: {
-    files: ['geomagio/**/*.py', 'bin/**/*.py'],
-    tasks: ['lint', 'test']
+    files: [
+      'bin/**/*.py',
+      'geomagio/**/*.py'
+    ],
+    tasks: [
+      'flake8:src',
+      'test'
+    ]
   },
-  gruntfile: {
-    files: ['Gruntfile.js', 'gruntconfig/**/*.js'],
-    tasks: ['jshint:gruntfile']
+  tests: {
+    files: [
+      'test/**/*.py'
+    ],
+    tasks: [
+      'flake8:test',
+      'test'
+    ]
   }
 };
diff --git a/geomagio/Algorithm_test.py b/test/Algorithm_test.py
similarity index 86%
rename from geomagio/Algorithm_test.py
rename to test/Algorithm_test.py
index b56af194b6f699d882e45062041b54a9cbe44778..cf4d2e3cbf249b8a50b4b75068abcb28c881a9ae 100644
--- a/geomagio/Algorithm_test.py
+++ b/test/Algorithm_test.py
@@ -2,11 +2,11 @@
 from obspy.core.stream import Stream
 from nose.tools import assert_equals
 from nose.tools import assert_is_instance
-from Algorithm import Algorithm
+from geomagio import Algorithm
 
 
 def test_algorithm_process():
-    """geomag.Algorithmtest.test_algorithm_process()
+    """Algorithm_test.test_algorithm_process()
 
     confirms that algorithm.process returns an obspy.core.stream object
     """
@@ -17,7 +17,7 @@ def test_algorithm_process():
 
 
 def test_algorithm_channels():
-    """geomag.Algorithmtest.test_algorithm_channels()
+    """Algorithm_test.test_algorithm_channels()
 
     confirms that algorithm.get_input_channels returns the correct channels
     confirms that algorithm.get_output_channels returns the correct channels
diff --git a/geomagio/ChannelConverter_test.py b/test/ChannelConverter_test.py
similarity index 93%
rename from geomagio/ChannelConverter_test.py
rename to test/ChannelConverter_test.py
index 0c33b4b04b6f5cec4ad957a58eb36b412f204694..aa33c9f3042b1bcebbce2457e0bd46065c25e0c7 100644
--- a/geomagio/ChannelConverter_test.py
+++ b/test/ChannelConverter_test.py
@@ -2,7 +2,7 @@
 
 import numpy
 import math
-import ChannelConverter as channel
+import geomagio.ChannelConverter as channel
 
 assert_almost_equal = numpy.testing.assert_almost_equal
 cos = math.cos
@@ -46,7 +46,7 @@ class ChannelConverterTest:
     """
 
     def test_get_computed_f_using_sqaures(self):
-        """geomag.ChannelConverterTest.test_get_computed_f_using_sqaures
+        """ChannelConverter_test.test_get_computed_f_using_sqaures
 
         Computed f is the combination of the 3 vector components from
             either the geographic coordinate system (X,Y,Z), or the observatory
@@ -61,7 +61,7 @@ class ChannelConverterTest:
                 True)
 
     def test_get_geo_from_obs(self):
-        """geomag.ChannelConverterTest.test_get_geo_from_obs()
+        """ChannelConverter_test.test_get_geo_from_obs()
 
         The observatory component ``h`` and ``e`` combined with the declination
         basline angle ``d0`` converts to the geographic north component
@@ -114,7 +114,7 @@ class ChannelConverterTest:
                 'Expect Y to equal sin(60).', True)
 
     def test_get_geo_from_mag(self):
-        """geomag.ChannelConverterTest.test_get_geo_from_mag()
+        """ChannelConverter_test.test_get_geo_from_mag()
 
         ``X``, ``Y`` are the north component, and east component of the
         vector ``H`` which is an angle ``D`` from north.
@@ -131,7 +131,7 @@ class ChannelConverterTest:
                 'Expect Y to be sin(30).', True)
 
     def test_get_geo_x_from_mag(self):
-        """geomag.ChannelConverterTest.test_get_geo_x_from_mag()
+        """ChannelConverter_test.test_get_geo_x_from_mag()
 
         ``X`` is the north component of the vector ``H``, which is an angle
         ``D`` from north.
@@ -152,7 +152,7 @@ class ChannelConverterTest:
                 'Expect X to equal cos(30).', True)
 
     def test_get_geo_y_from_mag(self):
-        """geomag.ChannelConverterTest.test_get_geo_y_from_mag()
+        """ChannelConverter_test.test_get_geo_y_from_mag()
 
         ``Y`` is the north component of the vector ``H``, which is an angle
         ``D`` from north.
@@ -174,7 +174,7 @@ class ChannelConverterTest:
                 'Expect Y to be 2sin(30).', True)
 
     def test_get_mag_from_obs(self):
-        """geomag.ChannelConverterTest.test_get_geo_y_from_obs()
+        """ChannelConverter_test.test_get_geo_y_from_obs()
 
         ``h``, ``e`` are the primary and secondary axis of the ``H``
         vector in the horizontal plane of the magnetic field.  ``d0``
@@ -193,7 +193,7 @@ class ChannelConverterTest:
         assert_almost_equal(D, 45 * D2R, 8, 'Expect D to be 45.', True)
 
     def test_get_mag_from_geo(self):
-        """geomag.ChannelConverterTest.test_get_geo_y_from_obs()
+        """ChannelConverter_test.test_get_geo_y_from_obs()
 
         ``X`` and ``Y are the north and east components of the ``H`` total
         magnetic field horizontal vector.  ``D`` is the angle from north of
@@ -209,7 +209,7 @@ class ChannelConverterTest:
         assert_almost_equal(D, 30 * D2R, 8, 'Expect D to be 30.', True)
 
     def test_get_mag_d_from_obs(self):
-        """geomag.ChannelConverterTest.test_get_mag_d_from_obs()
+        """ChannelConverter_test.test_get_mag_d_from_obs()
 
         The observatory components ``h`` and ``e`` form an angle (d) with
         the horizontal magnetic vector. Adding d to the observatory
@@ -263,7 +263,7 @@ class ChannelConverterTest:
                 'Expect D to equal -60 degrees', True)
 
     def test_get_mag_d_from_geo(self):
-        """geomag.ChannelConverterTest.test_get_mag_d_from_geo()
+        """ChannelConverter_test.test_get_mag_d_from_geo()
 
         Angle ``D`` from north of the horizontal vector can be calculated
         using the arctan of the ``X`` and ``Y`` components.
@@ -290,7 +290,7 @@ class ChannelConverterTest:
                 'Expect D to equal -30 degrees', True)
 
     def test_get_mag_h_from_obs(self):
-        """geomag.ChannelConverterTest.test_get_mag_h_from_obs()
+        """ChannelConverter_test.test_get_mag_h_from_obs()
 
         ``h`` and ``e`` are the primary and secondary components of the ``H``
         vector.
@@ -303,7 +303,7 @@ class ChannelConverterTest:
         assert_almost_equal(H, 5, 8, 'Expect H to be 5.', True)
 
     def test_get_mag_h_from_geo(self):
-        """geomag.ChannelConverterTest.test_get_mag_d_from_geo()
+        """ChannelConverter_test.test_get_mag_d_from_geo()
 
         ``X`` and ``Y`` are the north and east components of the horizontal
         magnetic field vector ``H``
@@ -316,7 +316,7 @@ class ChannelConverterTest:
         assert_almost_equal(H, 5, 8, 'Expect H to be 5.', True)
 
     def test_get_obs_from_geo(self):
-        """geomag.io.channelTest.test_get_obs_from_geo()
+        """ChannelConverter_test.test_get_obs_from_geo()
 
         The geographic north and east components ``X`` and ``Y`` of the
         magnetic field vector H, combined with the declination baseline angle
@@ -368,7 +368,7 @@ class ChannelConverterTest:
         assert_almost_equal(d, 30 * D2R, 8, 'Expect d to be 30 degrees.', True)
 
     def test_get_obs_from_mag(self):
-        """geomag.ChannelConverterTest.test_get_obs_from_mag()
+        """ChannelConverter_test.test_get_obs_from_mag()
 
         Call the get_obs_from_mag function, using trig identities too
         test correctness, including d0. Which should test most of the d0
@@ -384,7 +384,7 @@ class ChannelConverterTest:
                 'Expect e to be -cos(45).', True)
 
     def test_get_obs_d_from_obs(self):
-        """geomag.ChannelConverterTest.test_get_obs_d_from_obs()
+        """ChannelConverter_test.test_get_obs_d_from_obs()
 
         ``d`` is the angle formed by the observatory components ``h`` and
         ``e`` the primary and secondary axis of the horizontal magnetic
@@ -405,7 +405,7 @@ class ChannelConverterTest:
                 'Expect d to be 30 degrees.', True)
 
     def test_get_obs_d_from_mag_d(self):
-        """geomag.ChannelConverterTest.test_get_obs_d_from_mag()
+        """ChannelConverter_test.test_get_obs_d_from_mag()
 
         The observatory declination angle ``d`` is the difference between
         the magnetic north declination ``D`` and the observatory baseline
@@ -438,7 +438,7 @@ class ChannelConverterTest:
         assert_almost_equal(d, 60 * D2R, 8, 'Expect d to be 60 degrees.', True)
 
     def test_get_obs_e_from_mag(self):
-        """geomag.ChannelConverterTest.test_get_obs_e_from_mag()
+        """ChannelConverter_test.test_get_obs_e_from_mag()
 
         ``e`` is the secondary axis or 'east' component of the observatory
         reference frame. Using the difference between the magnetic declination
@@ -469,7 +469,7 @@ class ChannelConverterTest:
                 'Expect e to be sin(30)', True)
 
     def test_get_obs_e_from_obs(self):
-        """geomag.ChannelConverterTest.test_get_obs_e_from_obs()
+        """ChannelConverter_test.test_get_obs_e_from_obs()
 
         ``e`` is the seconday (east) component of the observatory vector ``h``.
         ``e`` is calculated using ``h`` * tan(``d``) where ``d`` is the
@@ -485,7 +485,7 @@ class ChannelConverterTest:
                 'Expect e to be 2 * tan(30).', True)
 
     def test_get_obs_h_from_mag(self):
-        """geomag.ChannelConverterTest.test_get_obs_h_from_mag()
+        """ChannelConverter_test.test_get_obs_h_from_mag()
 
         The observatories horizontal magnetic vector ``h`` is caculated from
         the magnetic north vector ``H`` and the observatory declination angle
@@ -509,7 +509,7 @@ class ChannelConverterTest:
                 'Expect h to be cos(15)', True)
 
     def test_geo_to_obs_to_geo(self):
-        """geomag.ChannelConverterTest.test_geo_to_obs_to_geo()
+        """ChannelConverter_test.test_geo_to_obs_to_geo()
 
         Call get_geo_from_obs using values from Boulder, then call
             get_obs_from_geo using the X,Y values returned from
@@ -526,7 +526,7 @@ class ChannelConverterTest:
         assert_almost_equal(e, -74.16, 8, 'Expect e to = -74.16', True)
 
     def test_get_radians_from_minutes(self):
-        """geomag.ChannelConverterTest.test_get_radian_from_decimal()
+        """ChannelConverter_test.test_get_radian_from_decimal()
 
         Call get_radian_from_decimal using 45 degrees, expect r to be pi/4
         """
@@ -536,7 +536,7 @@ class ChannelConverterTest:
                 'Expect radians to be pi/4', True)
 
     def test_get_minutes_from_radians(self):
-        """geomag.ChannelConverterTest.test_get_decimal_from_radian()
+        """ChannelConverter_test.test_get_decimal_from_radian()
 
         Call get_decimal_from_radian using pi/4, expect d to be 45
         """
diff --git a/geomagio/Controller_test.py b/test/Controller_test.py
similarity index 74%
rename from geomagio/Controller_test.py
rename to test/Controller_test.py
index 2ecdb97029254e71627a891b80d5da6e150b4bf8..e407a9ecaa9463508a72b8cdea09fc083842e542 100644
--- a/geomagio/Controller_test.py
+++ b/test/Controller_test.py
@@ -1,12 +1,10 @@
 #! /usr/bin/env python
-from geomagio.TimeseriesFactory import TimeseriesFactory
-from geomagio.Algorithm import Algorithm
-from geomagio.Controller import Controller
+from geomagio import Algorithm, Controller, TimeseriesFactory
 from nose.tools import assert_is_instance
 
 
 def test_controller():
-    """geomagio.Controllertest.test_controller()
+    """Controller_test.test_controller()
 
   instantiate the controller, make certain the factories and algorithms
   are set
diff --git a/geomagio/ObservatoryMetadata_test.py b/test/ObservatoryMetadata_test.py
similarity index 95%
rename from geomagio/ObservatoryMetadata_test.py
rename to test/ObservatoryMetadata_test.py
index fe0ffa6e3dbb8db92412f34ecc869baa84f61672..09f12d5865815f7de2018cb5605461f224289547 100644
--- a/geomagio/ObservatoryMetadata_test.py
+++ b/test/ObservatoryMetadata_test.py
@@ -1,6 +1,6 @@
 """Tests for ObservatoryMetadata.py"""
 
-from ObservatoryMetadata import ObservatoryMetadata
+from geomagio import ObservatoryMetadata
 from nose.tools import assert_equals
 import obspy.core
 
@@ -46,7 +46,7 @@ DATA_INTERVAL_TYPE = {
 
 
 def test_set_metadata():
-    """geomagio.edge.ObservatoryMetadata_test.test_set_metadata()
+    """ObservatoryMetadata_test.test_set_metadata()
     """
     # Test set_metadata by passing in a stats class, and looking
     # for parameters that are both passed in, and aquired from the default
diff --git a/geomagio/StreamConverter_test.py b/test/StreamConverter_test.py
similarity index 96%
rename from geomagio/StreamConverter_test.py
rename to test/StreamConverter_test.py
index 54699637e84b1a8ca8491f20b4fcbc236c0dfc87..c072e3b0ac44c3e8ab0b96ce7b99d97ce97ccad1 100644
--- a/geomagio/StreamConverter_test.py
+++ b/test/StreamConverter_test.py
@@ -11,8 +11,7 @@ For more info on the components see the Notes in ChannelConverterTest.py.
 """
 import obspy.core
 import numpy
-import StreamConverter
-import ChannelConverter
+from geomagio import ChannelConverter, StreamConverter
 
 assert_almost_equal = numpy.testing.assert_almost_equal
 
@@ -25,7 +24,7 @@ STARTTIME = obspy.core.UTCDateTime('2014-11-01')
 
 
 def test_get_geo_from_mag():
-    """geomag.StreamConverter_test.test_get_geo_from_mag()
+    """StreamConverter_test.test_get_geo_from_mag()
 
     The magnetic north stream containing the traces ''h'', ''d'', ''z'', and
     ''f'' converts to the geographics stream containing the traces ''x'',
@@ -51,7 +50,7 @@ def test_get_geo_from_mag():
 
 
 def test_get_geo_from_obs():
-    """geomag.StreamConverter_test.test_get_geo_from_obs()
+    """StreamConverter_test.test_get_geo_from_obs()
 
     The observatory stream containing the observatory traces
     ''h'', ''d'' or ''e'', ''z'', and ''f'' converts to the geographic
@@ -92,7 +91,7 @@ def test_get_geo_from_obs():
 
 
 def test_get_mag_from_geo():
-    """geomag.StreamConverter_test.test_get_mag_from_geo()
+    """StreamConverter_test.test_get_mag_from_geo()
 
     The geographic stream containing the traces ''x'', ''y'', ''z'', and
         ''f'' converts to the magnetic stream containing the traces
@@ -118,7 +117,7 @@ def test_get_mag_from_geo():
 
 
 def test_get_mag_from_obs():
-    """geomag.StreamConverter_test.test_get_mag_from_obs()
+    """StreamConverter_test.test_get_mag_from_obs()
 
     The observatory stream containing the traces ''h'', ''e'' or ''d'',
         ''z'' and ''f''
@@ -143,7 +142,7 @@ def test_get_mag_from_obs():
 
 
 def test_get_obs_from_geo():
-    """geomag.StreamConverter_test.test_get_obs_from_geo()
+    """StreamConverter_test.test_get_obs_from_geo()
 
     The geographic stream containing the traces ''x'', ''y'', ''z'', and
     ''f'' converts to the observatory stream containing the traces
@@ -173,7 +172,7 @@ def test_get_obs_from_geo():
 
 
 def test_get_obs_from_mag():
-    """geomag.StreamConverter_test.test_get_obs_from_mag()
+    """StreamConverter_test.test_get_obs_from_mag()
 
     The magnetic stream containing the traces ''h'', ''d'', ''z'', and ''f''
         converts to the observatory stream containing the traces
@@ -203,7 +202,7 @@ def test_get_obs_from_mag():
 
 
 def test_get_obs_from_obs():
-    """geomag.StreamConverter_test.test_get_obs_from_obs()
+    """StreamConverter_test.test_get_obs_from_obs()
 
     The observatory stream can contain either ''d'' or ''e'' depending
     on it's source. get_obs_from_obs will return either or both as part
@@ -239,7 +238,8 @@ def test_get_obs_from_obs():
 
 
 def test_verification_data():
-    """
+    """StreamConverter_test.test_verification_data()
+
     This is a verification test of data done with different
     converters,  to see if the same result is returned.
     Since the small angle approximation was used in the other
diff --git a/geomagio/TimeseriesUtility_test.py b/test/TimeseriesUtility_test.py
similarity index 93%
rename from geomagio/TimeseriesUtility_test.py
rename to test/TimeseriesUtility_test.py
index 5f5ea092a89616b7154f7a8af9a2370b6bef548c..a64c92ef2704c651eab305537f3da707abef8f33 100644
--- a/geomagio/TimeseriesUtility_test.py
+++ b/test/TimeseriesUtility_test.py
@@ -2,12 +2,12 @@
 from nose.tools import assert_equals
 from StreamConverter_test import __create_trace
 import numpy
-import TimeseriesUtility
+from geomagio import TimeseriesUtility
 from obspy.core import Stream, UTCDateTime
 
 
 def test_get_stream_gaps():
-    """geomag.TimeseriesUtility_test.test_get_stream_gaps
+    """TimeseriesUtility_test.test_get_stream_gaps()
 
     confirms that gaps are found in a stream
     """
@@ -36,7 +36,7 @@ def test_get_stream_gaps():
 
 
 def test_get_trace_gaps():
-    """geomag.TimeseriesUtility_test.test_get_trace_gaps
+    """TimeseriesUtility_test.test_get_trace_gaps()
 
     confirm that gaps are found in a trace
     """
@@ -54,7 +54,7 @@ def test_get_trace_gaps():
 
 
 def test_get_merged_gaps():
-    """geomag.TimeseriesUtility_test.test_get_merged_gaps
+    """TimeseriesUtility_test.test_get_merged_gaps()
 
     confirm that gaps are merged
     """
diff --git a/geomagio/XYZAlgorithm_test.py b/test/XYZAlgorithm_test.py
similarity index 87%
rename from geomagio/XYZAlgorithm_test.py
rename to test/XYZAlgorithm_test.py
index 415ba4fc5a9ab7779ba406d3b0d5444e0dfe5dc7..b84f87198174e311879f46789c64a792d1dbdbbb 100644
--- a/geomagio/XYZAlgorithm_test.py
+++ b/test/XYZAlgorithm_test.py
@@ -2,12 +2,12 @@
 from obspy.core.stream import Stream
 from nose.tools import assert_equals
 from nose.tools import assert_is
-from XYZAlgorithm import XYZAlgorithm
+from geomagio import XYZAlgorithm
 from StreamConverter_test import __create_trace
 
 
 def test_xyzalgorithm_process():
-    """geomag.XYZAlgorithmtest.test_algorithm_process()
+    """XYZAlgorithm_test.test_xyzalgorithm_process()
 
     confirms that a converted stream contains the correct outputchannels.
     """
@@ -22,7 +22,7 @@ def test_xyzalgorithm_process():
 
 
 def test_xyzalgorithm_channels():
-    """geomag.XYZAlgorithmtest.test_algorithm_process()
+    """XYZAlgorithm_test.test_xyzalgorithm_channels()
 
     confirms that the input/output channels are correct for the given
     informat/outformat during instantiation.
diff --git a/geomagio/edge/EdgeFactory_test.py b/test/edge_test/EdgeFactory_test.py
similarity index 86%
rename from geomagio/edge/EdgeFactory_test.py
rename to test/edge_test/EdgeFactory_test.py
index 82d55859bcda32b0811bd5c831d55240af6a8016..a15b0de38889812ccbefc5129f06611729200f55 100644
--- a/geomagio/edge/EdgeFactory_test.py
+++ b/test/edge_test/EdgeFactory_test.py
@@ -3,26 +3,26 @@
 from obspy.core.utcdatetime import UTCDateTime
 from obspy.core.stream import Stream
 from obspy.core.trace import Trace
-from EdgeFactory import EdgeFactory
+from geomagio.edge import EdgeFactory
 from nose.tools import assert_equals
 
 
 def test__get_edge_network():
-    """geomagio.edge.EdgeFactory_test.test__get_edge_network()
+    """edge_test.EdgeFactory_test.test__get_edge_network()
     """
     # _get_edge_network should always return NT for use by USGS geomag
     assert_equals(EdgeFactory()._get_edge_network(' ', ' ', ' ', ' '), 'NT')
 
 
 def test__get_edge_station():
-    """geomagio.edge.EdgeFactory_test.test__get_edge_station()
+    """edge_test.EdgeFactory_test.test__get_edge_station()
     """
     # _get_edge_station will return the observatory code passed in.
     assert_equals(EdgeFactory()._get_edge_station('BOU', ' ', ' ', ' '), 'BOU')
 
 
 def test__get_edge_channel():
-    """geomagio.edge.EdgeFactory_test.test__get_edge_channel()
+    """edge_test.EdgeFactory_test.test__get_edge_channel()
     """
     # Call private function _get_edge_channel, make certain
     # it gets back the appropriate 2 character code.
@@ -39,7 +39,7 @@ def test__get_edge_channel():
 
 
 def test__get_edge_location():
-    """geomagio.edge.EdgeFactory_test.test__get_edge_location()
+    """edge_test.EdgeFactory_test.test__get_edge_location()
     """
     # Call _get_edge_location, make certain it returns the correct edge
     # location code.
@@ -52,7 +52,7 @@ def test__get_edge_location():
 
 
 def test__get_interval_code():
-    """geomagio.edge.EdgeFactory_test.test__get_interval_code()
+    """edge_test.EdgeFactory_test.test__get_interval_code()
     """
     assert_equals(EdgeFactory()._get_interval_code('daily'), 'D')
     assert_equals(EdgeFactory()._get_interval_code('hourly'), 'H')
@@ -61,7 +61,7 @@ def test__get_interval_code():
 
 
 def test__set_metadata():
-    """geomagio.edge.EdgeFactory_test.test__set_metadata()
+    """edge_test.EdgeFactory_test.test__set_metadata()
     """
     # Call _set_metadata with 2 traces,  and make certain the stats get
     # set for both traces.
@@ -75,7 +75,7 @@ def test__set_metadata():
 
 # def test_get_timeseries():
 def dont_get_timeseries():
-    """geomagio.edge.EdgeFactory_test.test_get_timeseries()"""
+    """edge_test.EdgeFactory_test.test_get_timeseries()"""
     # Call get_timeseries, and test stats for comfirmation that it came back.
     # TODO, need to pass in host and port from a config file, or manually
     #   change for a single test.
diff --git a/geomagio/iaga2002/IAGA2002Factory_test.py b/test/iaga2002_test/IAGA2002Factory_test.py
similarity index 87%
rename from geomagio/iaga2002/IAGA2002Factory_test.py
rename to test/iaga2002_test/IAGA2002Factory_test.py
index c40d9f6c71766e768c01ae73c893b4e54ae9739f..3d835edc6c5eb12c6e7a393a306770d48eb7ec23 100644
--- a/geomagio/iaga2002/IAGA2002Factory_test.py
+++ b/test/iaga2002_test/IAGA2002Factory_test.py
@@ -1,12 +1,12 @@
 """Tests for IAGA2002Factory."""
 
-from IAGA2002Factory import IAGA2002Factory
+from geomagio.iaga2002 import IAGA2002Factory
 from obspy.core.utcdatetime import UTCDateTime
 from nose.tools import assert_equals
 
 
 def test__get_days():
-    """geomagio.iaga2002.IAGA2002Factory_test.test__get_days()
+    """iaga2002_test.IAGA2002Factory_test.test__get_days()
 
     Call the _get_days method with starttime and endtime separated by more
     than one day.
diff --git a/geomagio/iaga2002/IAGA2002Parser_test.py b/test/iaga2002_test/IAGA2002Parser_test.py
similarity index 92%
rename from geomagio/iaga2002/IAGA2002Parser_test.py
rename to test/iaga2002_test/IAGA2002Parser_test.py
index 841994280d3d32e18c760efe7c33d8929a41af3b..52172e6f462fe856529226b7630c37c7c5faa6e0 100644
--- a/geomagio/iaga2002/IAGA2002Parser_test.py
+++ b/test/iaga2002_test/IAGA2002Parser_test.py
@@ -1,7 +1,7 @@
 """Tests for the IAGA2002 Parser class."""
 
 from nose.tools import assert_equals
-from IAGA2002Parser import IAGA2002Parser
+from geomagio.iaga2002 import IAGA2002Parser
 
 
 IAGA2002_EXAMPLE = \
@@ -43,7 +43,7 @@ DATE       TIME         DOY     BDTH      BDTD      BDTZ      BDTF   |
 
 
 def test__merge_comments():
-    """geomagio.iaga2002.IAGA2002Parser_test.test_merge_comments()
+    """iaga2002_test.IAGA2002Parser_test.test_merge_comments()
 
     Call the _merge_comments method with 3 lines,
     only the middle line ending in a period.
@@ -56,7 +56,7 @@ def test__merge_comments():
 
 
 def test__parse_header():
-    """geomagio.iaga2002.IAGA2002Parser_test.test_parse_header()
+    """iaga2002_test.IAGA2002Parser_test.test_parse_header()
 
     Call the _parse_header method with a header.
     Verify the header name and value are split at the correct column.
@@ -68,7 +68,7 @@ def test__parse_header():
 
 
 def test__parse_comment():
-    """geomagio.iaga2002.IAGA2002Parser_test.test_parse_header()
+    """iaga2002_test.IAGA2002Parser_test.test_parse_header()
 
     Call the _parse_comment method with a comment.
     Verify the comment delimiters are removed.
@@ -82,7 +82,7 @@ def test__parse_comment():
 
 
 def test__parse_channels():
-    """geomagio.iaga2002.IAGA2002Parser_test.test_parse_channels()
+    """iaga2002_test.IAGA2002Parser_test.test_parse_channels()
 
     Call the _parse_header method with an IAGA CODE header, then call
     the _parse_channels method with a channels header line.
@@ -97,7 +97,7 @@ def test__parse_channels():
 
 
 def test_parse_decbas():
-    """geomagio.iaga2002.IAGA2002Parser_test.test_parse_decbas()
+    """iaga2002_test.IAGA2002Parser_test.test_parse_decbas()
 
     Call the parse method with a portion of an IAGA 2002 File,
     which contains a DECBAS header comment.
diff --git a/geomagio/iaga2002/MagWebFactory_test.py b/test/iaga2002_test/MagWebFactory_test.py
similarity index 66%
rename from geomagio/iaga2002/MagWebFactory_test.py
rename to test/iaga2002_test/MagWebFactory_test.py
index 12058954e8febc32b58e37f0cafa74a063fb9165..e520ee93ae9b7e7feb9f932c5bd2fb16b06682d5 100644
--- a/geomagio/iaga2002/MagWebFactory_test.py
+++ b/test/iaga2002_test/MagWebFactory_test.py
@@ -1,13 +1,13 @@
 """Tests for MagWebFactory."""
 
-import MagWebFactory
+from geomagio.iaga2002 import MagWebFactory
 from nose.tools import assert_equals
 
 
 def test_init():
-    """geomagio.iaga2002.MagWebFactory_test.test_init()
+    """iaga2002_test.MagWebFactory_test.test_init()
 
     Verify MagWebFactory calls parent constructor with MAGWEB_URL_TEMPLATE.
     """
-    factory = MagWebFactory.MagWebFactory()
+    factory = MagWebFactory()
     assert_equals(factory.urlTemplate, MagWebFactory.MAGWEB_URL_TEMPLATE)
diff --git a/geomagio/imfv283/IMFV283Parser_test.py b/test/imfv283_test/IMFV283Parser_test.py
similarity index 86%
rename from geomagio/imfv283/IMFV283Parser_test.py
rename to test/imfv283_test/IMFV283Parser_test.py
index 8932c8f4225f40c2da3527039dfc87bfc01d5727..3c79f9a2b559fe4ab21cb2c561de04c4707651fb 100644
--- a/geomagio/imfv283/IMFV283Parser_test.py
+++ b/test/imfv283_test/IMFV283Parser_test.py
@@ -1,9 +1,7 @@
 """Tests for the IMFV283 Parser class."""
 
 from nose.tools import assert_equals
-from IMFV283Parser import IMFV283Parser
-
-import imfv283_codes
+from geomagio.imfv283 import IMFV283Parser, imfv283_codes
 
 
 IMFV283_EXAMPLE_VIC = '75C2A3A814023012741G43-1NN027EUP00191`A^P@RVxZ}|' + \
@@ -18,7 +16,7 @@ IMFV283_EXAMPLE_FRD = '75C2102614023012927G43-0NN027EUP00191bx@WyhD{' + \
 
 
 def test_parse_msg_header():
-    """geomagio.imfv283.IMFV283Parser_test.test_parse_msg_header()
+    """imfv283_test.IMFV283Parser_test.test_parse_msg_header()
 
     Call the _parse_header method with a header.
     Verify the header name and value are split at the correct column.
@@ -28,6 +26,8 @@ def test_parse_msg_header():
 
 
 def test_parse_goes_header():
+    """imfv283_test.IMFV283Parser_test.test_parse_goes_header()
+    """
     goes_data = IMFV283Parser()._process_ness_block(IMFV283_EXAMPLE_VIC,
         imfv283_codes.OBSERVATORIES['VIC'],
         191)
diff --git a/geomagio/pcdcp/PCDCPFactory_test.py b/test/pcdcp_test/PCDCPFactory_test.py
similarity index 90%
rename from geomagio/pcdcp/PCDCPFactory_test.py
rename to test/pcdcp_test/PCDCPFactory_test.py
index 7dc149436ee46916081b2d62ca97caa5a96f745c..f03fc65e263885dd9b6598d7144cda9c4082dc6c 100644
--- a/geomagio/pcdcp/PCDCPFactory_test.py
+++ b/test/pcdcp_test/PCDCPFactory_test.py
@@ -1,6 +1,6 @@
 """Tests for PCDCPFactory."""
 
-from PCDCPFactory import PCDCPFactory
+from geomagio.pcdcp import PCDCPFactory
 from obspy.core.utcdatetime import UTCDateTime
 from obspy.core.stream import Stream
 from nose.tools import assert_equals
@@ -15,7 +15,7 @@ pcdcpString = \
 
 
 def test_parse_string():
-    """geomagio.pcdcp.PCDCPFactory_test.test_parse_string()
+    """pcdcp_test.PCDCPFactory_test.test_parse_string()
 
     Send a PCDCP file string in to parse_string to make sure a well formed
     stream is created with proper values.
diff --git a/geomagio/pcdcp/PCDCPParser_test.py b/test/pcdcp_test/PCDCPParser_test.py
similarity index 91%
rename from geomagio/pcdcp/PCDCPParser_test.py
rename to test/pcdcp_test/PCDCPParser_test.py
index 418c5907fb581886fe90b5927ade9d5d2f53e5bf..e31a4f8ba7de6ca8905a576dfe4a866ac71fc8ee 100644
--- a/geomagio/pcdcp/PCDCPParser_test.py
+++ b/test/pcdcp_test/PCDCPParser_test.py
@@ -1,7 +1,7 @@
 """Tests for the PCDCP Parser class."""
 
 from nose.tools import assert_equals
-from PCDCPParser import PCDCPParser
+from geomagio.pcdcp import PCDCPParser
 
 
 PCDCP_EXAMPLE = \
@@ -20,7 +20,7 @@ BOU  2015  001  01-Jan-15  HEZF  0.01nT  File Version 2.00
 
 
 def test__parse_header():
-    """geomagio.pcdcp.PCDCPParser_test.test_parse_header()
+    """pcdcp_test.PCDCPParser_test.test_parse_header()
 
     Call the _parse_header method with a header.
     Verify the header name and value are split at the correct column.