Wouldn't the --testdox option on PHPUnit provide you with the same information on CLI or other formats too!?
Nov 21, 2018
2
Level 14
I Forget Test Methods
Greetings,
I wrote an artisan command to compensate for my constantly losing sight of what test methods I've already written for a project. While I am certain this is wheel already exists, I couldn't find it in all the other wheels. ....I'm not even sure which wheel yard to look in actually.
Maybe someone can tell me which wheel I reinvented.
Btw, this should work, on it's own, dropped into app/Console/Commands.
<?php
namespace App\Console\Commands;
use App\TestFinder;
use Illuminate\Console\Command;
class FindTests extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'goat:list-tests';
/**
* The console command description.
*
* @var string
*/
protected $description = 'List methods starting with \'test_\' in test files ending in \'Test.php\'';
/**
* Path to test files
* @var string
*/
public $tests_path;
/**
* The suffix at the end of test file names
* @var string
*/
public $testfile_suffix = 'Test.php';
/**
* The prefix used on methods in tests
* @var string
*/
public $testmethod_prefix = 'test_';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
$this->tests_path = base_path('tests/Feature');
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$table_headers = ['Class', 'Tests'];
$results = $this->getAll()->map(function($test_class, $key) {
return [
'class' => $test_class['class_name'],
'tests' => implode("\n", $this->getTestMethods($test_class['class_name'])) . "\n"
];
});
$this->table($table_headers, $results);
}
/**
* Create the whole dataset to return
* @return collection
*/
protected function getAll()
{
$all_classes_with_their_methods = collect();
$this->getTestClassesWithFullPaths()->each(function($fq_class_name, $key) use ($all_classes_with_their_methods) {
$all_classes_with_their_methods->push(collect([
'class_name' => $fq_class_name,
'methods' => $this->getTestMethods($fq_class_name)
]));
});
return $all_classes_with_their_methods;
}
/**
* Get all test classes with paths
* @return collection
*/
protected function getTestClassesWithFullPaths()
{
$test_classes = $this->getTestFiles()->map(function($filename, $key) {
return 'Tests\Feature\' . str_before($filename, '.php');
});
return $test_classes;
}
/**
* Filter out any filenames that don't end with $this->testfile_suffix
* @return collection
*/
protected function getTestFiles()
{
$test_files = $this->scanDir()->filter(function($filename, $key) {
return ends_with($filename, $this->testfile_suffix);
});
return $test_files;
}
/**
* Filter all the methods to grab just the ones that start with test_
*
* @param string $class_name Class name with path
* @return array
*/
protected function getTestMethods($class_name)
{
$test_methods = collect(get_class_methods(new $class_name))->filter(function($method, $key) {
return starts_with($method, $this->testmethod_prefix);
});
return $test_methods->toArray() ?: ['no tests'];
}
/**
* This is a raw scandir, so you'll get "." and ".." along with
* every other file in $this->tests_path;
*
* @return collection List of files and directories
*/
protected function scanDir()
{
return collect(scandir($this->tests_path));
}
}
Level 104
Please or to participate in this conversation.