diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..3ba1a32
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,14 @@
+require 'rake'
+
+task :default => [:spec]
+
+desc "Run all module spec tests (Requires rspec-puppet gem)"
+task :spec do
+  system("rspec spec")
+end
+
+desc "Build package"
+task :build do
+  system("puppet-module build")
+end
+
diff --git a/manifests/dev.pp b/manifests/dev.pp
index 68f0ec9..ca16057 100644
--- a/manifests/dev.pp
+++ b/manifests/dev.pp
@@ -14,5 +14,8 @@
 class apache::dev {
   include apache::params
 
-  package{$apache::params::apache_dev: ensure => installed}
+  package { "apache_dev_package":
+    name => $apache::params::apache_dev,
+    ensure => installed
+  }
 }
diff --git a/manifests/init.pp b/manifests/init.pp
index d983917..cbdfc40 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -14,7 +14,7 @@
 #
 class apache {
   include apache::params
-  package { 'httpd': 
+  package { 'httpd':
     name   => $apache::params::apache_name,
     ensure => installed,
   }
@@ -25,7 +25,8 @@ class apache {
     subscribe => Package['httpd'],
   }
 
-  file { $apache::params::vdir:
+  file { "httpd_vdir":
+    name => $apache::params::vdir,
     ensure  => directory,
     recurse => true,
     purge   => true,
diff --git a/manifests/php.pp b/manifests/php.pp
index 605ddce..6e78298 100644
--- a/manifests/php.pp
+++ b/manifests/php.pp
@@ -15,7 +15,8 @@
 class apache::php {
   include apache::params
 
-  package { $apache::params::php_package:
+  package { "apache_php_package":
+    name   => $apache::params::php_package,
     ensure => present,
   }
 }
diff --git a/manifests/python.pp b/manifests/python.pp
index 3bdeacb..3257158 100644
--- a/manifests/python.pp
+++ b/manifests/python.pp
@@ -16,7 +16,8 @@ class apache::python {
 	include apache::params
 	include apache
 
-  package { $apache::params::python_package:
+  package { "apache_python_package":
+    name   => $apache::params::python_package,
     ensure => present,
   }
 	a2mod { "python": ensure => present, }
diff --git a/manifests/ssl.pp b/manifests/ssl.pp
index 6204d70..82035fe 100644
--- a/manifests/ssl.pp
+++ b/manifests/ssl.pp
@@ -15,10 +15,12 @@
 class apache::ssl {
 
   include apache
-  
+
   case $operatingsystem {
      'centos', 'fedora', 'redhat', 'scientific': {
-        package { $apache::params::ssl_package:
+        package { "apache_ssl_package":
+           name    => "$apache::params::ssl_package",
+           ensure  => installed,
            require => Package['httpd'],
         }
      }
diff --git a/manifests/vhost.pp b/manifests/vhost.pp
index f889ff0..dbe3d3d 100644
--- a/manifests/vhost.pp
+++ b/manifests/vhost.pp
@@ -65,8 +65,8 @@ define apache::vhost(
     }
   }
 
-  file {
-    "${apache::params::vdir}/${priority}-${name}.conf":
+  file { "${priority}-${name}.conf":
+      name    => "${apache::params::vdir}/${priority}-${name}.conf",
       content => template($template),
       owner   => 'root',
       group   => 'root',
diff --git a/manifests/vhost/proxy.pp b/manifests/vhost/proxy.pp
index 55b806d..57b9430 100644
--- a/manifests/vhost/proxy.pp
+++ b/manifests/vhost/proxy.pp
@@ -3,9 +3,9 @@
 # Configures an apache vhost that will only proxy requests
 #
 # Parameters:
-# * $port: 
+# * $port:
 #     The port on which the vhost will respond
-# * $dest: 
+# * $dest:
 #     URI that the requests will be proxied for
 # - $priority
 # - $template -- the template to use for the vhost
@@ -31,13 +31,16 @@ define apache::vhost::proxy (
 
   include apache
 
+  $apache_name = $apache::params::apache_name
+  $ssl_path = $apache::params::ssl_path
   $srvname = $name
 
   if $ssl == true {
     include apache::ssl
   }
 
-  file {"${apache::params::vdir}/${priority}-${name}":
+  file { "${priority}-${name}":
+    name    => "${apache::params::vdir}/${priority}-${name}",
     content => template($template),
     owner   => 'root',
     group   => 'root',
diff --git a/manifests/vhost/redirect.pp b/manifests/vhost/redirect.pp
index ed4a55f..d5fb6bd 100644
--- a/manifests/vhost/redirect.pp
+++ b/manifests/vhost/redirect.pp
@@ -29,7 +29,8 @@ define apache::vhost::redirect (
 
   $srvname = $name
 
-  file {"${apache::params::vdir}/${priority}-${name}":
+  file { "${priority}-${name}":
+    name    => "${apache::params::vdir}/${priority}-${name}",
     content => template($template),
     owner   => 'root',
     group   => 'root',
diff --git a/spec/classes/apache_spec.rb b/spec/classes/apache_spec.rb
new file mode 100644
index 0000000..b3a6d00
--- /dev/null
+++ b/spec/classes/apache_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe 'apache', :type => :class do
+
+  it { should include_class("apache::params") }
+
+  it { should contain_package("httpd") }
+
+  it { should contain_service("httpd").with(
+    'ensure'    => 'running',
+    'enable'    => 'true',
+    'subscribe' => 'Package[httpd]'
+    )
+  }
+
+  it { should contain_file("httpd_vdir").with(
+    'ensure'  => 'directory',
+    'recurse' => 'true',
+    'purge'   => 'true',
+    'notify'  => 'Service[httpd]',
+    'require' => 'Package[httpd]'
+    )
+  }
+end
diff --git a/spec/classes/dev_spec.rb b/spec/classes/dev_spec.rb
new file mode 100644
index 0000000..57d913d
--- /dev/null
+++ b/spec/classes/dev_spec.rb
@@ -0,0 +1,8 @@
+require 'spec_helper'
+
+describe 'apache::dev', :type => :class do
+
+  it { should include_class("apache::params") }
+  it { should contain_package("apache_dev_package") }
+
+end
diff --git a/spec/classes/mod/python_spec.rb b/spec/classes/mod/python_spec.rb
new file mode 100644
index 0000000..166e290
--- /dev/null
+++ b/spec/classes/mod/python_spec.rb
@@ -0,0 +1,18 @@
+require 'spec_helper'
+
+describe 'apache::mod::python', :type => :class do
+
+  it { should include_class("apache") }
+
+  it { should contain_package("mod_python_package").with(
+   'ensure'  => 'installed',
+   'require' => 'Package[httpd]'
+    )
+  }
+
+  it { should contain_a2mod("python").with(
+   'ensure'  => 'present'
+    )
+  }
+
+end
diff --git a/spec/classes/mod/wsgi_spec.rb b/spec/classes/mod/wsgi_spec.rb
new file mode 100644
index 0000000..c1c8dc9
--- /dev/null
+++ b/spec/classes/mod/wsgi_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe 'apache::mod::wsgi', :type => :class do
+
+  it { should include_class("apache") }
+
+  it { should contain_package("mod_wsgi_package").with(
+   'require' => 'Package[httpd]'
+    )
+  }
+
+  it { should contain_a2mod("wsgi").with(
+   'ensure'  => 'present'
+    )
+  }
+
+end
diff --git a/spec/classes/params_spec.rb b/spec/classes/params_spec.rb
new file mode 100644
index 0000000..7236c2d
--- /dev/null
+++ b/spec/classes/params_spec.rb
@@ -0,0 +1,13 @@
+require 'spec_helper'
+
+describe 'apache::params', :type => :class do
+
+  it { should contain_apache__params }
+
+  # There are 4 resources in this class currently
+  # there should not be any more resources because it is a params class
+  # The resources are class[apache::params], class[main], class[settings], stage[main]
+  it "Should not contain any resources" do
+    subject.resources.size.should == 4
+  end
+end
diff --git a/spec/classes/php_spec.rb b/spec/classes/php_spec.rb
new file mode 100644
index 0000000..33413f0
--- /dev/null
+++ b/spec/classes/php_spec.rb
@@ -0,0 +1,8 @@
+require 'spec_helper'
+
+describe 'apache::php', :type => :class do
+
+  it { should include_class("apache::params") }
+  it { should contain_package("apache_php_package") }
+
+end
diff --git a/spec/classes/python_spec.rb b/spec/classes/python_spec.rb
new file mode 100644
index 0000000..aae899d
--- /dev/null
+++ b/spec/classes/python_spec.rb
@@ -0,0 +1,13 @@
+require 'spec_helper'
+
+describe 'apache::python', :type => :class do
+
+  it { should include_class("apache") }
+  it { should include_class("apache::params") }
+  it { should contain_package("apache_python_package") }
+  it { should contain_a2mod("python").with(
+   'ensure'  => 'present'
+    )
+  }
+
+end
diff --git a/spec/classes/ssl_spec.rb b/spec/classes/ssl_spec.rb
new file mode 100644
index 0000000..fefedc3
--- /dev/null
+++ b/spec/classes/ssl_spec.rb
@@ -0,0 +1,30 @@
+require 'spec_helper'
+
+describe 'apache::ssl', :type => :class do
+
+  it { should include_class("apache") }
+  it { should include_class("apache::params") }
+
+  describe "it should install the ssl package in redhat" do
+    let :facts do
+      { :operatingsystem => 'redhat' }
+    end
+
+    it { should contain_package("apache_ssl_package").with(
+        'ensure'  => 'installed'
+      )
+    }
+  end
+
+  describe "it should contain a2mod ssl in debian" do
+    let :facts do
+      { :operatingsystem => 'debian' }
+    end
+
+    it { should contain_a2mod("ssl").with(
+        'ensure'  => 'present'
+      )
+    }
+  end
+
+end
diff --git a/spec/defines/vhost/proxy_spec.rb b/spec/defines/vhost/proxy_spec.rb
new file mode 100644
index 0000000..2f20a04
--- /dev/null
+++ b/spec/defines/vhost/proxy_spec.rb
@@ -0,0 +1,61 @@
+require 'spec_helper'
+
+describe 'apache::vhost::proxy', :type => :define do
+
+  let :title do
+    'my_proxy_vhost'
+  end
+
+
+  let :default_params do
+    {
+      :port          => '80',
+      :dest          => 'example.com',
+      :priority      => '10',
+      :template      => "apache/vhost-proxy.conf.erb",
+      :servername    => '',
+      :serveraliases => '',
+      :ssl           => false,
+      :vhost_name    => '*'
+    }
+  end
+
+  [{
+      :dest          => 'example2.com',
+      :port          => '80',
+      :ssl           => true
+   },
+  ].each do |param_set|
+
+    describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
+
+      let :param_hash do
+        default_params.merge(param_set)
+      end
+
+      let :params do
+        param_set
+      end
+
+      it { should include_class("apache") }
+      it { should contain_apache__params }
+
+      it {
+        if param_hash[:ssl]
+          should contain_apache__ssl
+        else
+          should_not contain_apache__ssl
+        end
+      }
+
+      it { should contain_file("#{param_hash[:priority]}-#{title}").with({
+          'owner'     => 'root',
+          'group'     => 'root',
+          'mode'      => '755',
+          'require'   => 'Package[httpd]',
+          'notify'    => 'Service[httpd]'
+        })
+      }
+    end
+  end
+end
diff --git a/spec/defines/vhost/redirect_spec.rb b/spec/defines/vhost/redirect_spec.rb
new file mode 100644
index 0000000..1b329ec
--- /dev/null
+++ b/spec/defines/vhost/redirect_spec.rb
@@ -0,0 +1,56 @@
+require 'spec_helper'
+
+describe 'apache::vhost::redirect', :type => :define do
+  let :title do
+    'my_vhost_redirect'
+  end
+
+
+  let :default_params do
+    {
+      :port          => '80',
+      :dest          => 'example.com',
+      :priority      => '10',
+      :template      => "apache/vhost-redirect.conf.erb",
+      :vhost_name    => '*'
+    }
+  end
+
+  [{
+      :dest          => 'example2.com',
+      :port          => '80',
+   },
+  ].each do |param_set|
+
+    describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
+
+      let :param_hash do
+        default_params.merge(param_set)
+      end
+
+      let :params do
+        param_set
+      end
+
+      it { should include_class("apache") }
+      it { should contain_apache__params }
+
+      it { should contain_file("#{param_hash[:priority]}-#{title}").with({
+          'owner'     => 'root',
+          'group'     => 'root',
+          'mode'      => '755',
+          'require'   => 'Package[httpd]',
+          'notify'    => 'Service[httpd]'
+        })
+      }
+
+      # FIXME: Firewall is not actually realized anywhere
+      #it { should contain_firewall("0100-INPUT ACCEPT #{param_hash[:port]}").with( {
+      #    'jump' => 'Accept',
+      #    'dport'  => "#{param_hash[:port]}",
+      #    'proto'  => 'tcp'
+      #  })
+      #}
+    end
+  end
+end
diff --git a/spec/defines/vhost_spec.rb b/spec/defines/vhost_spec.rb
new file mode 100644
index 0000000..ff71655
--- /dev/null
+++ b/spec/defines/vhost_spec.rb
@@ -0,0 +1,77 @@
+require 'spec_helper'
+
+describe 'apache::vhost', :type => :define do
+
+  let :title do
+    'my_vhost'
+  end
+
+  let :default_params do
+    {
+    :apache_name   => 'apache2',
+    :auth          => false,
+    :docroot       => 'path/to/docroot',
+    :options       => 'Indexes FollowSymLinks MultiViews',
+    :port          => '80',
+    :priority      => '25',
+    :redirect_ssl  => false,
+    :serveraliases => '',
+    :servername    => '',
+    :ssl           => true,
+    :template      => 'apache/vhost-default.conf.erb',
+    :vhost_name    => '*'
+    }
+  end
+
+  [{
+      :apache_name   => 'httpd',
+      :docroot       => 'path/to/docroot',
+      :port          => '80',
+      :priority      => '25',
+      :ssl           => false,
+      :template      => 'apache/vhost-default.conf.erb',
+   },
+  ].each do |param_set|
+
+    describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
+
+      let :param_hash do
+        default_params.merge(param_set)
+      end
+
+      let :params do
+        param_set
+      end
+
+      it { should include_class("apache") }
+      it { should contain_apache__params }
+
+      it {
+        if param_hash[:ssl]
+          should contain_apache__ssl
+        else
+          should_not contain_apache__ssl
+        end
+      }
+
+      it { should contain_file("#{param_hash[:priority]}-#{title}.conf").with({
+          'owner'     => 'root',
+          'group'     => 'root',
+          'mode'      => '755',
+          'require'   => 'Package[httpd]',
+          'notify'    => 'Service[httpd]'
+        })
+      }
+
+      # FIXME: Firewall is not actually realized anywhere
+      #it { should contain_firewall("0100-INPUT ACCEPT #{param_hash[:port]}").with( {
+      #    'action' => 'accept',
+      #    'dport'  => "#{param_hash[:port]}",
+      #    'proto'  => 'tcp'
+      #  })
+      #}
+
+
+    end
+  end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..d2648da
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,11 @@
+require 'puppet'
+require 'rubygems'
+require 'rspec-puppet'
+
+def param_value(subject, type, title, param)
+  subject.resource(type, title).send(:parameters)[param.to_sym]
+end
+
+RSpec.configure do |c|
+  c.module_path = File.join(File.dirname(__FILE__), '../../')
+end