From cbf6ced732cfa27bdf7d492604696e01d7657da9 Mon Sep 17 00:00:00 2001
From: hfuecks <hfuecks@gmail.com>
Date: Wed, 12 Oct 2005 10:10:13 +0200
Subject: [PATCH] test_suite_tuning

darcs-hash:20051012081013-e96b6-df581e5b94bb5e5ea1ed8693e754fd5877fbd164.gz
---
 test/index.php                |  50 ++++-----
 test/lib/cli_reporter.php     |   1 -
 test/lib/rss_writer_class.php |   1 -
 test/lib/testmanager.php      | 111 ++++++++++++-------
 test/lib/web.inc.php          |   1 -
 test/lib/xml_writer_class.php |   1 -
 test/remotetests.php          | 200 ++++++++++++++++++----------------
 test/runtests.php             |  51 ++++++---
 8 files changed, 237 insertions(+), 179 deletions(-)

diff --git a/test/index.php b/test/index.php
index b73732712..9b20cee39 100644
--- a/test/index.php
+++ b/test/index.php
@@ -10,6 +10,7 @@ ini_set('memory_limit','128M');
 /* Used to determine output to display */
 define('DW_TESTS_OUTPUT_HTML',1);
 define('DW_TESTS_OUTPUT_XML',2);
+
 if ( isset($_GET['output']) && $_GET['output'] == 'xml' ) {
     define('DW_TESTS_OUTPUT',DW_TESTS_OUTPUT_XML);
 } else {
@@ -91,9 +92,7 @@ function DW_TESTS_PaintSuiteHeader() {
         default:
             echo "<h1>Dokuwiki: Unit Test Suite</h1>\n";
             echo "<p><a href='index.php?show=groups'>Test groups</a>";
-            echo " || <a href='index.php?show=cases'>Test cases</a>";
-            echo " || <a href='index.php?show=webgroups'>Web Test Groups</a>";
-	    echo " || <a href='index.php?show=webcases'>Web Test Cases</a></p>";
+            echo " || <a href='index.php?show=cases'>Test cases</a></p>";
         break;
     }
 }
@@ -101,11 +100,11 @@ function DW_TESTS_PaintSuiteHeader() {
 function DW_TESTS_PaintCaseList() {
     switch ( DW_TESTS_OUTPUT ) {
         case DW_TESTS_OUTPUT_XML:
-            //echo XMLTestManager::getTestCaseList(TEST_CASES);
+            echo XMLTestManager::getTestCaseList(TEST_CASES);
         break;
         case DW_TESTS_OUTPUT_HTML:
         default:
-            //echo HTMLTestManager::getTestCaseList(TEST_CASES);
+            echo HTMLTestManager::getTestCaseList(TEST_CASES);
         break;
     }
 }
@@ -113,11 +112,11 @@ function DW_TESTS_PaintCaseList() {
 function DW_TESTS_PaintGroupTestList() {
     switch ( DW_TESTS_OUTPUT ) {
         case DW_TESTS_OUTPUT_XML:
-            //echo XMLTestManager::getGroupTestList(TEST_GROUPS);
+            echo XMLTestManager::getGroupTestList(TEST_GROUPS);
         break;
         case DW_TESTS_OUTPUT_HTML:
         default:
-            //echo HTMLTestManager::getGroupTestList(TEST_GROUPS);
+            echo HTMLTestManager::getGroupTestList(TEST_GROUPS);
         break;
     }
 }
@@ -138,23 +137,25 @@ EOD;
 }
 
 /** OUTPUT STARTS HERE **/
-
-// If it's a group test
-if (isset($_GET['run'])) {
-	switch ( $_GET['run'] ) {
-        /*
-	TestManager::runGroupTest(ucfirst($_GET['run']),
-                                  TEST_GROUPS,
-                                  DW_TESTS_GetReporter());
-	TestManager::runTestCase($_GET['case'], DW_TESTS_GetReporter());
-				  DW_TESTS_PaintRunMore();
-	*/
-		default:
-			TestManager::runAllTests(DW_TESTS_GetReporter());
-		break;
-	}
-    DW_TESTS_PaintRunMore();
-    exit();
+
+// If it's a group test
+if (isset($_GET['group'])) {
+    if ('all' == $_GET['group']) {
+        TestManager::runAllTests(DW_TESTS_GetReporter());
+    } else {
+        TestManager::runGroupTest(ucfirst($_GET['group']),
+                                  TEST_GROUPS,
+                                  DW_TESTS_GetReporter());
+    }
+    DW_TESTS_PaintRunMore();
+    exit();
+}
+
+// If it's a single test case
+if (isset($_GET['case'])) {
+    TestManager::runTestCase($_GET['case'], TEST_CASES, DW_TESTS_GetReporter());
+    DW_TESTS_PaintRunMore();
+    exit();
 }
 
 // Else it's the main page
@@ -170,4 +171,3 @@ if (isset($_GET['show']) && $_GET['show'] == 'cases') {
 }
 
 DW_TESTS_PaintFooter();
-?>
\ No newline at end of file
diff --git a/test/lib/cli_reporter.php b/test/lib/cli_reporter.php
index e5eb76697..a65112a34 100644
--- a/test/lib/cli_reporter.php
+++ b/test/lib/cli_reporter.php
@@ -89,4 +89,3 @@ class CLIReporter extends SimpleReporter {
         }
     }
 }
