diff --git a/browserid/lib/db_json.js b/browserid/lib/db_json.js
index a38da9d76af3aaa37f8759a7da205f2a74dd0868..1aeaa38922dbf6eab01992da8758d866cd9c77fa 100644
--- a/browserid/lib/db_json.js
+++ b/browserid/lib/db_json.js
@@ -44,7 +44,8 @@ fs = require('fs'),
 secrets = require('./secrets'),
 jsel = require('JSONSelect'),
 logger = require('../../libs/logging.js').logger,
-configuration = require('../../libs/configuration.js');
+configuration = require('../../libs/configuration.js'),
+temp = require('temp');
 
 // a little alias for stringify
 const ESC = JSON.stringify;
@@ -87,8 +88,23 @@ function getExpiryTime() {
   return ((new Date()).getTime() + (14 * 24 * 60 * 60 * 1000));
 }
 
+// when unit_test is set in configuration, database should be
+// ephemeral.  which simply means we use a temp file and delete
+// on close;
+var delete_on_close = false;
+
 exports.open = function(cfg, cb) {
-  if (cfg && cfg.path) dbPath = cfg.path;
+  delete_on_close = false;
+
+  if (cfg) {
+    if (cfg.unit_test) {
+      dbPath = temp.path({suffix: '.db'});
+      delete_on_close = true;
+    } else if (cfg.path) {
+      dbPath = cfg.path;
+    }
+  }
+
   try {
     db = JSON.parse(fs.readFileSync(dbPath));
   } catch(e) {
@@ -100,6 +116,10 @@ exports.open = function(cfg, cb) {
 exports.close = function(cb) {
   flush();
   setTimeout(cb, 0);
+  if (delete_on_close) {
+    delete_on_close = false;
+    fs.unlink(dbPath, function(err) { });
+  };
 };
 
 exports.emailKnown = function(email, cb) {
diff --git a/browserid/tests/db-test.js b/browserid/tests/db-test.js
index dcac10029b1c36cc77858e2b9afb9f47dd04017d..8d0d7ab49ac5727da86dd5f3ad234e878c6b459d 100755
--- a/browserid/tests/db-test.js
+++ b/browserid/tests/db-test.js
@@ -35,442 +35,379 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
+require('./lib/test_env.js');
+
 const
 assert = require('assert'),
 vows = require('vows'),
 db = require('../lib/db.js'),
-temp = require('temp'),
 fs = require('fs'),
-path = require('path');
+path = require('path'),
+configuration = require('../../libs/configuration.js');
 
 var suite = vows.describe('db');
 // disable vows (often flakey?) async error behavior
 suite.options.error = false;
 
-function addTestsForDriver(driver) {
-  var dbPath = temp.path({suffix: '.db'});
+var dbCfg = configuration.get('database');
 
-  const dbCfg = {
-    driver: driver,
-    user: "test",      // only pertinent for mysql
-    unit_test: "true", // causes mysql driver to use an ephemeral database and to delete on close
-    path: dbPath       // only pertinent for JSON
-  };
+suite.addBatch({
+  "onReady": {
+    topic: function() { db.onReady(this.callback); },
+    "works": function(r) { }
+  },
+  "onReady still": {
+    topic: function() { db.onReady(this.callback); },
+    "works for more than one caller": function(r) { }
+  },
+  "opening the database": {
+    topic: function() {
+      db.open(dbCfg, this.callback);
+    },
+    "and its ready": function(r) {
+      assert.isUndefined(r);
+    },
+    "doesn't prevent onReady": {
+      topic: function() { db.onReady(this.callback); },
+      "from working": function(r) { }
+    }
+  }
+});
 
-  if (driver === 'mysql') {
-    // let's check to see if we can connect and render a nice
-    // error message if not.  For community members making casual
-    // contributions, we should expect that they might not want to
-    // set up mysql.
-    suite.addBatch({
-      "mysql server": {
-        topic: function() {
-          db.open(dbCfg, this.callback);
-        },
-        "accepting connections": function(err) {
-          if (err) {
-            console.log("MYSQL TESTS WILL FAIL cause cannot connect to a local mysql database (" + err.message + ")");
-          }
-        },
-        "connection closes": {
-          topic: function() { db.close(this.callback); },
-          "without error": function(err) {
-            assert.isUndefined(err);
-          }
-        }
-      }
-    });
+// caching of secrets between test batches.
+var secret = undefined;
+
+suite.addBatch({
+  "an email address is not reported as staged before it is": {
+    topic: function() {
+      db.isStaged('lloyd@nowhe.re', this.callback);
+    },
+    "isStaged returns false": function (r) {
+      assert.isFalse(r);
+    }
+  },
+  "an email address is not reported as known before it is": {
+    topic: function() {
+      db.emailKnown('lloyd@nowhe.re', this.callback);
+    },
+    "emailKnown returns false": function (r) {
+      assert.isFalse(r);
+    }
   }
+});
 
-  suite.addBatch({
-    "onReady": {
-      topic: function() { db.onReady(this.callback); },
-      "works": function(r) { }
+suite.addBatch({
+  "stage a user for creation pending verification": {
+    topic: function() {
+      db.stageUser({
+        email: 'lloyd@nowhe.re',
+        pubkey: 'fakepubkey',
+        hash: 'fakepasswordhash'
+      }, this.callback);
     },
-    "onReady still": {
-      topic: function() { db.onReady(this.callback); },
-      "works for more than one caller": function(r) { }
+    "staging returns a valid secret": function(r) {
+      secret = r;
+      assert.isString(secret);
+      assert.strictEqual(secret.length, 48);
+    }
+  }
+});
+
+suite.addBatch({
+  "an email address is reported": {
+    topic: function() {
+      db.isStaged('lloyd@nowhe.re', this.callback);
     },
-    "opening the database": {
-      topic: function() {
-        db.open(dbCfg, this.callback);
-      },
-      "and its ready": function(r) {
-        assert.isUndefined(r);
-      },
-      "doesn't prevent onReady": {
-        topic: function() { db.onReady(this.callback); },
-        "from working": function(r) { }
-      }
+    " as staged after it is": function (r) {
+      assert.strictEqual(r, true);
+    }
+  },
+  "an email address is not reported": {
+    topic: function() {
+      db.emailKnown('lloyd@nowhe.re', this.callback);
+    },
+    " as known when it is only staged": function (r) {
+      assert.strictEqual(r, false);
     }
-  });
+  }
+});
 
-  // caching of secrets between test batches.
-  var secret = undefined;
+suite.addBatch({
+  "upon receipt of a secret": {
+    topic: function() {
+      db.gotVerificationSecret(secret, this.callback);
+    },
+    "gotVerificationSecret completes without error": function (r) {
+      assert.strictEqual(r, undefined);
+    }
+  }
+});
 
-  suite.addBatch({
-    "an email address is not reported as staged before it is": {
-      topic: function() {
-        db.isStaged('lloyd@nowhe.re', this.callback);
-      },
-      "isStaged returns false": function (r) {
-        assert.isFalse(r);
-      }
+suite.addBatch({
+  "an email address is not reported": {
+    topic: function() {
+      db.isStaged('lloyd@nowhe.re', this.callback);
     },
-    "an email address is not reported as known before it is": {
-      topic: function() {
-        db.emailKnown('lloyd@nowhe.re', this.callback);
-      },
-      "emailKnown returns false": function (r) {
-        assert.isFalse(r);
-      }
+    "as staged immediately after its verified": function (r) {
+      assert.strictEqual(r, false);
     }
-  });
+  },
+  "an email address is known": {
+    topic: function() {
+      db.emailKnown('lloyd@nowhe.re', this.callback);
+    },
+    "when it is": function (r) {
+      assert.strictEqual(r, true);
+    }
+  }
+});
 
-  suite.addBatch({
-    "stage a user for creation pending verification": {
-      topic: function() {
-        db.stageUser({
-          email: 'lloyd@nowhe.re',
-          pubkey: 'fakepubkey',
-          hash: 'fakepasswordhash'
-        }, this.callback);
-      },
-      "staging returns a valid secret": function(r) {
-        secret = r;
-        assert.isString(secret);
-        assert.strictEqual(secret.length, 48);
-      }
+suite.addBatch({
+  "adding keys to email": {
+    topic: function() {
+      db.addKeyToEmail('lloyd@nowhe.re', 'lloyd@nowhe.re', 'fakepubkey2', this.callback);
+    },
+    "works": function(r) {
+      assert.isUndefined(r);
     }
-  });
+  }
+});
 
-  suite.addBatch({
-    "an email address is reported": {
-      topic: function() {
-        db.isStaged('lloyd@nowhe.re', this.callback);
-      },
-      " as staged after it is": function (r) {
-        assert.strictEqual(r, true);
-      }
+suite.addBatch({
+  "adding multiple keys to email": {
+    topic: function() {
+      db.addKeyToEmail('lloyd@nowhe.re', 'lloyd@nowhe.re', 'fakepubkey3', this.callback);
     },
-    "an email address is not reported": {
-      topic: function() {
-        db.emailKnown('lloyd@nowhe.re', this.callback);
-      },
-      " as known when it is only staged": function (r) {
-        assert.strictEqual(r, false);
-      }
+    "works too": function(r) {
+      assert.isUndefined(r);
     }
-  });
+  }
+});
 
-  suite.addBatch({
-    "upon receipt of a secret": {
-      topic: function() {
-        db.gotVerificationSecret(secret, this.callback);
-      },
-      "gotVerificationSecret completes without error": function (r) {
-        assert.strictEqual(r, undefined);
-      }
+suite.addBatch({
+  "pubkeysForEmail": {
+    topic: function() {
+      db.pubkeysForEmail('lloyd@nowhe.re', this.callback);
+    },
+    "returns all public keys properly": function(r) {
+      assert.isArray(r);
+      assert.strictEqual(r.length, 3);
     }
-  });
+  }
+});
 
-  suite.addBatch({
-    "an email address is not reported": {
-      topic: function() {
-        db.isStaged('lloyd@nowhe.re', this.callback);
-      },
-      "as staged immediately after its verified": function (r) {
-        assert.strictEqual(r, false);
-      }
+suite.addBatch({
+  "checkAuth returns": {
+    topic: function() {
+      db.checkAuth('lloyd@nowhe.re', this.callback);
     },
-    "an email address is known": {
-      topic: function() {
-        db.emailKnown('lloyd@nowhe.re', this.callback);
-      },
-      "when it is": function (r) {
-        assert.strictEqual(r, true);
-      }
+    "the correct password": function(r) {
+      assert.strictEqual(r, "fakepasswordhash");
     }
-  });
+  }
+});
 
-  suite.addBatch({
-    "adding keys to email": {
-      topic: function() {
-        db.addKeyToEmail('lloyd@nowhe.re', 'lloyd@nowhe.re', 'fakepubkey2', this.callback);
+suite.addBatch({
+  "staging an email": {
+    topic: function() {
+      db.stageEmail('lloyd@nowhe.re', 'lloyd@somewhe.re', 'fakepubkey4', this.callback);
+    },
+    "yields a valid secret": function(secret) {
+      assert.isString(secret);
+      assert.strictEqual(secret.length, 48);
+    },
+    "then": {
+      topic: function(secret) {
+        var cb = this.callback;
+        db.isStaged('lloyd@somewhe.re', function(r) { cb(secret, r); });
       },
-      "works": function(r) {
-        assert.isUndefined(r);
+      "makes it visible via isStaged": function(sekret, r) { assert.isTrue(r); },
+      "and lets you verify it": {
+        topic: function(secret, r) {
+          db.gotVerificationSecret(secret, this.callback);
+        },
+        "successfully": function(r) {
+          assert.isUndefined(r);
+        },
+        "and knownEmail": {
+          topic: function() { db.emailKnown('lloyd@somewhe.re', this.callback); },
+          "returns true": function(r) { assert.isTrue(r); }
+        },
+        "and isStaged": {
+          topic: function() { db.isStaged('lloyd@somewhe.re', this.callback); },
+          "returns false": function(r) { assert.isFalse(r); }
+        }
       }
     }
-  });
+  }
+});
 
-  suite.addBatch({
-    "adding multiple keys to email": {
+// exports.emailsBelongToSameAccount
+suite.addBatch({
+  "emails do belong to the same account": {
+    "is true": { 
       topic: function() {
-        db.addKeyToEmail('lloyd@nowhe.re', 'lloyd@nowhe.re', 'fakepubkey3', this.callback);
+        db.emailsBelongToSameAccount('lloyd@nowhe.re', 'lloyd@somewhe.re', this.callback);
       },
-      "works too": function(r) {
-        assert.isUndefined(r);
+      "when they do": function(r) {
+        assert.isTrue(r);
       }
-    }
-  });
-
-  suite.addBatch({
-    "pubkeysForEmail": {
+    },
+    "is false": { 
       topic: function() {
-        db.pubkeysForEmail('lloyd@nowhe.re', this.callback);
+        db.emailsBelongToSameAccount('lloyd@anywhe.re', 'lloyd@somewhe.re', this.callback);
       },
-      "returns all public keys properly": function(r) {
-        assert.isArray(r);
-        assert.strictEqual(r.length, 3);
+      "when they don't": function(r) {
+        assert.isFalse(r);
       }
     }
-  });
+  }
+});
 
-  suite.addBatch({
-    "checkAuth returns": {
+// exports.getSyncResponse
+suite.addBatch({
+  "sync responses": {  
+    "are empty": {
       topic: function() {
-        db.checkAuth('lloyd@nowhe.re', this.callback);
+        db.getSyncResponse('lloyd@nowhe.re',
+                           {
+                             'lloyd@nowhe.re': 'fakepubkey',
+                             'lloyd@somewhe.re': 'fakepubkey4'
+                           },
+                           this.callback);
       },
-      "the correct password": function(r) {
-        assert.strictEqual(r, "fakepasswordhash");
+      "when everything is in sync": function (err, resp) {
+        assert.isUndefined(err);
+        assert.isArray(resp.unknown_emails);
+        assert.isArray(resp.key_refresh);
+        assert.strictEqual(resp.unknown_emails.length, 0);
+        assert.strictEqual(resp.key_refresh.length, 0);
       }
-    }
-  });
-
-  suite.addBatch({
-    "staging an email": {
+    },
+    "handles client unknown emails": {
       topic: function() {
-        db.stageEmail('lloyd@nowhe.re', 'lloyd@somewhe.re', 'fakepubkey4', this.callback);
-      },
-      "yields a valid secret": function(secret) {
-        assert.isString(secret);
-        assert.strictEqual(secret.length, 48);
+        db.getSyncResponse('lloyd@nowhe.re',
+                           {
+                             'lloyd@nowhe.re': 'fakepubkey'
+                           },
+                           this.callback);
       },
-      "then": {
-        topic: function(secret) {
-          var cb = this.callback;
-          db.isStaged('lloyd@somewhe.re', function(r) { cb(secret, r); });
-        },
-        "makes it visible via isStaged": function(sekret, r) { assert.isTrue(r); },
-        "and lets you verify it": {
-          topic: function(secret, r) {
-            db.gotVerificationSecret(secret, this.callback);
-          },
-          "successfully": function(r) {
-            assert.isUndefined(r);
-          },
-          "and knownEmail": {
-            topic: function() { db.emailKnown('lloyd@somewhe.re', this.callback); },
-            "returns true": function(r) { assert.isTrue(r); }
-          },
-          "and isStaged": {
-            topic: function() { db.isStaged('lloyd@somewhe.re', this.callback); },
-            "returns false": function(r) { assert.isFalse(r); }
-          }
-        }
+      "by returning them in the key_refresh list": function (err, resp) {
+        assert.isUndefined(err);
+        assert.isArray(resp.unknown_emails);
+        assert.isArray(resp.key_refresh);
+        assert.strictEqual(resp.unknown_emails.length, 0);
+        assert.strictEqual(resp.key_refresh.length, 1);
+        assert.strictEqual(resp.key_refresh[0], 'lloyd@somewhe.re');
       }
-    }
-  });
-
-  // exports.emailsBelongToSameAccount
-  suite.addBatch({
-    "emails do belong to the same account": {
-      "is true": { 
-        topic: function() {
-          db.emailsBelongToSameAccount('lloyd@nowhe.re', 'lloyd@somewhe.re', this.callback);
-        },
-        "when they do": function(r) {
-          assert.isTrue(r);
-        }
+    },
+    "handles server unknown emails": {
+      topic: function() {
+        db.getSyncResponse('lloyd@nowhe.re',
+                           {
+                             'lloyd@nowhe.re': 'fakepubkey',
+                             'lloyd@somewhe.re': 'fakepubkey4',
+                             'lloyd@anywhe.re': 'nofakepubkey',
+                           },
+                           this.callback);
       },
-      "is false": { 
-        topic: function() {
-          db.emailsBelongToSameAccount('lloyd@anywhe.re', 'lloyd@somewhe.re', this.callback);
-        },
-        "when they don't": function(r) {
-          assert.isFalse(r);
-        }
+      "by returning them in the unknown_emails list": function (err, resp) {
+        assert.isUndefined(err);
+        assert.isArray(resp.unknown_emails);
+        assert.strictEqual(resp.unknown_emails.length, 1);
+        assert.strictEqual(resp.unknown_emails[0], 'lloyd@anywhe.re');
+        assert.isArray(resp.key_refresh);
+        assert.strictEqual(resp.key_refresh.length, 0);
       }
-    }
-  });
-
-  // exports.getSyncResponse
-  suite.addBatch({
-    "sync responses": {  
-      "are empty": {
-        topic: function() {
-          db.getSyncResponse('lloyd@nowhe.re',
-                             {
-                               'lloyd@nowhe.re': 'fakepubkey',
-                               'lloyd@somewhe.re': 'fakepubkey4'
-                             },
-                             this.callback);
-        },
-        "when everything is in sync": function (err, resp) {
-          assert.isUndefined(err);
-          assert.isArray(resp.unknown_emails);
-          assert.isArray(resp.key_refresh);
-          assert.strictEqual(resp.unknown_emails.length, 0);
-          assert.strictEqual(resp.key_refresh.length, 0);
-        }
-      },
-      "handles client unknown emails": {
-        topic: function() {
-          db.getSyncResponse('lloyd@nowhe.re',
-                             {
-                               'lloyd@nowhe.re': 'fakepubkey'
-                             },
-                             this.callback);
-        },
-        "by returning them in the key_refresh list": function (err, resp) {
-          assert.isUndefined(err);
-          assert.isArray(resp.unknown_emails);
-          assert.isArray(resp.key_refresh);
-          assert.strictEqual(resp.unknown_emails.length, 0);
-          assert.strictEqual(resp.key_refresh.length, 1);
-          assert.strictEqual(resp.key_refresh[0], 'lloyd@somewhe.re');
-        }
-      },
-      "handles server unknown emails": {
-        topic: function() {
-          db.getSyncResponse('lloyd@nowhe.re',
-                             {
-                               'lloyd@nowhe.re': 'fakepubkey',
-                               'lloyd@somewhe.re': 'fakepubkey4',
-                               'lloyd@anywhe.re': 'nofakepubkey',
-                             },
-                             this.callback);
-        },
-        "by returning them in the unknown_emails list": function (err, resp) {
-          assert.isUndefined(err);
-          assert.isArray(resp.unknown_emails);
-          assert.strictEqual(resp.unknown_emails.length, 1);
-          assert.strictEqual(resp.unknown_emails[0], 'lloyd@anywhe.re');
-          assert.isArray(resp.key_refresh);
-          assert.strictEqual(resp.key_refresh.length, 0);
-        }
-      },
-      "handles server unknown keys": {
-        topic: function() {
-          db.getSyncResponse('lloyd@nowhe.re',
-                             {
-                               'lloyd@nowhe.re': 'fakepubkeyINVALID',
-                               'lloyd@somewhe.re': 'fakepubkey4'
-                             },
-                             this.callback);
-        },
-        "by returning them in the key_refresh list": function (err, resp) {
-          assert.isUndefined(err);
-          assert.isArray(resp.unknown_emails);
-          assert.strictEqual(resp.unknown_emails.length, 0);
-          assert.isArray(resp.key_refresh);
-          assert.strictEqual(resp.key_refresh.length, 1);
-          assert.strictEqual(resp.key_refresh[0], 'lloyd@nowhe.re');
-        }
+    },
+    "handles server unknown keys": {
+      topic: function() {
+        db.getSyncResponse('lloyd@nowhe.re',
+                           {
+                             'lloyd@nowhe.re': 'fakepubkeyINVALID',
+                             'lloyd@somewhe.re': 'fakepubkey4'
+                           },
+                           this.callback);
       },
-      "handle more than one case at a time": {
-        topic: function() {
-          db.getSyncResponse('lloyd@nowhe.re',
-                             {
-                               'lloyd@somewhe.re': 'fakepubkeyINVALID',
-                               'lloyd@anywhe.re': 'notreally'
-                             },
-                             this.callback);
-        },
-        "when everything is outta sync": function (err, resp) {
-          assert.isUndefined(err);
-          assert.isArray(resp.unknown_emails);
-          assert.strictEqual(resp.unknown_emails.length, 1);
-          assert.strictEqual(resp.unknown_emails[0], 'lloyd@anywhe.re');
-
-          assert.isArray(resp.key_refresh);
-          assert.strictEqual(resp.key_refresh.length, 2);
-          assert.strictEqual(resp.key_refresh[0], 'lloyd@nowhe.re');
-          assert.strictEqual(resp.key_refresh[1], 'lloyd@somewhe.re');
-        }
+      "by returning them in the key_refresh list": function (err, resp) {
+        assert.isUndefined(err);
+        assert.isArray(resp.unknown_emails);
+        assert.strictEqual(resp.unknown_emails.length, 0);
+        assert.isArray(resp.key_refresh);
+        assert.strictEqual(resp.key_refresh.length, 1);
+        assert.strictEqual(resp.key_refresh[0], 'lloyd@nowhe.re');
       }
-    }
-  });
-
-  suite.addBatch({
-    "removing an existing email": {
+    },
+    "handle more than one case at a time": {
       topic: function() {
-        db.removeEmail("lloyd@somewhe.re", "lloyd@nowhe.re", this.callback);
-      },
-      "returns no error": function(r) {
-        assert.isUndefined(r);
+        db.getSyncResponse('lloyd@nowhe.re',
+                           {
+                             'lloyd@somewhe.re': 'fakepubkeyINVALID',
+                             'lloyd@anywhe.re': 'notreally'
+                           },
+                           this.callback);
       },
-      "causes emailKnown": {
-        topic: function() {
-          db.emailKnown('lloyd@nowhe.re', this.callback);
-        },
-        "to return false": function (r) {
-          assert.strictEqual(r, false);
-        }
+      "when everything is outta sync": function (err, resp) {
+        assert.isUndefined(err);
+        assert.isArray(resp.unknown_emails);
+        assert.strictEqual(resp.unknown_emails.length, 1);
+        assert.strictEqual(resp.unknown_emails[0], 'lloyd@anywhe.re');
+
+        assert.isArray(resp.key_refresh);
+        assert.strictEqual(resp.key_refresh.length, 2);
+        assert.strictEqual(resp.key_refresh[0], 'lloyd@nowhe.re');
+        assert.strictEqual(resp.key_refresh[1], 'lloyd@somewhe.re');
       }
     }
-  });
+  }
+});
 
-  suite.addBatch({
-    "canceling an account": {
+suite.addBatch({
+  "removing an existing email": {
+    topic: function() {
+      db.removeEmail("lloyd@somewhe.re", "lloyd@nowhe.re", this.callback);
+    },
+    "returns no error": function(r) {
+      assert.isUndefined(r);
+    },
+    "causes emailKnown": {
       topic: function() {
-        db.cancelAccount("lloyd@somewhe.re", this.callback);
-      },
-      "returns no error": function(r) {
-        assert.isUndefined(r);
+        db.emailKnown('lloyd@nowhe.re', this.callback);
       },
-      "causes emailKnown": {
-        topic: function() {
-          db.emailKnown('lloyd@somewhe.re', this.callback);
-        },
-        "to return false": function (r) {
-          assert.strictEqual(r, false);
-        }
+      "to return false": function (r) {
+        assert.strictEqual(r, false);
       }
     }
-  });
+  }
+});
 
-  suite.addBatch({
-    "closing the database": {
+suite.addBatch({
+  "canceling an account": {
+    topic: function() {
+      db.cancelAccount("lloyd@somewhe.re", this.callback);
+    },
+    "returns no error": function(r) {
+      assert.isUndefined(r);
+    },
+    "causes emailKnown": {
       topic: function() {
-        db.close(this.callback);
+        db.emailKnown('lloyd@somewhe.re', this.callback);
       },
-      "should work": function(err) {
-        assert.isUndefined(err);
+      "to return false": function (r) {
+        assert.strictEqual(r, false);
       }
     }
-  });
-
-  if (driver !== 'mysql') {
-    suite.addBatch({
-      "remove the database file": {
-        topic: function() {
-          fs.unlink(dbPath, this.callback);
-        },
-        "and unlink should not error": function(err) {
-          assert.isNull(err);
-        },
-        "and the file": {
-          topic: function() {
-            path.exists(dbPath, this.callback);
-          },
-          "should be missing": function(r) {
-            assert.isFalse(r);
-          }
-        }
-      }
-    });
   }
-}
-
-// test all available drivers
-files = fs.readdirSync(path.join(__dirname, "..", "lib"));
+});
 
-files.forEach(function(f) {
-  var m = /^db_(.+)\.js$/.exec(f);
-  if (m) {
-    addTestsForDriver(m[1]);
+suite.addBatch({
+  "closing the database": {
+    topic: function() {
+      db.close(this.callback);
+    },
+    "should work": function(err) {
+      assert.isUndefined(err);
+    }
   }
 });
 
diff --git a/browserid/tests/forgotten-email-test.js b/browserid/tests/forgotten-email-test.js
index 1e8d9e14727ddb204fca5fee58c29f65dc489144..1b4187f71251b7ecad44bd091ef474781d3c20f8 100755
--- a/browserid/tests/forgotten-email-test.js
+++ b/browserid/tests/forgotten-email-test.js
@@ -35,6 +35,8 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
+require('./lib/test_env.js');
+
 const assert = require('assert'),
 vows = require('vows'),
 start_stop = require('./lib/start-stop.js'),
diff --git a/browserid/tests/lib/test_env.js b/browserid/tests/lib/test_env.js
new file mode 100644
index 0000000000000000000000000000000000000000..a98816c4ad723f88d2654b44b2e0acc972965bfc
--- /dev/null
+++ b/browserid/tests/lib/test_env.js
@@ -0,0 +1,47 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla BrowserID.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Lloyd Hilaiel <lloyd@hilaiel.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* this zero-exports include file should be included by each of the tests.
+ * if NODE_ENV was not explicitly set to a test environment it will set
+ * NODE_ENV and issue a warning on the console to developers */ 
+
+if (undefined === process.env['NODE_ENV']) {
+  console.log("Setting NODE_ENV to test_json to test with the local JSON database");
+  console.log("To test with a local mysql database, setup mysql and set NODE_ENV to test_mysql");
+  process.env['NODE_ENV'] = 'test_json';
+} else if (process.env['NODE_ENV'].substr(0,5) !== 'test_') {
+  console.log("(Woah.  Running tests without a test_ configuration.  Is this *really* what you want?)");
+} 
diff --git a/browserid/tests/password-length-test.js b/browserid/tests/password-length-test.js
index 03b14f384ed93440ba0c8c2eb16fd858812a84bb..226810384d79432cd7fa707c4d3ffe3f5a3fc59a 100755
--- a/browserid/tests/password-length-test.js
+++ b/browserid/tests/password-length-test.js
@@ -35,6 +35,8 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
+require('./lib/test_env.js');
+
 const assert =
 require('assert'),
 vows = require('vows'),
diff --git a/browserid/tests/registration-status-wsapi-test.js b/browserid/tests/registration-status-wsapi-test.js
index 04fa127a9c61d69e220742cfb7267a890c208f91..54d6a4b3ee000723c8b78bf7319bce6a1a7813ae 100755
--- a/browserid/tests/registration-status-wsapi-test.js
+++ b/browserid/tests/registration-status-wsapi-test.js
@@ -35,6 +35,8 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
+require('./lib/test_env.js');
+
 const
 assert = require('assert'),
 vows = require('vows'),
diff --git a/libs/configuration.js b/libs/configuration.js
index faec8c14542e74230cc29ae0e1333d47f09b4ab4..1f6b993850eb1b967a61e8438bb87de97c72def6 100644
--- a/libs/configuration.js
+++ b/libs/configuration.js
@@ -94,6 +94,13 @@ g_configs.local =  {
   database: { driver: "json" }
 };
 
+// test environments are variations on local
+g_configs.test_json = JSON.parse(JSON.stringify(g_configs.local));
+g_configs.test_json.database = { driver: "json", unit_test: true }; 
+
+g_configs.test_mysql = JSON.parse(JSON.stringify(g_configs.local));
+g_configs.test_mysql.database = { driver: "mysql", user: "test", unit_test: true }; 
+
 // default deployment is local
 if (undefined === process.env['NODE_ENV']) {
   process.env['NODE_ENV'] = 'local';
diff --git a/test.sh b/test.sh
index a0ef1563a8e8f5556edc3d85fce2c29c7936278f..7c77d81e7e49ed83519ef3e51a052826b310a5bf 100755
--- a/test.sh
+++ b/test.sh
@@ -6,9 +6,13 @@ if [ ! -x "$VOWS" ]; then
     exit 1
 fi
 
-for file in browserid/tests/*.js ; do
-    vows $file
-    if [[ $? != 0 ]] ; then
-        exit 1
-    fi
+for env in test_json test_mysql ; do
+  export NODE_ENV=$env
+  echo "Testing with NODE_ENV=$env"
+  for file in browserid/tests/*.js ; do
+      vows $file
+      if [[ $? != 0 ]] ; then
+          exit 1
+      fi
+  done
 done