Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Jenkins Integration Testing for Plugin Development

From MoodleDocs
Revision as of 13:03, 14 July 2021 by David Mudrak (talk | contribs) (Text replacement - "<code>" to "<syntaxhighlight lang="php">")

This article describes how to use a Jenkins continuous integration server for automating PHPUnit and Behat tests for Moodle and Moodle plugins. The configuration uses Moodle's way of running PHPUnit and Behat tests using the command line.

Integration scenario: We are developing a Moodle plugin. We want to run automated tests, ensuring that it runs correctly on multiple Moodle platform versions, e.g., Moodle 2.7 and Moodle 2.8. This is motivated by the fact that we announce compatibility with these versions in the Moodle plugin directory, and we want to - at least - know, when a plugin becomes incompatible with an older version or needs to be changed. Since we are only running one recent Moodle version for development, automated tests with other versions are useful for us.

Prerequisites for this manual: Ubuntu-based integration server, headless (i.e. without a graphical environment), here: Ubuntu 14.04.

Installation of required software

  • Install Jenkins as a Ubuntu native package, as described on their website (instructions currently at http://pkg.jenkins-ci.org/debian/).
  • Install a Moodle runtime environment. A web server is not needed, since PHP 5's standalone server will be used. The following commands were used for our system:

<syntaxhighlight lang="php">sudo apt-get install postgresql
sudo apt-get install php5-cli php-pear php5-curl php5-pgsql php5-gd php5-intl

  • Install git, which will be used to obtain the sources of Moodle and of your plugin.

<syntaxhighlight lang="php">sudo apt-get install git

  • For acceptance tests, you need to use a browser. Therefore you need to be able to run graphical applications. On headless servers (i.e. those without a display), you can install Xvfb, emulating a display which will be used by your browser.

<syntaxhighlight lang="php">sudo apt-get install xvfb firefox

  • Furthermore, acceptance tests require the Selenium standalone server to be installed. Download from http://www.seleniumhq.org/download/ (here: Version 2.45.0) and unpack it at a jenkins-accessible location, e.g. $JENKINS_HOME/selenium (here: /var/lib/jenkins/selenium).

Basic configuration of Jenkins using the shell

  • Configuration of the init script can be found at <syntaxhighlight lang="php">/etc/default/jenkins. It is not strictly necessary to change anything here, but we set <syntaxhighlight lang="php">HTTP_PORT=-1 and added <syntaxhighlight lang="php">HTTPS_PORT=8998 to make the server only via HTTPS. In that case, you also need to add <syntaxhighlight lang="php">--httpsPort=$HTTPS_PORT to the <syntaxhighlight lang="php">JENKINS_ARGS variable and restart Jenkins.
  • Furthermore, Moodle requires a <syntaxhighlight lang="php">config.php which is not contained in a repository. Therefore, configuration files need to be stored at a separate location, from where they can be pulled in. For our scenario, we stored the configuration file at <syntaxhighlight lang="php">$JENKINS_HOME/moodle-config/config_$target.php, where $target indicates a Moodle branch to build against (e.g., /var/lib/jenkins/moodle-config/config_MOODLE_28_STABLE.php).

Jenkins server configuration

For all following steps you need to open Jenkins in your browser.

Install or update the following plugins:

  • Xvfb plugin
  • Multiple SCMs plugin
  • Matrix project plugin
  • JUnit plugin
  • GitHub plugin
  • Job Configuration History Plugin (optional, but very useful)

Configure Jenkins in the following way (Manage Jenkins → Configure System):

  • Git
    • Add a git installation. Choose an arbitrary name and set the path to <syntaxhighlight lang="php">git
  • Git plugin
    • Set the fields <syntaxhighlight lang="php">Global Config user.name Value and <syntaxhighlight lang="php">Global Config user.email Value. In our case, we set those values to account and e-mail of a technical GitHub account that is only used by the Jenkins server

Create a job for your integration scenario:

  • On the dashboard, select New Item.
  • Choose Multi-configuration project and define an Item name without any spaces.
  • On the next page, define the following settings (Change to your requirements. Remember our integration scenario described above!):
    • GitHub project: URL to the web page of your repository
    • Source Code management:
      • Choose <syntaxhighlight lang="php">Multiple SCMs.
      • Use <syntaxhighlight lang="php">Add SCM to add two git repositories.
      • For the first repository,
        • set the URL to <syntaxhighlight lang="php">git://git.moodle.org/moodle.git.
        • Since this is a public repository, credentials are not required.
        • Under Additional Behaviours, add <syntaxhighlight lang="php">Advanced clone behaviours and check the option <syntaxhighlight lang="php">Shallow clone.
      • For the second repository,
        • set the URL to the URL of your git repository.
        • If this is a private repository, add credentials for accessing it (consider SSH authentication!)
        • Under Additional Behaviours, add <syntaxhighlight lang="php">Check out to a sub-directory and, for <syntaxhighlight lang="php">Local subdirectory for repo, enter the path where you would deploy your module in a usual Moodle installation (e.g., <syntaxhighlight lang="php">mod/yourmodule), without surrounding slashes.
        • Under Additional Behaviours, add <syntaxhighlight lang="php">Advanced clone behaviours and check the option <syntaxhighlight lang="php">Shallow clone.
    • Build Triggers:
      • Check Build when a change is pushed to GitHub.
      • Check Poll SCM. As a schedule, define e.g. <syntaxhighlight lang="php">H/5 * * * * for polling every five minutes.
    • Configuration Matrix:
      • Add two user-defined axes.
        • For the first axis, set name to <syntaxhighlight lang="php">target and values to <syntaxhighlight lang="php">MOODLE_28_STABLE MOODLE_27_STABLE. These values correspond to the branch names used in the Moodle repository.
        • For the second axis, set name to <syntaxhighlight lang="php">testtype and values to <syntaxhighlight lang="php">UnitTest BehatTest. These are used later on to perform different test types - be patient :).
      • Check Run each configuration sequentially.
    • Build Environment:
      • Check Start Xvfb before the build, and shut it down after.
    • Build:
      • Add Execute shell
        • Enter the following commands (Note that we use <syntaxhighlight lang="php">$target here, which always holds the current value of <syntaxhighlight lang="php">target in a particular configuration. Furthermore, this copies an appropriate config.php file into the current workspace):

