diff --git a/circle.yml b/circle.yml
index 23598b347561ddaee69f7a31252b626ef2711469..fedeadec122b64bffbcbbe6b0cd76caa24f185d9 100644
--- a/circle.yml
+++ b/circle.yml
@@ -1,4 +1,4 @@
 test:
   override:
-    - case $CIRCLE_NODE_INDEX in 0) lein eastwood ;; 1) lein expectations ;; esac:
+    - case $CIRCLE_NODE_INDEX in 0) lein eastwood ;; 1) lein test ;; esac:
         parallel: true
diff --git a/project.clj b/project.clj
index 9dc8edadd3150cb292a27e818d5e47717dd369c9..8c5f7c5e74bb69bcb44c2e6b101a979306affd16 100644
--- a/project.clj
+++ b/project.clj
@@ -5,6 +5,7 @@
   :description "Metabase Community Edition"
   :url "http://metabase.com/"
   :min-lein-version "2.3.0"
+  :aliases {"test" ["with-profile" "+expectations" "expectations"]}
   :dependencies [[org.clojure/clojure "1.6.0"]
                  [org.clojure/core.async "LATEST"]                    ; facilities for async programming + communication (using 'LATEST' because this is an alpha library)
                  [org.clojure/core.match "0.3.0-alpha4"]              ; optimized pattern matching library for Clojure
@@ -69,5 +70,8 @@
                               "-XX:MaxPermSize=128m"                  ; a little more headroom for PermGen
                               "-XX:+CMSClassUnloadingEnabled"         ; let Clojure's dynamically generated temporary classes be GC'ed from PermGen
                               "-XX:+UseConcMarkSweepGC"]}             ; Concurrent Mark Sweep GC needs to be used for Class Unloading (above)
+             :expectations {:jvm-opts ["-Dmb.db.file=target/metabase-test"
+                                       "-Dmb.jetty.join=false"
+                                       "-Dmb.jetty.port=3001"]}
              :uberjar {:aot :all
                        :prep-tasks ["npm" "gulp" "javac" "compile"]}})
diff --git a/src/metabase/core.clj b/src/metabase/core.clj
index 9b3651c86f389e87fc8a8e3d059893e4a98fb442..376b4beaf483541dfbba5743d3e0f505fc39311a 100644
--- a/src/metabase/core.clj
+++ b/src/metabase/core.clj
@@ -53,37 +53,57 @@
           hostname (or (config/config-str :mb-jetty-host) "localhost")
           port (config/config-int :mb-jetty-port)
           setup-url (str "http://"
-                      (or hostname "localhost")
-                      (when-not (= 80 port) (str ":" port))
-                      "/setup/init/"
-                      setup-token)]
+                         (or hostname "localhost")
+                         (when-not (= 80 port) (str ":" port))
+                         "/setup/init/"
+                         setup-token)]
       (log/info (str "Please use the following url to setup your Metabase installation:\n\n"
-                  setup-url
-                  "\n\n"))))
+                     setup-url
+                     "\n\n"))))
 
   (log/info "Metabase Initialization COMPLETE")
   true)
 
 