-?>
diff --git a/test/lib/rss_writer_class.php b/test/lib/rss_writer_class.php
index 7b9beae5f..684acfcfa 100644
--- a/test/lib/rss_writer_class.php
+++ b/test/lib/rss_writer_class.php
@@ -367,4 +367,3 @@ class rss_writer_class extends xml_writer_class
 };
 
 }
-?>
\ No newline at end of file
diff --git a/test/lib/testmanager.php b/test/lib/testmanager.php
index 6ad53b00d..abfef440f 100644
--- a/test/lib/testmanager.php
+++ b/test/lib/testmanager.php
@@ -2,12 +2,14 @@
 /**
 * Lots TODO here...
 */
+
+define('TEST_GROUPS',realpath(dirname(__FILE__).'/../cases'));
+define('TEST_CASES',realpath(dirname(__FILE__).'/../cases'));
+
 class TestManager {
     var $_testcase_extension = '.test.php';
     var $_grouptest_extension = '.group.php';
-    var $_webtest_extension = '.webtest.php';
-    var $_webgrouptest_extension = '.webgroup.php';
-
+    
     function setup() {
         $ini_file = realpath(dirname(__FILE__).'/../tests.ini');
 	
@@ -21,7 +23,7 @@ class TestManager {
         }
         TestManager::_installSimpleTest();
     }
-
+    
     function _installSimpleTest() {
         require_once SIMPLE_TEST . 'unit_tester.php';
         require_once SIMPLE_TEST . 'web_tester.php';
@@ -39,9 +41,28 @@ class TestManager {
         $test->run($reporter);
     }
 
-    function runTestCase($testcase_file, &$reporter) {
+    function runTestCase($testcase_name, $test_case_directory, &$reporter) {
         $manager =& new TestManager();
+        
+        $testcase_name = preg_replace('/[^a-zA-Z_:]/','',$testcase_name);
+        $testcase_name = str_replace(':',DIRECTORY_SEPARATOR,$testcase_name);
+        
+        $testcase_file = $test_case_directory . DIRECTORY_SEPARATOR .
+            strtolower($testcase_name) . $manager->_testcase_extension;
+        
+        if (! file_exists($testcase_file)) {
+            trigger_error("Test case {$testcase_file} cannot be found",
+                          E_USER_ERROR);
+        }
 
+        $test =& new GroupTest("Individual test case: " . $testcase_name);
+        $test->addTestFile($testcase_file);
+        $test->run($reporter);
+    }
+    
+    function runTestFile($testcase_file, &$reporter) {
+        $manager =& new TestManager();
+        
         if (! file_exists($testcase_file)) {
             trigger_error("Test case {$testcase_file} cannot be found",
                           E_USER_ERROR);
@@ -54,7 +75,8 @@ class TestManager {
 
     function runGroupTest($group_test_name, $group_test_directory, &$reporter) {
         $manager =& new TestManager();
-
+        $group_test_name = preg_replace('/[^a-zA-Z_:]/','',$group_test_name);
+        $group_test_name = str_replace(':',DIRECTORY_SEPARATOR,$group_test_name);
         $file_path = $group_test_directory . DIRECTORY_SEPARATOR .
             strtolower($group_test_name) . $manager->_grouptest_extension;
 
@@ -85,10 +107,14 @@ class TestManager {
     }
 
     function &_getTestCaseList($directory = '.') {
+        $base = TEST_GROUPS . DIRECTORY_SEPARATOR;
         $file_list =& $this->_getTestFileList($directory);
         $testcases = array();
         foreach ($file_list as $testcase_file) {
-            $testcases[$testcase_file] = str_replace($directory . '/', '', $testcase_file);
+            $case = str_replace($this->_testcase_extension, '',$testcase_file);
+            $case = str_replace($base, '', $case);
+            $case = str_replace(DIRECTORY_SEPARATOR, ':', $case);
+            $testcases[$testcase_file] = $case;
         }
         return $testcases;
     }
@@ -109,11 +135,14 @@ class TestManager {
     }
 
     function &_getTestGroupList($directory = '.') {
+        $base = TEST_GROUPS . DIRECTORY_SEPARATOR;
         $file_list =& $this->_getTestGroupFileList($directory);
         $grouptests = array();
         foreach ($file_list as $grouptest_file) {
-            $grouptests[$grouptest_file] = str_replace($this->_grouptest_extension, '',
-                                                       basename($grouptest_file));
+            $group = str_replace($this->_grouptest_extension, '',$grouptest_file);
+            $group = str_replace($base, '', $group);
+            $group = str_replace(DIRECTORY_SEPARATOR, ':', $group);
+            $grouptests[$grouptest_file] = $group;
         }
         sort($grouptests);
         return $grouptests;
@@ -190,8 +219,8 @@ class CLITestManager extends TestManager {
         $test_cases =& $manager->_getTestCaseList($directory);
 
         $buffer = "Available test cases:\n";
-        foreach ($test_cases as $test_case_file => $test_case) {
-            $buffer .= "  " . $test_case_file . "\n";
+        foreach ($test_cases as $test_case) {
+            $buffer .= "  " . $test_case . "\n";
         }
         return $buffer . "\n";
     }
@@ -211,7 +240,6 @@ class HTMLTestManager extends TestManager {
     function &getGroupTestList($directory = '.') {
         $manager =& new HTMLTestManager();
         $group_tests =& $manager->_getTestGroupList($directory);
-
         if (1 > count($group_tests)) {
             return "<p>No test groups set up!</p>";
         }
@@ -232,9 +260,9 @@ class HTMLTestManager extends TestManager {
             return "<p>No test cases set up!</p>";
         }
         $buffer = "<p>Available test cases:</p>\n<ul>";
-        foreach ($testcases as $testcase_file => $testcase) {
+        foreach ($testcases as $testcase) {
             $buffer .= "<li><a href='" . $manager->getBaseURL() .
-                "?case=" . urlencode($testcase_file) . "'>" .
+                "?case=" . urlencode($testcase) . "'>" .
                 $testcase . "</a></li>\n";
         }
         return $buffer . "</ul>\n";
@@ -278,8 +306,9 @@ class XMLTestManager extends HTMLTestManager {
 
             $rss->additem($properties);
         }
-
-        $rss->writeRss($output);
+        if ( !$rss->writeRss($output) ) {
+            die ( $rss->error );
+        }
         return $output;
 
     }
@@ -296,15 +325,15 @@ class XMLTestManager extends HTMLTestManager {
             return $output;
         }
 
-        foreach ($testcases as $testcase_file => $testcase) {
+        foreach ($testcases as $testfile => $testcase) {
             $properties["title"]=$testcase;
             $properties["description"]=$testcase;
             $properties["link"]='http://'.$_SERVER['SERVER_NAME'].
                 $manager->getBaseURL()."?case=" .
-                    urlencode($testcase_file) . "&output=xml";
+                    urlencode($testcase) . "&output=xml";
 
             // Comment this out for performance?
-            $properties["dc:date"]=gmdate("Y-m-d\TH:i:sO",filemtime($testcase_file));
+            $properties["dc:date"]=gmdate("Y-m-d\TH:i:sO",filemtime($testfile));
 
             $rss->additem($properties);
         }
@@ -315,29 +344,29 @@ class XMLTestManager extends HTMLTestManager {
 
     function &_getRssWriter() {
 
-        $wact_url = 'http://'.$_SERVER['SERVER_NAME'].str_replace('index.php','',$_SERVER['PHP_SELF']);
+        $url = 'http://'.$_SERVER['SERVER_NAME'].str_replace('index.php','',$_SERVER['PHP_SELF']);
 
         require_once TEST_ROOT . '/lib/xml_writer_class.php';
         require_once TEST_ROOT . '/lib/rss_writer_class.php';
 
         $rss_writer_object=& new rss_writer_class();
         $rss_writer_object->specification="1.0";
-        $rss_writer_object->about=$wact_url."index.php?output=xml";
-        $rss_writer_object->stylesheet=$wact_url."rss2html.xsl";
+        $rss_writer_object->about=$url."index.php?output=xml";
+        $rss_writer_object->stylesheet=$url."rss2html.xsl";
         $rss_writer_object->rssnamespaces["dc"]="http://purl.org/dc/elements/1.1/";
 
         // Channel Properties
         $properties=array();
-        $properties["title"]="WACT Unit Test Cases";
-        $properties["description"]="WACT Unit Test Cases";
-        $properties["link"]="http://wact.sourceforge.net/";
+        $properties["title"]="Dokuwiki Unit Test Cases";
+        $properties["description"]="Dokuwiki Unit Test Cases";
+        $properties["link"]="http://wiki.splitbrain.org/";
         $properties["dc:date"]=gmdate("Y-m-d\TH:i:sO");
         $rss_writer_object->addchannel($properties);
 
         // Logo like this (if we had one)
         /*
         $properties=array();
-        $properties["url"]="http://www.phpclasses.org/graphics/logo.gif";
+        
         $properties["link"]="http://www.phpclasses.org/";
         $properties["title"]="PHP Classes repository logo";
         $properties["description"]="Repository of components and other resources for PHP developers";
@@ -355,31 +384,39 @@ class XMLTestManager extends HTMLTestManager {
 class RemoteTestManager extends TestManager {
 
     function RemoteTestManager() {
-        parent::TestManager();
+        RemoteTestManager::_installSimpleTest();
     }
 
     function _installSimpleTest() {
-        parent::_installSimpleTest();
         require_once SIMPLE_TEST . 'remote.php';
     }
 
     function runAllTests(&$reporter, $url = FALSE) {
         $groups = RemoteTestManager::getGroupTestList($url);
-
         $T = &new RemoteTestCase($groups['All Tests']);
         $T->run($reporter);
     }
+    
+    function runTestUrl($case_url,& $reporter, $url = FALSE) {
+        RemoteTestManager::_installSimpleTest();
+        $T = &new RemoteTestCase($case_url);
+        $T->run($reporter);
+    }
 
-    function runTestCase($case_file,& $reporter, $url = FALSE) {
+    function runTestCase($case_id,& $reporter, $url = FALSE) {
         $cases = RemoteTestManager::getTestCaseList($url);
-
-        $T = &new RemoteTestCase($cases[$case_file]);
+        if ( !array_key_exists($case_id, $cases) ) {
+            trigger_error("Unknown test id $case_id\n",E_USER_ERROR);
+        }
+        $T = &new RemoteTestCase($cases[$case_id]);
         $T->run($reporter);
     }
 
     function runGroupTest($group_name, &$reporter, $url = FALSE) {
         $groups = RemoteTestManager::getGroupTestList($url);
-
+        if ( !array_key_exists($group_name, $groups) ) {
+            trigger_error("Unknown group $group_name\n",E_USER_ERROR);
+        }
         $T = &new RemoteTestCase($groups[$group_name]);
         $T->run($reporter);
     }
@@ -387,11 +424,11 @@ class RemoteTestManager extends TestManager {
     function & getGroupTestList($url = FALSE) {
 
         if ( !$url ) {
-            $url = REMOTE_TEST_HTTP_PATH;
+            $url = REMOTE_TEST_URL;
         }
 
         $url .= '?output=xml';
-
+        
         $manager =& new RemoteTestManager();
         $rss = & $manager->_getRssReader($url);
 
@@ -406,11 +443,10 @@ class RemoteTestManager extends TestManager {
 
     function &getTestCaseList($url = FALSE) {
         if ( !$url ) {
-            $url = REMOTE_TEST_HTTP_PATH;
+            $url = REMOTE_TEST_URL;
         }
 
         $url .= '?show=cases&output=xml';
-
         $manager =& new RemoteTestManager();
         $rss = & $manager->_getRssReader($url);
 
@@ -438,4 +474,3 @@ class RemoteTestManager extends TestManager {
     }
 
 }
-?>
diff --git a/test/lib/web.inc.php b/test/lib/web.inc.php
index 88020bd2a..7ca70f204 100644
--- a/test/lib/web.inc.php
+++ b/test/lib/web.inc.php
@@ -45,4 +45,3 @@ class DWWebTestCase extends WebTestCase {
     }
 
 }
-?>
diff --git a/test/lib/xml_writer_class.php b/test/lib/xml_writer_class.php
index d82637e9b..97fb1bee0 100644
--- a/test/lib/xml_writer_class.php
+++ b/test/lib/xml_writer_class.php
@@ -290,4 +290,3 @@ class xml_writer_class
 };
 
 }
-?>
\ No newline at end of file
diff --git a/test/remotetests.php b/test/remotetests.php
index f4d1af869..3dd290712 100755
--- a/test/remotetests.php
+++ b/test/remotetests.php
@@ -1,8 +1,5 @@
 #!/usr/bin/php -q
 <?php
-/**
-* TODO: This needs migrating to inc/cli_opts.php
-*/
 ini_set('memory_limit','128M');
 
 if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
@@ -12,22 +9,23 @@ TestManager::setup();
 
 function usage() {
     $usage = <<<EOD
-Usage: ./runtests.php [OPTION]...
+Usage: ./remotetests.php [OPTION]...
 Run the Dokuwiki unit tests remotely executing tests over HTTP and delivering
 results to the command line. If ALL of the test cases pass a count of
 total passes is printed on STDOUT. If ANY of the test cases fail (or raise
 errors) details are printed on STDERR and this script returns a non-zero
 exit code.
-  -u  --url=HTTP_PATH     specify remote server test url (w. index.php)
-  -f  --file=NAME         specify a test case file
+  -c  --case=NAME         specify a test case by it's ID (see -i for list)
+  -f  --caseurl=NAME         specify a test case file (full or relative path)
   -g  --group=NAME        specify a grouptest. If no grouptest is
                           specified, all test cases will be run.
-  -l  --glist             list available group tests
-  -c  --clist             list available test case files
+  -i  --caselist          list individual test cases by their ID
+  -l  --grouplist         list available grouptests
   -s, --separator=SEP     set the character(s) used to separate fail
                           details to SEP
   -p, --path              path to SimpleTest installation
   -h, --help              display this help and exit
+  -u  --url=TEST_URL      specify remote server test url (w. index.php)
 
 EOD;
     echo $usage;
@@ -35,118 +33,128 @@ EOD;
 }
 
 /* default test options */
-$opt_url = FALSE;
 $opt_separator = '->';
-$opt_group_list = FALSE;
-$opt_case_list = FALSE;
-$opt_casefile = FALSE;
+$opt_caselist = FALSE;
+$opt_grouplist = FALSE;
+$opt_caseid = FALSE;
+$opt_caseurl = FALSE;
 $opt_groupfile = FALSE;
+$opt_url = FALSE;
 
-/* only allow cmd line options if PEAR Console_Getopt is available */
-@include_once 'Console/Getopt.php'; /* PEAR lib */
-if (class_exists('Console_Getopt')) {
+include_once(DOKU_INC.'inc/cliopts.php');
+$short_opts = "c:f:g:hils:p:u:";
+$long_opts  = array("case=","caselist","help", "caseurl=", "group=", "grouplist", "separator=", "path=","url=");
+$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
+if ( $OPTS->isError() ) {
+    fwrite( STDERR, $OPTS->getMessage() . "\n");
+    usage($available_grouptests);
+    exit(1);
+}
 
-    $argv = Console_Getopt::readPHPArgv();
-    if (PEAR::isError($argv)) {
-        die('Fatal Error: ' . $argv->getMessage()) . "\n";
+foreach ($OPTS->options as $key => $val) {
+    switch ($key) {
+        case 'c':
+        case 'case':
+            $opt_caseid = $val;
+            break;
+        case 'h':
+        case 'help':
+            usage();
+            break;
+        case 'f':
+        case 'caseurl':
+            $opt_caseurl = $val;
+            break;
+        case 'g':
+        case 'group':
+            $opt_groupfile = $val;
+            break;
+        case 'i':
+        case 'caselist':
+            $opt_caselist = TRUE;
+            break;
+        case 'l':
+        case 'grouplist':
+            $opt_grouplist = TRUE;
+            break;
+        case 's':
+        case 'separator':
+            $opt_separator = $val;
+            break;
+        case 'p':
+        case 'path':
+            if (file_exists($val)) {
+                define('SIMPLE_TEST', $val);
+            }
+            break;
+        case 'u':
+        case '--url':
+            $opt_url = $val;
+            break;
     }
+}
 
-    $short_opts = "u:f:g:hlcs:p:";
-    $long_opts  = array(
-		"help", "url=", "file=", "group=",
-		"glist", "clist", "separator=", "path="
-		);
-    $options = Console_Getopt::getopt($argv, $short_opts, $long_opts);
-    if (PEAR::isError($options)) {
-        usage($available_grouptests);
+if ( ! $opt_url ) {
+    if ( !defined('REMOTE_TEST_URL') ) {
+        fwrite( STDERR, "No test URL defined. Either modify tests.ini or use -u option\n");
+        exit(1);
+    } else {
+        $opt_url = REMOTE_TEST_URL;
     }
+}
+
 
-    foreach ($options[0] as $option) {
-        switch ($option[0]) {
-            case 'h':
-            case '--help':
-                usage();
-                break;
-            case 'u':
-            case '--url':
-                $opt_url = $option[1];
-                break;				
-            case 'f':
-            case '--file':
-                $opt_casefile = $option[1];
-                break;
-            case 'g':
-            case '--group':
-                $opt_groupfile = $option[1];
-                break;
-            case 'l':
-            case '--glist':
-                $opt_group_list = TRUE;
-                break;
-            case 'c':
-            case '--clist':
-                $opt_case_list = TRUE;
-                break;				
-            case 's':
-            case '--separator':
-                $opt_separator = $option[1];
-                break;
-            case 'p':
-            case '--path':
-                if (file_exists($option[1])) {
-                    define('SIMPLE_TEST', $option[1]);
-                }
-                break;
-        }
+if (!@include_once SIMPLE_TEST . 'reporter.php') {
+    if ( defined(SIMPLE_TEST) ) {
+        fwrite( STDERR, "Where's Simple Test ?!? Not at ".SIMPLE_TEST." \n");
+    } else {
+        fwrite( STDERR, "Where's Simple Test ?!? SIMPLE_TEST not even defined!\n");
     }
+    exit(1);
 }
 
+require_once 'lib/cli_reporter.php';
+
+/* list grouptests */
+if ($opt_grouplist) {
+    $groups = RemoteTestManager::getGroupTestList($opt_url);
+    fwrite( STDOUT, "Available grouptests:\n");
+    foreach ( array_keys($groups) as $group ) {
+        fwrite( STDOUT, $group."\n");
+    }
+}
 
-if ( !defined('SIMPLE_TEST') ) {
-    define('SIMPLE_TEST', ConfigManager::getOptionAsPath('tests', 'simpletest', 'library_path'));
+/* list test cases */
+if ($opt_caselist) {
+    $cases = RemoteTestManager::getTestCaseList($opt_url);
+    fwrite( STDOUT, "Available tests tests:\n");
+    foreach ( array_keys($cases) as $case ) {
+        fwrite( STDOUT, $case."\n");
+    }
 }
-if (!@include_once SIMPLE_TEST . 'runner.php') {
-    RaiseError('runtime', 'LIBRARY_REQUIRED', array(
-        'library' => 'Simple Test',
-        'path' => SIMPLE_TEST));
+
+/* exit if we've displayed a list */
+if ( $opt_grouplist || $opt_caselist ) {
+    exit(0);
 }
-require_once 'lib/cli_reporter.php';
 
-/* list tests */
-if ($opt_group_list || $opt_case_list ) {
-
-	if ($opt_group_list) {
-		$gList = RemoteTestManager::getGroupTestList($opt_url);
-	
-		foreach ( $gList as $gName => $gUrl ) {
-			fwrite(STDOUT,"[$gName] $gUrl\n");
-		}
-	}
-
-	if ($opt_case_list) {
-		$cList = RemoteTestManager::getTestCaseList($opt_url);
-		
-		foreach ( $cList as $cName => $cUrl ) {
-			fwrite(STDOUT,"[$cName] $cUrl\n");
-		}
-	}
-	
+/* run a test case given it's URL */
+if ($opt_caseurl) {
+    RemoteTestManager::runTestUrl($opt_caseurl, new CLIReporter($opt_separator), $opt_url);
     exit(0);
 }
 
-/* run a test case */
-if ($opt_casefile) {
-    RemoteTestManager::runTestCase(
-		$opt_casefile, new CLIReporter($opt_separator), $opt_url
-		);
+/* run a test case by id*/
+if ($opt_caseid) {
+    RemoteTestManager::runTestCase($opt_caseid, new CLIReporter($opt_separator), $opt_url);
     exit(0);
 }
 
 /* run a grouptest */
 if ($opt_groupfile) {
     RemoteTestManager::runGroupTest(
-		$opt_groupfile, new CLIReporter($opt_separator), $opt_url
-		);
+        $opt_groupfile, new CLIReporter($opt_separator), $opt_url
+        );
     exit(0);
 }
 /* run all tests */
diff --git a/test/runtests.php b/test/runtests.php
index 5e9bea983..ba9bc4b1d 100755
--- a/test/runtests.php
+++ b/test/runtests.php
@@ -1,11 +1,6 @@
 #!/usr/bin/php -q
 <?php
-/**
-* TODO: This needs migrating to inc/cli_opts.php
-*/
-
 ini_set('memory_limit','128M');
-/* wact common */
 if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
 define('TEST_ROOT', dirname(__FILE__));
 define('TMPL_FILESCHEME_PATH', TEST_ROOT . '/filescheme/');
@@ -21,10 +16,12 @@ Run the Dokuwiki unit tests. If ALL of the test cases pass a count of total
 passes is printed on STDOUT. If ANY of the test cases fail (or raise
 errors) details are printed on STDERR and this script returns a non-zero
 exit code.
-  -f  --file=NAME         specify a test case file
+  -c  --case=NAME         specify a test case by it's ID (see -i for list)
+  -f  --file=NAME         specify a test case file (full or relative path)
   -g  --group=NAME        specify a grouptest. If no grouptest is
                           specified, all test cases will be run.
-  -l  --list              list available grouptests/test case files
+  -i  --caselist          list individual test cases by their ID
+  -l  --grouplist         list available grouptests
   -s, --separator=SEP     set the character(s) used to separate fail
                           details to SEP
   -p, --path              path to SimpleTest installation
@@ -37,15 +34,16 @@ EOD;
 
 /* test options */
 $opt_separator = '->';
-$opt_list = FALSE;
+$opt_caselist = FALSE;
+$opt_grouplist = FALSE;
+$opt_caseid = FALSE;
 $opt_casefile = FALSE;
 $opt_groupfile = FALSE;
 
-/* only allow cmd line options if PEAR Console_Getopt is available */
 include_once(DOKU_INC.'inc/cliopts.php');
 
-$short_opts = "f:g:hls:p:";
-$long_opts  = array("help", "file=", "group=", "list", "separator=", "path=");
+$short_opts = "c:f:g:hils:p:";
+$long_opts  = array("case=","caselist","help", "file=", "group=", "grouplist", "separator=", "path=");
 $OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
 if ( $OPTS->isError() ) {
     fwrite( STDERR, $OPTS->getMessage() . "\n");
@@ -55,6 +53,10 @@ if ( $OPTS->isError() ) {
 
 foreach ($OPTS->options as $key => $val) {
     switch ($key) {
+        case 'c':
+        case 'case':
+            $opt_caseid = $val;
+            break;
         case 'h':
         case 'help':
             usage();
@@ -67,9 +69,13 @@ foreach ($OPTS->options as $key => $val) {
         case 'group':
             $opt_groupfile = $val;
             break;
+        case 'i':
+        case 'caselist':
+            $opt_caselist = TRUE;
+            break;
         case 'l':
-        case 'list':
-            $opt_list = TRUE;
+        case 'grouplist':
+            $opt_grouplist = TRUE;
             break;
         case 's':
         case 'separator':
@@ -84,7 +90,6 @@ foreach ($OPTS->options as $key => $val) {
    }
 }
 
-
 if (!@include_once SIMPLE_TEST . 'reporter.php') {
     die("Where's Simple Test ?!? Not at ".SIMPLE_TEST);
 }
@@ -92,14 +97,28 @@ if (!@include_once SIMPLE_TEST . 'reporter.php') {
 require_once 'lib/cli_reporter.php';
 
 /* list grouptests */
-if ($opt_list) {
+if ($opt_grouplist) {
     echo CLITestManager::getGroupTestList(TEST_GROUPS);
+}
+
+/* list test cases */
+if ($opt_caselist) {
     echo CLITestManager::getTestCaseList(TEST_CASES);
+}
+
+/* exit if we've displayed a list */
+if ( $opt_grouplist || $opt_caselist ) {
     exit(0);
 }
+
 /* run a test case */
 if ($opt_casefile) {
-    TestManager::runTestCase($opt_casefile, new CLIReporter($opt_separator));
+    TestManager::runTestFile($opt_casefile, new CLIReporter($opt_separator));
+    exit(0);
+}
+/* run a test case by id*/
+if ($opt_caseid) {
+    TestManager::runTestCase($opt_caseid, TEST_CASES, new CLIReporter($opt_separator));
     exit(0);
 }
 /* run a grouptest */
-- 
GitLab