<syntaxhighlight lang="php">git checkout $target;
curl -s https://getcomposer.org/installer | php;
php composer.phar install --prefer-source;
cp $JENKINS_HOME/moodle-config/config_$target.php config.php;

  • Add Conditional step (single)
    • Run?: <syntaxhighlight lang="php">Strings match, String 1: <syntaxhighlight lang="php">${testtype}, String 2: <syntaxhighlight lang="php">UnitTest (the motivation is that this command is only run for unit tests. In contrast, the other step will be for behat acceptance tests).
    • Builder: <syntaxhighlight lang="php">Execute shell
    • Enter the following commands:

<syntaxhighlight lang="php">mkdir -p ../moodledata/phpunit;
php admin/tool/phpunit/cli/init.php;
vendor/bin/phpunit --log-junit results/phpunit/phpunit.xml --group mod_ratingallocate || true;

  • Add Conditional step (single)
    • Run?: <syntaxhighlight lang="php">Strings match, String 1: <syntaxhighlight lang="php">${testtype}, String 2: <syntaxhighlight lang="php">BehatTest.
    • Builder: <syntaxhighlight lang="php">Execute shell
    • Enter the following commands (replace <syntaxhighlight lang="php">[SeleniumVersion], <syntaxhighlight lang="php">[ModuleTag], and <syntaxhighlight lang="php">[JobName] accordingly):

<syntaxhighlight lang="php">mkdir -p ../moodledata/behat;
php admin/tool/behat/cli/init.php;
java -jar /var/lib/jenkins/selenium/selenium-server-standalone-[SeleniumVersion].jar > /dev/null 2>&1 &
SELENIUM_PID=$!
php -S localhost:8000 > /dev/null 2>&1 &
PHP_PID=$!
vendor/bin/behat --config /var/lib/jenkins/jobs/[JobName]/workspace/target/moodledata/behat/behat/behat.yml --tags '@[ModuleTag]' --format moodle_progress,junit --out ,behatlog || true;
kill $SELENIUM_PID
kill $PHP_PID

  • Post-build Actions:
    • Add Publish JUnit test result report
      • Change the pattern for <syntaxhighlight lang="php">Test report XMLs to the value <syntaxhighlight lang="php">**/phpunit/phpunit.xml,**/behatlog/*.xml
  • Save the configuration and start the first build to test it.