+;; ## Jetty (Web) Server
+
+
+(def ^:private jetty-instance
+  (atom nil))
+
+(defn start-jetty
+  "Start the embedded Jetty web server."
+  []
+  (when-not @jetty-instance
+    (let [jetty-config (cond-> (medley/filter-vals identity {:port (config/config-int :mb-jetty-port)
+                                                             :host (config/config-str :mb-jetty-host)
+                                                             :max-threads (config/config-int :mb-jetty-maxthreads)
+                                                             :min-threads (config/config-int :mb-jetty-minthreads)
+                                                             :max-queued (config/config-int :mb-jetty-maxqueued)
+                                                             :max-idle-time (config/config-int :mb-jetty-maxidletime)})
+                               (config/config-str :mb-jetty-join) (assoc :join? (config/config-bool :mb-jetty-join))
+                               (config/config-str :mb-jetty-daemon) (assoc :daemon? (config/config-bool :mb-jetty-daemon)))]
+      (log/info "Launching Embedded Jetty Webserver with config:\n" (with-out-str (clojure.pprint/pprint jetty-config)))
+      (->> (ring-jetty/run-jetty app jetty-config)
+           (reset! jetty-instance)))))
+
+(defn stop-jetty
+  "Stop the embedded Jetty web server."
+  []
+  (when @jetty-instance
+    (log/info "Shutting Down Embedded Jetty Webserver")
+    (.stop ^org.eclipse.jetty.server.Server @jetty-instance)
+    (reset! jetty-instance nil)))
+
+
 (defn -main
   "Launch Metabase in standalone mode."
   [& args]
   (log/info "Starting Metabase in STANDALONE mode")
-
-  ;; run application init and if there are no issues then continue on to launching the webserver
-  (when (try
-          (init)
-          (catch Exception e
-            (log/error "Metabase Initialization FAILED: " (.getMessage e))))
-    ;; startup webserver
-    (let [jetty-config (->> {:port (config/config-int :mb-jetty-port)
-                             :host (config/config-str :mb-jetty-host)
-                             :join? (config/config-bool :mb-jetty-join?)
-                             :daemon? (config/config-bool :mb-jetty-daemon?)
-                             :max-threads (config/config-int :mb-jetty-maxthreads)
-                             :min-threads (config/config-int :mb-jetty-minthreads)
-                             :max-queued (config/config-int :mb-jetty-maxqueued)
-                             :max-idle-time (config/config-int :mb-jetty-maxidletime)}
-                         (medley/filter-vals identity))]
-      (log/info "Launching Embedded Jetty Webserver with config:\n" (with-out-str (clojure.pprint/pprint jetty-config)))
-      (ring-jetty/run-jetty app jetty-config))))
+  (try
+    ;; run our initialization process
+    (init)
+    ;; launch embedded webserver
+    (start-jetty)
+    (catch Exception e
+      (log/error "Metabase Initialization FAILED: " (.getMessage e)))))
diff --git a/test/log4j.properties b/test/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c2e7b0ff2c176e956b635b668a1d84c07dc6ee6e
--- /dev/null
+++ b/test/log4j.properties
@@ -0,0 +1,20 @@
+log4j.rootLogger=INFO, console
+
+# log to the console
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Target=System.out
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d [%-5p] %c :: %m%n
+
+# log to a file
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.File=${logfile.path}/corvus.log
+log4j.appender.file.MaxFileSize=500MB
+log4j.appender.file.MaxBackupIndex=2
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d [%t] %-5p%c - %m%n
+
+# customizations to logging by package
+log4j.logger.com.mchange=WARN
+log4j.logger.liquibase=WARN
+log4j.logger.metabase=INFO
diff --git a/test/metabase/api/common_test.clj b/test/metabase/api/common_test.clj
index f271c28d85b30b5742361fc7ae6459b5fc24d05b..ca2277c65378e4733bdc1397cca96e862eb21c2b 100644
--- a/test/metabase/api/common_test.clj
+++ b/test/metabase/api/common_test.clj
@@ -5,7 +5,7 @@
             [metabase.api.org-test :refer [create-org]]
             [metabase.test-data :refer :all]
             [metabase.test-data.create :refer [create-user]]
-            metabase.test-utils
+            metabase.test-setup
             [metabase.test.util :refer :all]
             [metabase.util :refer [regex= regex?]])
   (:import com.metabase.corvus.api.ApiException))
diff --git a/test/metabase/api/meta/field_test.clj b/test/metabase/api/meta/field_test.clj
index f189df5e4027e8a8187499f8a9b0554413af006d..17f7f928901ed6c58c0dddc3da68dbaade67cfd9 100644
--- a/test/metabase/api/meta/field_test.clj
+++ b/test/metabase/api/meta/field_test.clj
@@ -55,6 +55,7 @@
 
 ;; ## PUT /api/meta/field/:id
 ;; Check that we can update a Field
