CiviUnitTestCase - Fix miscoordination with CiviEnvBuilder
authorTim Otten <totten@civicrm.org>
Thu, 15 Dec 2022 04:13:08 +0000 (20:13 -0800)
committerTim Otten <totten@civicrm.org>
Thu, 15 Dec 2022 05:14:22 +0000 (21:14 -0800)
Background
----------

Recall that `CiviUnitTestCase` and `CiviEnvBuilder` are two different
implementations of a similar concept.

* `Concept`: If two tests use the same baseline DB/environment, and if they
  preserve the baseline, then you don't need to reset everything in between
  tests.  But if they change, then you need to reset.

* `CiviUnitTestCase`: The older rendition.  Tightly coupled.  Only allows
  one specific baseline.  Mingled with a lot of unrelated functionality in
  `CiviUnitTestCase`.

* `CiviEnvBuilder`: The newer rendition.  Loosely coupled.  Allows different
  baselines.  Can be mixed into any plain-old `TestCase`.  Used by
  `Civi\Test::headless()` and `Civi\Test::e2e()`.

Problem Scenario
----------------

Suppose you have a mix of different tests running with the same DB -- e.g.

1. Run some tests based on `CiviEnvBuilder`
2. Run some tests based on `CiviUnitTestCase`
3. Run some tests based on `CiviEnvBuilder`

This wasn't originally anticipated, but it can happen -- either because
the test-suite is large+mixed, or because a developer is manually
running specific tests (which happen to be written differently).

The problem goes like this:

1. Run some tests based on `CiviEnvBuilder`
    * This resets the DB and also stores a DB signature. ("Here is how
      we setup the DB...")
2. Run some tests based on `CiviUnitTestCase`
    * This resets the DB, but leaves the old DB signature in place.
3. Run some tests based on `CiviEnvBuilder`
    * This sees the old DB signature and wrongly concludes that we
      still have the DB from step (1).

Solution
--------

Whenever one resets the DB, it should update the DB signature.

tests/phpunit/CiviTest/CiviUnitTestCase.php

index 0267d64048f459707598249d5e9cf53eb30f35ce..304456c6e78458fbfaf1c3274c9ade83070fe2a1 100644 (file)
@@ -343,6 +343,10 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase {
 
     Civi\Test::data()->populate();
 
+    // `CiviUnitTestCase` has replaced the baseline DB configuration. To coexist with other
+    // tests based on `CiviEnvBuilder`, we need to store a signature marking the current DB configuration.
+    (new \Civi\Test\CiviEnvBuilder())->callback(function(){}, 'CiviUnitTestCase')->apply(TRUE);
+
     return TRUE;
   }