MDL-37046 behat: Externalizations
authorDavid Monllao <davidm@moodle.com>
Fri, 14 Dec 2012 06:59:31 +0000 (14:59 +0800)
committerDavid Monllao <davidm@moodle.com>
Tue, 29 Jan 2013 00:40:37 +0000 (08:40 +0800)
Instead of starting the PHP web server and calling
behat as a passthru we maintain them as standalone

admin/tool/behat/cli/util.php
admin/tool/behat/lang/en/tool_behat.php
admin/tool/behat/locallib.php
lib/behat/bin/behat [deleted file]

index d140667..bb97667 100644 (file)
@@ -15,7 +15,7 @@
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * CLI tests runner
+ * CLI tool
  *
  * @package    tool_behat
  * @copyright  2012 David MonllaĆ³
@@ -31,12 +31,9 @@ require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/behat/locallib.php');
 // CLI options.
 list($options, $unrecognized) = cli_get_params(
     array(
-        'help'               => false,
-        'runtests'           => false,
-        'tags'               => false,
-        'extra'              => '',
-        'with-javascript'    => false,
-        'testenvironment'    => false
+        'help'    => false,
+        'enable'  => false,
+        'disable' => false,
     ),
     array(
         'h' => 'help'
@@ -46,16 +43,14 @@ list($options, $unrecognized) = cli_get_params(
 $help = "
 Behat tool
 
-Ensure the user who executes the action has permissions over behat installation
-
 Options:
---runtests           Runs the tests (accepts --with-javascript option, --tags=\"\" option to execute only the matching tests and --extra=\"\" to specify extra behat options)
---testenvironment    Allows the test environment to be accesses through the built-in server (accepts value 'enable' or 'disable')
+--enable Enables test environment
+--disable Disables test environment
 
 -h, --help     Print out this help
 
 Example from Moodle root directory:
-\$ php admin/tool/behat/cli/util.php --runtests --tags=\"tool_behat\"
+\$ php admin/tool/behat/cli/util.php --enable
 
 More info in http://docs.moodle.org/dev/Acceptance_testing#Running_tests
 ";
@@ -70,29 +65,17 @@ if ($unrecognized) {
     cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
 }
 
-$commands = array('runtests', 'testenvironment');
-foreach ($commands as $command) {
-    if ($options[$command]) {
-        $action = $command;
-    }
-}
-
-if (empty($action)) {
-    mtrace('No command selected');
+// Run command.
+if ($options['enable']) {
+    $action = 'enable';
+} else if ($options['disable']) {
+    $action = 'disable';
+} else {
     echo $help;
     exit(0);
 }
 
-switch ($action) {
-
-    case 'runtests':
-        tool_behat::runtests($options['with-javascript'], $options['tags'], $options['extra']);
-        break;
-
-    case 'testenvironment':
-        tool_behat::switchenvironment($options['testenvironment']);
-        break;
-}
+tool_behat::switchenvironment($action);
 
+mtrace(get_string('testenvironment' . $action, 'tool_behat'));
 
-mtrace(get_string('finished', 'tool_behat'));
index c600663..50ca24f 100644 (file)
  */
 
 $string['allavailablesteps'] = 'All the available steps';
-$string['finished'] = 'Process finished';
 $string['giveninfo'] = 'Given. Processes to set up the environment';
 $string['installinfo'] = 'for installation and tests execution info';
 $string['moreinfoin'] = 'More info in';
 $string['newstepsinfo'] = 'for info about adding new steps definitions';
 $string['newtestsinfo'] = 'for info about writting new tests';
+$string['noaction'] = 'No action selected';
 $string['nostepsdefinitions'] = 'There aren\'t steps definitions matching this filter';
 $string['pluginname'] = 'Acceptance testing';
 $string['phpunitenvproblem'] = 'PHPUnit environment problem';
@@ -36,6 +36,8 @@ $string['stepsdefinitionscomponent'] = 'Area';
 $string['stepsdefinitionscontains'] = 'Contains';
 $string['stepsdefinitionsfilters'] = 'Steps definitions';
 $string['stepsdefinitionstype'] = 'Type';
+$string['testenvironmentenable'] = 'Test environment enabled';
+$string['testenvironmentdisable'] = 'Test environment disabled';
 $string['theninfo'] = 'Then. Checkings to ensure the outcomes are the expected ones';
 $string['viewsteps'] = 'Filter';
 $string['wheninfo'] = 'When. Actions that provokes an event';
index bd1717d..0399d5f 100644 (file)
@@ -38,15 +38,10 @@ require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/behat/steps_definitions_
 class tool_behat {
 
     /**
-     * Path where each component's tests are stored
-     * @var string
-     */
+     * @var string Path where each component's tests are stored */
     private static $behat_tests_path = '/tests/behat';
 
-    /**
-     * Steps types
-     * @var array
-     */
+    /** @var array Steps types */
     private static $steps_types = array('given', 'when', 'then');
 
     /** @var string Docu url */
@@ -66,7 +61,7 @@ class tool_behat {
         self::check_behat_setup();
 
         // The loaded steps depends on the component specified.
-        self::update_config_file($component);
+        self::update_config_file($component, false);
 
         // The Moodle\BehatExtension\HelpPrinter\MoodleDefinitionsPrinter will parse this search format.
         if ($type) {
@@ -80,8 +75,8 @@ class tool_behat {
         }
 
         $currentcwd = getcwd();
-        chdir($CFG->dirroot . '/lib/behat');
-        exec('bin/behat --config="' . self::get_behat_config_filepath() . '" ' . $filteroption, $steps, $code);
+        chdir($CFG->dirroot);
+        exec(self::get_behat_command() . ' --config="' . self::get_steps_list_config_filepath() . '" ' . $filteroption, $steps, $code);
         chdir($currentcwd);
 
         if ($steps) {
@@ -96,20 +91,13 @@ class tool_behat {
     }
 
     /**
-     * Allows / disables the test environment to be accesses through the built-in server
+     * Allows / disables the test environment to be accessed through the built-in server
      *
      * Built-in server must be started separately
      *
      * @param string $testenvironment enable|disable
      */
-    public static function switchenvironment($testenvironment = false) {
-        global $CFG;
-
-        // Priority to the one specified as argument.
-        if (!$testenvironment) {
-            $testenvironment = optional_param('testenvironment', 'enable', PARAM_ALPHA);
-        }
-
+    public static function switchenvironment($testenvironment) {
         if ($testenvironment == 'enable') {
             self::start_test_mode();
         } else if ($testenvironment == 'disable') {
@@ -118,84 +106,38 @@ class tool_behat {
     }
 
     /**
-     * Runs the acceptance tests
+     * Updates a config file
      *
-     * It starts test mode and runs the built-in PHP
-     * erver and stops it all then it's done
+     * The tests runner and the steps definitions list uses different
+     * config files to avoid problems with concurrent executions.
+     *
+     * The steps definitions list can be filtered by component so it's
+     * behat.yml can be different from the dirroot one.
      *
-     * @param boolean $withjavascript Include tests with javascript
-     * @param string $tags Restricts the executed tests to the ones that matches the tags
-     * @param string $extra Extra CLI behat options
-     */
-    public static function runtests($withjavascript = false, $tags = false, $extra = '') {
-        global $CFG;
-
-        // Checks the behat set up and the PHP version.
-        self::check_behat_setup(true);
-
-        // Check that PHPUnit test environment is correctly set up.
-        self::test_environment_problem();
-
-        // Updates all the Moodle features and steps definitions.
-        self::update_config_file();
-
-        @set_time_limit(0);
-
-        // No javascript by default.
-        if (!$withjavascript && strstr($tags, 'javascript') == false) {
-            $jsstr = '~@javascript';
-        }
-
-        // Adding javascript option to --tags.
-        $tagsoption = '';
-        if ($tags) {
-            if (!empty($jsstr)) {
-                $tags .= '&&' . $jsstr;
-            }
-            $tagsoption = " --tags '" . $tags . "'";
-
-        // No javascript by default.
-        } else if (!empty($jsstr)) {
-            $tagsoption = " --tags '" . $jsstr . "'";
-        }
-
-        // Starts built-in server and inits test mode.
-        self::start_test_mode();
-        $server = self::start_test_server();
-
-        // Runs the tests switching the current working directory to behat path.
-        $currentcwd = getcwd();
-        chdir($CFG->dirroot . '/lib/behat');
-        ob_start();
-        passthru('bin/behat --ansi --config="' . self::get_behat_config_filepath() .'" ' . $tagsoption . ' ' .$extra, $code);
-        $output = ob_get_contents();
-        ob_end_clean();
-        chdir($currentcwd);
-
-        // Stops built-in server and stops test mode.
-        self::stop_test_server($server[0], $server[1]);
-        self::stop_test_mode();
-
-        // Output.
-        echo $output;
-    }
-
-    /**
-     * Updates the config file
      * @param string $component Restricts the obtained steps definitions to the specified component
+     * @param string $testsrunner If the config file will be used to run tests
      * @throws file_exception
      */
-    private static function update_config_file($component = '') {
+    private static function update_config_file($component = '', $testsrunner = true) {
         global $CFG;
 
-        $behatpath = $CFG->dirroot . '/lib/behat';
+        // Behat must run with the whole set of features and steps definitions.
+        if ($testsrunner === true) {
+            $prefix = '';
+            $configfilepath = $CFG->dirroot . '/behat.yml';
+
+        // Alternative for steps definitions filtering
+        } else {
+            $configfilepath = self::get_steps_list_config_filepath();
+            $prefix = $CFG->dirroot .'/';
+        }
 
         // Behat config file specifing the main context class,
         // the required Behat extensions and Moodle test wwwroot.
         $contents = 'default:
   paths:
-    features: ' . $behatpath . '/features
-    bootstrap: ' . $behatpath . '/features/bootstrap
+    features: ' . $prefix . 'lib/behat/features
+    bootstrap: ' . $prefix . 'lib/behat/features/bootstrap
   context:
     class: behat_init_context
   extensions:
@@ -233,8 +175,8 @@ class tool_behat {
         }
 
         // Stores the file.
-        if (!file_put_contents(self::get_behat_config_filepath(), $contents)) {
-            throw new file_exception('cannotcreatefile', self::get_behat_config_filepath());
+        if (!file_put_contents($configfilepath, $contents)) {
+            throw new file_exception('cannotcreatefile', $configfilepath);
         }
 
     }
@@ -272,6 +214,18 @@ class tool_behat {
         return $stepsdefinitions;
     }
 
+    /**
+     * Checks if $CFG->test_wwwroot is available
+     *
+     * @return boolean
+     */
+    public static function is_server_running() {
+        global $CFG;
+
+        $request = new curl();
+        $request->get($CFG->test_wwwroot);
+        return (true && !$request->get_errno());
+    }
 
     /**
      * Cleans the path returned by get_components_with_tests() to standarize it
@@ -325,7 +279,7 @@ class tool_behat {
         }
 
         // Moodle setting.
-        if (!is_dir($vendor = __DIR__ . '/../../../vendor/behat')) {
+        if (!is_dir(__DIR__ . '/../../../vendor/behat')) {
 
             $msg = get_string('wrongbehatsetup', 'tool_behat');
 
@@ -340,8 +294,8 @@ class tool_behat {
 
         // Behat test command.
         $currentcwd = getcwd();
-        chdir($CFG->dirroot . '/lib/behat');
-        exec('bin/behat --help', $output, $code);
+        chdir($CFG->dirroot);
+        exec(self::get_behat_command() . ' --help', $output, $code);
         chdir($currentcwd);
 
         if ($code != 0) {
@@ -352,6 +306,10 @@ class tool_behat {
     /**
      * Enables test mode
      *
+     * Starts the test mode checking the composer installation and
+     * the phpunit test environment and updating the available
+     * features and steps definitions.
+     *
      * Stores a file in dataroot/behat to allow Moodle to switch
      * to the test environment when using cli-server
      *
@@ -360,6 +318,15 @@ class tool_behat {
     private static function start_test_mode() {
         global $CFG;
 
+        // Checks the behat set up and the PHP version.
+        self::check_behat_setup(true);
+
+        // Check that PHPUnit test environment is correctly set up.
+        self::test_environment_problem();
+
+        // Updates all the Moodle features and steps definitions.
+        self::update_config_file();
+
         if (self::is_test_mode_enabled()) {
             debugging('Test environment was already enabled');
             return;
@@ -376,31 +343,6 @@ class tool_behat {
         chmod($filepath, $CFG->directorypermissions);
     }
 
-    /**
-     * Runs the php built-in server
-     * @return array The process running the server and the pipes array
-     */
-    private static function start_test_server() {
-        global $CFG;
-
-        $descriptorspec = array(
-            array("pipe", "r"),
-            array("pipe", "w"),
-            array("pipe", "a")
-        );
-
-        $server = str_replace('http://', '', $CFG->test_wwwroot);
-        $process = proc_open('php -S ' . $server, $descriptorspec, $pipes, $CFG->dirroot);
-
-        // TODO If it's already started close pipes.
-
-        if (!is_resource($process)) {
-            print_error('testservercantrun');
-        }
-
-        return array($process, $pipes);
-    }
-
     /**
      * Disables test mode
      * @throws file_exception
@@ -418,27 +360,6 @@ class tool_behat {
         }
     }
 
-    /**
-     * Stops the built-in server
-     *
-     * @param resource $process
-     * @param array $pipes IN, OUT and error pipes
-     */
-    private static function stop_test_server($process, $pipes) {
-
-        if (is_resource($process)) {
-
-            // Closing pipes.
-            fclose($pipes[0]);
-            fclose($pipes[1]);
-            fclose($pipes[2]);
-
-            // Closing process.
-            proc_terminate($process);
-            proc_close($process);
-        }
-    }
-
     /**
      * Checks whether test environment is enabled or disabled
      *
@@ -464,7 +385,7 @@ class tool_behat {
     private static function is_test_environment_running() {
         global $CFG;
 
-        if (!empty($CFG->originaldataroot) || defined('BEHAT_RUNNING')) {
+        if (!empty($CFG->originaldataroot)) {
             return true;
         }
 
@@ -473,21 +394,25 @@ class tool_behat {
 
     /**
      * Returns the path to the file which specifies if test environment is enabled
+     *
+     * The file is in dataroot/behat/ but we need to
+     * know if test mode is running because then we swap
+     * it to phpunit_dataroot and we need the original value
+     *
      * @return string
      */
     private static function get_test_filepath() {
         global $CFG;
 
         if (self::is_test_environment_running()) {
-            $testenvfile = $CFG->originaldataroot . '/behat/test_environment_enabled.txt';
+            $prefix = $CFG->originaldataroot;
         } else {
-            $testenvfile = $CFG->dataroot . '/behat/test_environment_enabled.txt';
+            $prefix = $CFG->dataroot;
         }
 
-        return $testenvfile;
+        return $prefix . '/behat/test_environment_enabled.txt';
     }
 
-
     /**
      * Ensures the behat dir exists in moodledata
      * @throws file_exception
@@ -512,10 +437,18 @@ class tool_behat {
     }
 
     /**
-     * Returns the behat config file path
+     * Returns the executable path
+     * @return string
+     */
+    private static function get_behat_command() {
+        return 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'behat';
+    }
+
+    /**
+     * Returns the behat config file path used by the steps definition list
      * @return string
      */
-    private static function get_behat_config_filepath() {
+    private static function get_steps_list_config_filepath() {
         return self::get_behat_dir() . '/behat.yml';
     }
 
diff --git a/lib/behat/bin/behat b/lib/behat/bin/behat
deleted file mode 100755 (executable)
index 5678d16..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Mimics default bin/behat command to keep it in it's sandbox
- *
- * @package    core
- * @category   behat
- * @copyright  2012 David MonllaĆ³
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-define('BEHAT_PHP_BIN_PATH', getenv('PHP_PEAR_PHP_BIN') ?: '/usr/bin/env php');
-define('BEHAT_BIN_PATH',     __FILE__);
-define('BEHAT_VERSION',      'DEV');
-
-// vendor directory existence checked in tool_behat::check_behat_config().
-$vendor = __DIR__.'/../../../vendor';
-require($vendor.'/autoload.php');
-
-$app = new Behat\Behat\Console\BehatApplication(BEHAT_VERSION);
-$app->run();