+;; TODO - this should NOT be modifying a field from our test data, we should create new data to mess with
 (expect-eval-actual-first
     (match-$ (let [field (sel :one Field :id (field->id :venues :latitude))]
                ;; this is sketchy. But return the Field back to its unmodified state so it won't affect other unit tests
@@ -73,4 +74,4 @@
        :preview_display true
        :created_at $
        :base_type "FloatField"})
-      ((user->client :rasta) :put 200 (format "meta/field/%d" (field->id :venues :latitude)) {:special_type :fk}))
+  ((user->client :rasta) :put 200 (format "meta/field/%d" (field->id :venues :latitude)) {:special_type :fk}))
diff --git a/test/metabase/http_client.clj b/test/metabase/http_client.clj
index 14630e75b822dc025417b59c78581420573f6580..eab604dbe1e050da2916c1e54fc310988671a4b7 100644
--- a/test/metabase/http_client.clj
+++ b/test/metabase/http_client.clj
@@ -3,6 +3,7 @@
   (:require [clojure.tools.logging :as log]
             [cheshire.core :as cheshire]
             [clj-http.lite.client :as client]
+            [metabase.config :as config]
             [metabase.util :as u])
   (:import com.metabase.corvus.api.ApiException))
 
@@ -15,7 +16,7 @@
 
 (def ^:dynamic *url-prefix*
   "Prefix to automatically prepend to the URL of calls made with `client`."
-  "http://localhost:3000/api/")
+  (str "http://localhost:" (config/config-str :mb-jetty-port) "/api/"))
 
 (defn
   ^{:arglists ([credentials? method expected-status-code? url http-body-map? & url-kwargs])}
diff --git a/test/metabase/models/org_perm_test.clj b/test/metabase/models/org_perm_test.clj
deleted file mode 100644
index c3f4cd157cc5460dcda4e57110502c0416cce315..0000000000000000000000000000000000000000
--- a/test/metabase/models/org_perm_test.clj
+++ /dev/null
@@ -1,52 +0,0 @@
-(ns metabase.models.org-perm-test
-  (:require [clojure.tools.logging :as log]
-            [clj-time.coerce :as tc]
-            [clj-time.core :as time]
-            [expectations :refer :all]
-            [korma.core :refer :all]
-            (metabase [db :refer :all]
-                      test-utils)
-            (metabase.models [org-perm :refer [OrgPerm]]
-                             [org :refer [Org]]
-                             [user :refer [User]])))
-
-
-;(defn insert-org []
-;  (let [result (ins Org
-;                 :name "org_perm_test"
-;                 :slug "org_perm_test"
-;                 :inherits false)]
-;    (or (:id result) -1)))
-;
-;(defn insert-user []
-;  (let [result (ins User
-;                 :email "org_perm_test"
-;                 :first_name "org_perm_test"
-;                 :last_name "org_perm_test"
-;                 :password "org_perm_test"
-;                 :date_joined (java.sql.Timestamp. (tc/to-long (time/now)))
-;                 :is_active true
-;                 :is_staff true
-;                 :is_superuser false)]
-;    (or (:id result) -1)))
-;
-;(defn count-perms []
-;  (get-in (first (select OrgPerm (aggregate (count :*) :cnt))) [:cnt]))
-;
-;
-;; start with 0 entries
-;(expect 0 (count-perms))
-;
-;; insert a new value
-;(expect (more->
-;          false nil?
-;          true (contains? :id))
-;  (let [org-id (insert-org)
-;        user-id (insert-user)]
-;    (ins OrgPerm
-;      :admin false
-;      :organization_id org-id
-;      :user_id user-id)))
-;
-;; now we should have 1 entry
-;(expect 1 (count-perms))
diff --git a/test/metabase/models/org_test.clj b/test/metabase/models/org_test.clj
deleted file mode 100644
index 24b8c155a637d6f32fadaa7ccd4e6c61fea5423d..0000000000000000000000000000000000000000
--- a/test/metabase/models/org_test.clj
+++ /dev/null
@@ -1,27 +0,0 @@
-(ns metabase.models.org-test
-  (:require [clojure.tools.logging :as log]
-            [expectations :refer :all]
-            [korma.core :refer :all]
-            (metabase [db :refer :all]
-                      test-utils)
-            [metabase.models.org :refer [Org]]))
-
-
-;(defn count-orgs []
-;  (get-in (first (select Org (aggregate (count :*) :cnt))) [:cnt]))
-;
-;
-;; start with 0 entries
-;(expect 0 (count-orgs))
-;
-;; insert a new value
-;(expect (more->
-;          false nil?
-;          true (contains? :id))
-;  (ins Org
-;    :name "org_test"
-;    :slug "org_test"
-;    :inherits false))
-;
-;; now we should have 1 entry
-;(expect 1 (count-orgs))
diff --git a/test/metabase/models/setting_test.clj b/test/metabase/models/setting_test.clj
index 383f353bf2cad95932c7481d09984cd45b23515b..da5bf9d38aaa7d83d8a8ef6b0008b509bfba469b 100644
--- a/test/metabase/models/setting_test.clj
+++ b/test/metabase/models/setting_test.clj
@@ -2,8 +2,7 @@
   (:require [expectations :refer :all]
             [medley.core :as m]
             (metabase [db :refer [sel]]
-                      [test-data :refer :all]
-                      test-utils)
+                      [test-data :refer :all])
             [metabase.models.setting :refer [defsetting Setting] :as setting]
             [metabase.test.util :refer :all]))
 
