diff --git a/tests/mollom.test b/tests/mollom.test
index ab27d62..81ff136 100644
--- a/tests/mollom.test
+++ b/tests/mollom.test
@@ -558,6 +558,8 @@ class MollomWebTestCase extends DrupalWebTestCase {
    * Assert that the CAPTCHA field is not found on the current page.
    */
   protected function assertNoCaptchaField() {
+    $this->assertNoText($this->unsure_message);
+    $this->assertNoText($this->incorrect_message);
     $this->assertNoFieldByXPath('//input[@type="text"][@name="mollom[captcha]"]', '', 'CAPTCHA field not found.');
     $image = $this->xpath('//img[@alt=:alt]', array(':alt' => t('Type the characters you see in this picture.')));
     $this->assert(empty($image), 'CAPTCHA image not found.');
@@ -963,6 +965,24 @@ class MollomWebTestCase extends DrupalWebTestCase {
     //variable_set('cache_lifetime', 60);
   }
 
+  /**
+   * Asserts a successful mollom_test_form submission.
+   *
+   * @param $old_mid
+   *   (optional) The existing test record id to assert.
+   */
+  protected function assertTestSubmitData($old_mid = NULL) {
+    $this->assertText('Successful form submission.');
+    $mid = $this->getFieldValueByName('mid');
+    if (isset($old_mid)) {
+      $this->assertSame('Test record id', $mid, $old_mid);
+    }
+    else {
+      $this->assertTrue($mid > 0, t('Test record id @id found.', array('@id' => $mid)));
+    }
+    return $mid;
+  }
+
 }
 
 /**
@@ -3850,11 +3870,6 @@ class MollomAnalysisTestCase extends MollomWebTestCase {
     $this->setKeys(TRUE, TRUE);
     $this->assertValidKeys();
 
-    $this->admin_user = $this->drupalCreateUser(array(
-      'access administration pages',
-      'administer mollom',
-    ));
-
     $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS);
   }
 
@@ -4052,24 +4067,6 @@ class MollomAnalysisTestCase extends MollomWebTestCase {
     $this->assertNoCaptchaField();
     $this->assertTestSubmitData();
   }
-
-  /**
-   * Asserts a successful mollom_test_form submission.
-   *
-   * @param $old_mid
-   *   (optional) The existing test record id to assert.
-   */
-  protected function assertTestSubmitData($old_mid = NULL) {
-    $this->assertText('Successful form submission.');
-    $mid = $this->getFieldValueByName('mid');
-    if (isset($old_mid)) {
-      $this->assertSame('Test record id', $mid, $old_mid);
-    }
-    else {
-      $this->assertTrue($mid > 0, t('Test record id @id found.', array('@id' => $mid)));
-    }
-    return $mid;
-  }
 }
 
 /**
@@ -4402,23 +4399,6 @@ class MollomAnalysisOptionsTestCase extends MollomWebTestCase {
     }
   }
 
-  /**
-   * Asserts a successful mollom_test_form submission.
-   *
-   * @param $old_mid
-   *   (optional) The existing test record id to assert.
-   */
-  protected function assertTestSubmitData($old_mid = NULL) {
-    $this->assertText('Successful form submission.');
-    $mid = $this->getFieldValueByName('mid');
-    if (isset($old_mid)) {
-      $this->assertSame('Test record id', $mid, $old_mid);
-    }
-    else {
-      $this->assertTrue($mid > 0, t('Test record id @id found.', array('@id' => $mid)));
-    }
-    return $mid;
-  }
 }
 
 /**
@@ -4482,11 +4462,11 @@ class MollomAnalysisPageCachingTestCase extends MollomWebTestCase {
  * Tests CAPTCHA functionality.
  */
 class MollomCaptchaTestCase extends MollomWebTestCase {
+  protected $disableDefaultSetup = TRUE;
+
   // Re-route Mollom communication to this testing site.
   protected $mollomClass = 'MollomDrupalTestLocal';
 
-  protected $disableDefaultSetup = TRUE;
-
   public static function getInfo() {
     return array(
       'name' => 'CAPTCHA',
@@ -4497,24 +4477,26 @@ class MollomCaptchaTestCase extends MollomWebTestCase {
 
   function setUp() {
     parent::setUp(array('mollom', 'mollom_test'));
-    $this->setKeys();
+    $this->setKeys(TRUE, TRUE);
     $this->assertValidKeys();
 
-    $this->admin_user = $this->drupalCreateUser(array(
-      'access administration pages',
-      'administer mollom',
-    ));
-    $this->web_user = $this->drupalCreateUser(array());
+    $this->setProtection('mollom_test_form', MOLLOM_MODE_CAPTCHA);
+  }
 
-    $this->drupalLogin($this->admin_user);
-    $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_CAPTCHA);
-    $this->drupalLogout();
+  function testCAPTCHA() {
+    $methods = get_class_methods($this);
+    foreach ($methods as $method) {
+      if (substr($method, 0, 7) === 'subtest') {
+        //debug($method);
+        $this->$method();
+      }
+    }
   }
 
   /**
    * Tests #required validation of CAPTCHA form element.
    */
-  function testRequiredValidation() {
+  function subtestCAPTCHARequired() {
     $this->drupalGet('mollom-test/form');
 
     // Verify that CAPTCHA cannot be left empty.
@@ -4535,18 +4517,28 @@ class MollomCaptchaTestCase extends MollomWebTestCase {
     );
     $this->postIncorrectCaptcha(NULL, $edit, 'Submit', 'Successful form submission.');
 
-    // Lastly, verify correct solution.
+    // Verify correct solution, but trigger other validation errors.
     $edit = array(
+      'title' => '',
       'mollom[captcha]' => 'correct',
     );
     $this->drupalPost(NULL, $edit, 'Submit');
+    $this->assertNoCaptchaField();
+    $this->assertNoText('Successful form submission.');
+
+    // Lastly, confirm we're able to submit.
+    $edit = array(
+      'title' => $this->randomString(),
+    );
+    $this->drupalPost(NULL, $edit, 'Submit');
+    $this->assertNoText($this->incorrect_message);
     $this->assertTestSubmitData();
   }
 
   /**
    * Tests incorrect solution of CAPTCHA form element.
    */
-  function testIncorrect() {
+  function subtestCAPTCHAIncorrect() {
     $this->drupalGet('mollom-test/form');
 
     // Verify that incorrect solution still leaves the field required.
@@ -4564,42 +4556,51 @@ class MollomCaptchaTestCase extends MollomWebTestCase {
   }
 
   /**
-   * Tests correct solution of CAPTCHA form element.
+   * Tests correct solution of CAPTCHA.
    */
-  function testCorrect() {
+  function subtestCAPTCHACorrect() {
     $this->drupalGet('mollom-test/form');
 
-    // Verify that CAPTCHA can be solved in one shot.
     $edit = array(
-      'title' => $this->randomString(),
       'mollom[captcha]' => 'correct',
     );
     $this->drupalPost(NULL, $edit, 'Submit');
+    $this->assertNoCaptchaField();
+    $this->assertNoText('Successful form submission.');
+
+    $edit = array(
+      'body' => $this->randomString(),
+    );
+    $this->drupalPost(NULL, $edit, 'Submit');
+    $this->assertNoCaptchaField();
+    $this->assertNoText('Successful form submission.');
+
+    $edit = array(
+      'title' => $this->randomString(),
+    );
+    $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertTestSubmitData();
   }
 
   /**
-   * Asserts a successful mollom_test_form submission.
-   *
-   * @param $old_mid
-   *   (optional) The existing test record id to assert.
+   * Tests correct solution of CAPTCHA in a single pass.
    */
-  protected function assertTestSubmitData($old_mid = NULL) {
-    $this->assertText('Successful form submission.');
-    $mid = $this->getFieldValueByName('mid');
-    if (isset($old_mid)) {
-      $this->assertSame('Test record id', $mid, $old_mid);
-    }
-    else {
-      $this->assertTrue($mid > 0, t('Test record id @id found.', array('@id' => $mid)));
-    }
-    return $mid;
+  function subtestCAPTCHACorrectSinglePass() {
+    $this->drupalGet('mollom-test/form');
+
+    // Verify that CAPTCHA can be solved in one shot.
+    $edit = array(
+      'title' => $this->randomString(),
+      'mollom[captcha]' => 'correct',
+    );
+    $this->drupalPost(NULL, $edit, 'Submit');
+    $this->assertTestSubmitData();
   }
 
   /**
    * Tests the CAPTCHA type switch callback.
    */
-  function testSwitchCallback() {
+  function subtestCAPTCHASwitchCallback() {
     // Verify that the CAPTCHA can be switched on a CAPTCHA-only protected form.
     // (without having a contentId)
     $this->drupalGet('mollom-test/form');
@@ -4625,6 +4626,102 @@ class MollomCaptchaTestCase extends MollomWebTestCase {
 }
 
 /**
+ * Tests CAPTCHA with page cache.
+ */
+class MollomCaptchaPageCacheTestCase extends MollomCaptchaTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'CAPTCHA (page cache)',
+      'description' => 'Tests CAPTCHA with page cache.',
+      'group' => 'Mollom',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->enablePageCache();
+
+    // Prime the page + form cache.
+    $this->drupalGet('mollom-test/form');
+    $this->assertText('Views: 1');
+    $this->drupalGet('mollom-test/form');
+    $this->assertText('Views: 2');
+  }
+}
+
+/**
+ * Tests CAPTCHA with page and form cache.
+ */
+class MollomCaptchaPageFormCacheTestCase extends MollomCaptchaTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'CAPTCHA (page + form cache)',
+      'description' => 'Tests CAPTCHA with page and form cache.',
+      'group' => 'Mollom',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->enablePageCache();
+    variable_set('mollom_test.form.cache', TRUE);
+
+    // Prime the page + form cache.
+    $this->drupalGet('mollom-test/form');
+    $this->assertText('Views: 1');
+    $this->drupalGet('mollom-test/form');
+    $this->assertText('Views: 2');
+  }
+}
+
+/**
+ * Tests CAPTCHA as authenticated user.
+ */
+class MollomCaptchaAuthenticatedTestCase extends MollomCaptchaTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'CAPTCHA (authenticated)',
+      'description' => 'Tests CAPTCHA as authenticated user.',
+      'group' => 'Mollom',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->web_user = $this->drupalCreateUser(array());
+    $this->drupalLogin($this->web_user);
+  }
+}
+
+/**
+ * Tests CAPTCHA as authenticated user with enabled page and form cache.
+ */
+class MollomCaptchaAuthenticatedPageFormCacheTestCase extends MollomCaptchaTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'CAPTCHA (authenticated + page + form cache)',
+      'description' => 'Tests CAPTCHA as authenticated user with enabled page and form cache.',
+      'group' => 'Mollom',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->enablePageCache();
+    variable_set('mollom_test.form.cache', TRUE);
+
+    // Prime the page + form cache.
+    $this->drupalGet('mollom-test/form');
+    $this->assertText('Views: 1');
+    $this->drupalGet('mollom-test/form');
+    $this->assertText('Views: 2');
+
+    $this->web_user = $this->drupalCreateUser(array());
+    $this->drupalLogin($this->web_user);
+  }
+}
+
+/**
  * Tests report to Mollom functionality.
  */
 class MollomReportTestCase extends MollomWebTestCase {
