Don F
Don F

Reputation: 2023

Unit Testing a PHP Script

I have some php scripts that are run as cronjobs. No classes and only a few functions.

Id like to test the script with PHPUnit to make sure everything is working but it appears I need to rewrite the php as a class, which I dont want to do (or know how to).

For example if I had a script and its only function was to add 1 and 2 together,

 <?php

 $a=1;
 $b=2
 $c=$a+$b;

 ?>

how do I test that $c==3 with phpunit?

Thanks, Don

Upvotes: 5

Views: 4146

Answers (3)

Cristik
Cristik

Reputation: 32782

Usually the smaller test unit is a function or method, to which you can pass inputs and from which you can expect a certain output. So, if your script includes function, you can test those.

However in the particular scenario you described, you can simply assert that $c equals 3, but that won't help much with testing, as tests are supposed to black-box test the unit.

Also if the script you want to test calls some global PHP functions, then you can mock those functions and assert that they were called as expected (here's an example on how you can mock the global functions). The same mocking can be applied also to functions in the script executing other global PHP functions. Care must be taken though if the script executes some damaging actions, like deleting files as if you fail to mock the delete function you might end up with some nasty results.

Upvotes: 0

Schleis
Schleis

Reputation: 43690

For your example, you don't test that $c = 3.

But that is because your example is a little too simplistic. The variable $c stops existing after your script executes. So the fact that it exists doesn't matter. You want to test what your code does, not how it does things.

I will modify your example a little bit:

job.php

<?php

$a=1;
$b=2
echo $a + $b;

?>

Now we actually have some output and some behavior. The test for this would like:

public function testJob() {
   require('job.php');
   $this->expectOutputString('3');
} 

PHPUnit has the ability to assert against stdOut. We make sure that the code outputs what we expect. Your tests for these types of files would check that what they did was correct. Since PHP's require statement will execute the file at the point, we can run the script and check its output.

If your file has functions, you just include that and check each function in their own individual test.

Upvotes: 7

Maxim Krizhanovsky
Maxim Krizhanovsky

Reputation: 26699

It's not necessary to have classes, you can unit test functions the same way! You can even unit test without capsulating the function, although it will be much harder.

What I'd do in the specific case is to encapsulate code in a function or in a class with static method.

<?php
 function add($a, $b) {
    return $a + $b;
 }
 $c=add($a, $b);
?>

and then provide test for the add function. It's important where $a and $b values come from. That's what you need to mock. If you can control their values, you can use

global $c;
// your test setup 
include(<cron file>);
$this->assertEquals($expectedValue, $c);

Upvotes: 0

Related Questions