diff --git a/test/metabase/models/user_test.clj b/test/metabase/models/user_test.clj
deleted file mode 100644
index 4a9c990294a95021bd1f9866454d767a91b43bc6..0000000000000000000000000000000000000000
--- a/test/metabase/models/user_test.clj
+++ /dev/null
@@ -1,34 +0,0 @@
-(ns metabase.models.user-test
-  (:require [clojure.tools.logging :as log]
-            [clj-time.coerce :as tc]
-            [clj-time.core :as time]
-            [expectations :refer :all]
-            [korma.core :refer :all]
-            (metabase [db :refer :all]
-                      test-utils)
-            [metabase.models.user :refer [User]]))
-
-
-;(defn count-users []
-;  (get-in (first (select User (aggregate (count :*) :cnt))) [:cnt]))
-;
-;
-;; start with 0 entries
-;(expect 0 (count-users))
-;
-;; insert a new value
-;(expect (more->
-;          false nil?
-;          true (contains? :id))
-;  (ins User
-;    :email "user_test"
-;    :first_name "user_test"
-;    :last_name "user_test"
-;    :password "user_test"
-;    :date_joined (java.sql.Timestamp. (tc/to-long (time/now)))
-;    :is_active true
-;    :is_staff true
-;    :is_superuser false))
-;
-;; now we should have 1 entry
-;(expect 1 (count-users))
diff --git a/test/metabase/test_data/load.clj b/test/metabase/test_data/load.clj
index e389e35aa12c2f961844a27c5ce63bdf2f98cf09..4a04abe319cb126705261f3aa5380e05f6df91fb 100644
--- a/test/metabase/test_data/load.clj
+++ b/test/metabase/test_data/load.clj
@@ -20,7 +20,7 @@
 (def ^:private db-name "Test Database")
 (def ^:private org-name "Test Organization")
 (def ^:private test-db-filename
-  (delay (format "%s/t.db" (System/getProperty "user.dir"))))
+  (delay (format "%s/target/test-data" (System/getProperty "user.dir"))))
 (def ^:private test-db-connection-string
   (delay (format "file:%s;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1" @test-db-filename)))
 
