Advanced PHP autograding
Discover the advanced autograding options available for PHP assignments
Last updated
Discover the advanced autograding options available for PHP assignments
Last updated
In this guide, we explore the advanced grading options available for PHP assignments. For more information about setting up a PHP assignment from scratch, see:
PHPUnit is an industry-standard unit testing framework for PHP. It is particularly useful for grading assignments that require students to write functions and classes. Using PHPUnit unit tests offers several advantages over conventional IO tests, including the ability to use assertions, parametrize test cases, and provide better feedback for students. For further documentation about PHPUnit we recommend this online resource.
Consider the example submission Fibonacci.php
file below:
<?php
function PrintFibonacci($n) {
$num1 = 0;
$num2 = 1;
echo "$num1\n";
echo "$num2\n";
for ($i = 2; $i < $n; $i++) {
$num3 = $num1 + $num2;
echo "$num3\n";
$num1 = $num2;
$num2 = $num3;
}
}
function ComputeFibonacci($n) {
if ($n == 0) {
return 0;
}
if ($n == 1) {
return 1;
}
if ($n == 2) {
return 1;
}
$num1 = 0;
$num2 = 1;
for ($i = 2; $i <= $n; $i++) {
$num3 = $num1 + $num2;
$num1 = $num2;
$num2 = $num3;
}
return $num3;
}
$number = (int)readline("Enter the number of terms: ");
PrintFibonacci($number);
Our goal is to unit test the ComputeFibonacci
function. Our tests are defined in the following FibonacciTests.php
file:
<?php
use PHPUnit\Framework\TestCase;
include('./Fibonacci.php');
class FibonacciTests extends TestCase
{
public function testFibonacciZero()
{
$this->assertEquals(0, ComputeFibonacci(0));
}
public function testFibonacciOne()
{
$this->assertEquals(1, ComputeFibonacci(5));
}
public function testFibonacciTwo()
{
$this->assertEquals(1, ComputeFibonacci(2));
}
public function testFibonacciThree()
{
$this->assertEquals(2, ComputeFibonacci(3));
}
public function testFibonacciTen()
{
$this->assertEquals(55, ComputeFibonacci(10));
}
public function testFibonacciTwenty()
{
$this->assertEquals(6765, ComputeFibonacci(20));
}
}
After installing PHP as described in the previous guide, we can use Script Block to install Composer, a PHP dependency management framework, and then PHPUnit.
In the Install php dependecies
Script block above, we run the following Bash script:
set -e
# install composer
yes | sudo apt install php-cli unzip
curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
HASH=`curl -sS https://composer.github.io/installer.sig`
php -r "if (hash_file('SHA384', '/tmp/composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
# install php dependencies
sudo apt-get update
sudo apt-get install php-xml
sudo apt-get install php-mbstring
# install php tools
composer require --dev phpunit/phpunit:^9.5
# add the tools to the path
echo 'export PATH=$PATH:~/vendor/phpunit' >> ~/.cg_bash_env
echo 'export PATH=$PATH:~/vendor/bin' >> ~/.cg_bash_env
Once we are done with the Setup Phase in AutoTest, we can move on to the next Tests phase. Here, we first need to upload our testing file FibonacciTests.php
using an Upload Files Block.
We can then run our unit tests using a Custom Test Block as shown below:
The Custom Test Block runs the following commands:
set -e
# move the necessary files to the current directory
cp $UPLOADED_FILES/* .
mv ~/composer.json .
# wrap a bash script around phpunit (needed to handle the exit code returned by phpunit)
cat <<EOF > script.sh
phpunit --log-junit report.xml FibonacciTests.php
cg junitxml report.xml
exit 0
EOF
# run the script that calls phpunit
chmod +x script.sh
./script.sh
Notice that you can hide these commands from the students using a Hide Block.
The results of the unit tests will be shown to the student as below:
PHP_CodeSniffer is an industry-standard linter for PHP that allows you to enforce rules from various coding standards. It is a useful tool for enforcing code styling best practices for beginner programmers. To read more about PHP_CodeSniffer, we recommend this online resource.
We can repeat the same steps described in the section above for installing PHPUnit, just now the installing script is slightly different:
set -e
# install composer
yes | sudo apt install php-cli unzip
curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
HASH=`curl -sS https://composer.github.io/installer.sig`
php -r "if (hash_file('SHA384', '/tmp/composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
# install php dependencies
sudo apt-get update
sudo apt-get install php-xml
sudo apt-get install php-mbstring
# install php tools
composer require --dev squizlabs/php_codesniffer
# add the tools to the path
echo 'export PATH=$PATH:~/vendor/phpunit' >> ~/.cg_bash_env
echo 'export PATH=$PATH:~/vendor/bin' >> ~/.cg_bash_env
We can run PHP_Codesniffer on a student file, Fibonacci
.php` in the example below, through a Custom Test Block:
Within the Custom Test Block, we run the following script:
set -e
# wrap a bash script around phpcs (needed to handle the exit code returned by phpcs)
cat <<EOF > script.sh
phpcs --report=checkstyle --standard=PSR12 ./Fibonacci.php > report.xml
cg checkstyle parse report.xml
exit 0
EOF
# run the script that calls phpcs
chmod +x script.sh
./script.sh
Running the Code Quality Test will produce inline comments within the student submission, as shown below: