Restore execution of CaseActivityTest
authorTim Otten <totten@civicrm.org>
Wed, 25 Jan 2023 04:34:04 +0000 (20:34 -0800)
committerTim Otten <totten@civicrm.org>
Wed, 25 Jan 2023 05:00:46 +0000 (21:00 -0800)
Following eb92dd792c07e0b11ee1561cf00930402345e8b3, the `CaseActivityTest` started to run
only intermittently. Why?

__high-level__: `Civi\Core\ClassScanner` and `phpunit8` both do a scan over the folder `tests/phpunit/CRM/Case/WorkflowMessage`

__low-level__: `Civi\Core\ClassScanner` has caching. Depending on the state of the cache, it may or may not do a scan:

* If the cache is filled, then `ClassScanner` doesn't need to scan.
    * When `phpunit8` subsequently does a scan, it will load `CaseActivityTest.php` normally.
* If the cache is empty, then `ClassScanner` does the first scan. It is the one that actually loads `CaseActivityTest.php`.
    * Later, `phpunit8` does a scan. Due to a quirk, it doesn't realize the class exists.

The scanner in phpunit works roughly like this:

```php
$tests = [];
foreach (glob('*Test.php') as $file) {
  $before = get_declared_classes();
  require_once $file;
  $after = get_declared_classes();
  $tests = array_merge($tests, array_diff($before, $after));
}
```

So if the class was previously loaded, then phpunit doesn't see it.

tests/phpunit/CiviTest/bootstrap.php

index 4623fd4818129331fb12ad29cba79189990a49e9..a12fc9923577393a117c3c5e361e65299f97e5ea 100644 (file)
@@ -17,8 +17,9 @@ $GLOBALS['CIVICRM_FORCE_MODULES'][] = 'civitest';
 function civitest_civicrm_scanClasses(array &$classes): void {
   $phpunit = \Civi::paths()->getPath('[civicrm.root]/tests/phpunit');
   if (strpos(get_include_path(), $phpunit) !== FALSE) {
-    \Civi\Core\ClassScanner::scanFolders($classes, $phpunit, 'CRM/*/WorkflowMessage', '_');
-    \Civi\Core\ClassScanner::scanFolders($classes, $phpunit, 'Civi/*/WorkflowMessage', '\\');
+    \Civi\Core\ClassScanner::scanFolders($classes, $phpunit, 'CRM/*/WorkflowMessage', '_', '/Test$/');
+    \Civi\Core\ClassScanner::scanFolders($classes, $phpunit, 'Civi/*/WorkflowMessage', '\\', '/Test$/');
+    // Exclude all `*Test.php` files - if we load them, then phpunit gets confused.
   }
 }