@@ -41,20 +41,20 @@
   []
   {:post [(map? %)]}
   (or (sel :one Database :name db-name)
-    (do (when-not (.exists (clojure.java.io/file (str @test-db-filename ".mv.db"))) ; only create + populate the test DB file if needed
-          (create-and-populate-tables))
-        (log/info "Creating new metabase Database object...")
-        (let [db (ins Database
-                   :organization_id (:id (test-org))
-                   :name db-name
-                   :engine :h2
-                   :details {:conn_str @test-db-connection-string})]
-          (log/info "Syncing Tables...")
-          (driver/sync-tables db)
-          (log/info "Adding Schema Metadata...")
-          (add-metadata!)
-          (log/info "Finished. Enjoy your test data <3")
-          db))))
+      (do (when-not (.exists (clojure.java.io/file (str @test-db-filename ".mv.db"))) ; only create + populate the test DB file if needed
+            (create-and-populate-tables))
+          (log/info "Creating new metabase Database object...")
+          (let [db (ins Database
+                     :organization_id (:id (test-org))
+                     :name db-name
+                     :engine :h2
+                     :details {:conn_str @test-db-connection-string})]
+            (log/info "Syncing Tables...")
+            (driver/sync-tables db)
+            (log/info "Adding Schema Metadata...")
+            (add-metadata!)
+            (log/info "Finished. Enjoy your test data <3")
+            db))))
 
 
 ;; ## Debugging/Interactive Development Functions
