class names */ public static function _findTestClasses($path) { // print_r(array( // 'loading' => $path, // get_included_files() // )); $origClasses = get_declared_classes(); require_once $path; $newClasses = get_declared_classes(); return preg_grep('/Test$/', array_diff( $newClasses, $origClasses )); } /** * @param $paths * @return array (string $file => string $class) * @throws \Exception */ public static function findTestClasses($paths) { $testClasses = []; $finder = new Finder(); foreach ($paths as $path) { if (is_dir($path)) { foreach ($finder->files()->in($paths)->name('*Test.php') as $file) { $testClass = self::_findTestClasses((string) $file); if (count($testClass) == 1) { $testClasses[(string) $file] = array_shift($testClass); } elseif (count($testClass) > 1) { throw new \Exception("Too many classes in $file"); } else { throw new \Exception("Too few classes in $file"); } } } elseif (is_file($path)) { $testClass = self::_findTestClasses($path); if (count($testClass) == 1) { $testClasses[$path] = array_shift($testClass); } elseif (count($testClass) > 1) { throw new \Exception("Too many classes in $path"); } else { throw new \Exception("Too few classes in $path"); } } } return $testClasses; } /** * @param array $paths * * @return array * each element is an array with keys: * - file: string * - class: string * - method: string */ public static function findTestsByPath($paths) { $r = []; $testClasses = self::findTestClasses($paths); foreach ($testClasses as $testFile => $testClass) { $clazz = new \ReflectionClass($testClass); foreach ($clazz->getMethods() as $method) { if (preg_match('/^test/', $method->name)) { $r[] = [ 'file' => $testFile, 'class' => $testClass, 'method' => $method->name, ]; } } } return $r; } }