@@ -77,11 +77,11 @@
   "Binds `*test-db*` if not already bound to a Korma DB entity and executes BODY."
   [& body]
   `(if *test-db* (do ~@body)
-       (binding [*test-db* (create-db (h2 {:db @test-db-connection-string
-                                           :naming {:keys s/lower-case
-                                                    :fields s/upper-case}}))]
-         (log/info "CREATING H2 TEST DATABASE...")
-         ~@body)))
+                 (binding [*test-db* (create-db (h2 {:db @test-db-connection-string
+                                                     :naming {:keys s/lower-case
+                                                              :fields s/upper-case}}))]
+                   (log/info "CREATING H2 TEST DATABASE...")
+                   ~@body)))
 
 (defn- exec-sql
   "Execute raw SQL STATEMENTS against the test database."
diff --git a/test/metabase/test_setup.clj b/test/metabase/test_setup.clj
new file mode 100644
index 0000000000000000000000000000000000000000..d726012918fd302c997ab1dda98df38e5f8ddbee
--- /dev/null
+++ b/test/metabase/test_setup.clj
@@ -0,0 +1,56 @@
+(ns metabase.test-setup
+  "Functions that run before + after unit tests (setup DB, start web server, load test data)."
+  (:require [clojure.java.io :as io]
+            [clojure.tools.logging :as log]
+            [expectations :refer :all]
+            (metabase [core :as core]
+                      [db :as db]
+                      [test-data :refer :all])))
+
+(declare clear-test-db)
+
+;; # SETTINGS
+
+;; Don't run unit tests whenever JVM shuts down
+;; it's pretty annoying to have our DB reset all the time
+(expectations/disable-run-on-shutdown)
+
+
+;; # FUNCTIONS THAT GET RUN ON TEST SUITE START / STOP
+
+(defn test-startup
+  {:expectations-options :before-run}
+  []
+  (log/info "Starting up Metabase unit test runner")
+  ;; clear out any previous test data that's lying around
+  (clear-test-db)
+  ;; setup the db and migrate up to current schema
+  (db/setup-db :auto-migrate true)
+  ;; this causes the test data to be loaded
+  @test-db
+  ;; startup test web server
+  (core/start-jetty))
+
+
+(defn test-teardown
+  {:expectations-options :after-run}
+  []
+  (log/info "Shutting down Metabase unit test runner")
+  (core/stop-jetty))
+
+
+;; ## DB Setup
+;; WARNING: BY RUNNING ANY UNIT TESTS THAT REQUIRE THIS FILE OR BY RUNNING YOUR ENTIRE TEST SUITE YOU WILL EFFECTIVELY BE WIPING OUT YOUR DATABASE.
+;; SETUP-DB DELETES YOUR DATABASE FILE, AND GETS RAN AUTOMATICALLY BY EXPECTATIONS. USE AT YOUR OWN RISK!
+
+(defn- clear-test-db
+  "Delete the test db file if it's still lying around."
+  []
+  (let [filename (-> (re-find #"file:(\w+\.db).*" (db/db-file)) second)] ; db-file is prefixed with "file:", so we strip that off
+    (map (fn [file-extension]                                         ; delete the database files, e.g. `metabase.db.h2.db`, `metabase.db.trace.db`, etc.
+           (let [file (str filename file-extension)]
+             (when (.exists (io/file file))
+               (io/delete-file file))))
+         [".h2.db"
+          ".trace.db"
+          ".lock.db"])))
diff --git a/test/metabase/test_utils.clj b/test/metabase/test_utils.clj
deleted file mode 100644
index f53775a4b1aaa670550281882e4e79480832c9c9..0000000000000000000000000000000000000000
--- a/test/metabase/test_utils.clj
+++ /dev/null
@@ -1,81 +0,0 @@
-(ns metabase.test-utils ; TODO - rename to setup
-  "Functions that run before + after unit tests (setup DB, start web server, load test data)."
-  (:require [clojure.java.io :as io]
-            [clojure.tools.logging :as log]
-            [expectations :refer :all]
-            [ring.adapter.jetty :as ring]
-            (metabase [core :as core]
-                      [db :refer :all]
-                      [test-data :refer :all])))
-
-(declare load-test-data
-         setup-test-db
-         start-jetty)
-
-;; # SETTINGS
-
-;; Don't run unit tests whenever JVM shuts down
-;; it's pretty annoying to have our DB reset all the time
-(expectations/disable-run-on-shutdown)
-
-
-;; # FUNCTIONS THAT GET RUN ON TEST SUITE START / STOP
-
-(defn test-setup
-  {:expectations-options :before-run}
-  []
-  ;; Disable debug logging since it clutters up our output
-  (.setLevel (org.apache.log4j.Logger/getLogger "metabase") org.apache.log4j.Level/INFO)
-  (setup-test-db)
-  (load-test-data)
-  (start-jetty))
-
-;; ## DB Setup
-;; WARNING: BY RUNNING ANY UNIT TESTS THAT REQUIRE THIS FILE OR BY RUNNING YOUR ENTIRE TEST SUITE YOU WILL EFFECTIVELY BE WIPING OUT YOUR DATABASE.
-;; SETUP-DB DELETES YOUR DATABASE FILE, AND GETS RAN AUTOMATICALLY BY EXPECTATIONS. USE AT YOUR OWN RISK!
-
-(defn- setup-test-db
-  "Setup database schema."
-  []
-  (let [filename (-> (re-find #"file:(\w+\.db).*" (db-file)) second)] ; db-file is prefixed with "file:", so we strip that off
-    (map (fn [file-extension]                                         ; delete the database files, e.g. `metabase.db.h2.db`, `metabase.db.trace.db`, etc.
-           (let [file (str filename file-extension)]
-             (when (.exists (io/file file))
-               (io/delete-file file))))
-         [".h2.db"
-          ".trace.db"
-          ".lock.db"]))
-  (log/info "tearing down database and resetting to empty schema")
-  (migrate (setup-jdbc-db) :down)
-  (log/info "setting up database and running all migrations")
-  (setup-db :auto-migrate true)
-  (log/info "database setup complete"))
-
-(defn- load-test-data []
-  @test-db)
-
-
-;; ## Jetty (Web) Server
-
-
-(def ^:private jetty-instance
-  (atom nil))
-
-(defn- start-jetty
-  "Start the Jetty web server."
-  []
-  (log/info "STARTING THE JETTY SERVER...")
-  (when-not @jetty-instance
-    (try (->> (ring/run-jetty core/app {:port 3000
-                                        :join? false}) ; detach the thread
-              (reset! jetty-instance))
-        (catch java.net.BindException e                ; assume server is already running if port's already bound
-          (log/warn "ALREADY RUNNING!")))))            ; e.g. if someone is running `lein ring server` locally. Tests should still work normally.
-
-(defn stop-jetty
-  "Stop the Jetty web server."
-  {:expectations-options :after-run}
-  []
-  (when @jetty-instance
-    (.stop ^org.eclipse.jetty.server.Server @jetty-instance)
-    (reset! jetty-instance nil)))