Now that we know how to run the test suite with run-tests, let's create our first .phpt
file.
Create a basic test
We started by creating a basic test file that tested that echo
could take a list of arguments. We created a new file in the root php-src
directory called echo_basic.phpt
.
$ vi echo_basic.phpt
--TEST--
echo - basic test for echo language construct
--FILE--
<?php
echo 'This works ', 'and takes args!';
?>
--EXPECT--
This works and takes args!
Then we ran the basic test with make.
$ make test TESTS=echo_basic.phpt
We talked about the section names a bit.
-
--TEST--
A very brief description of the test; if you need more room use the--DESCRIPTION--
section -
--FILE--
The PHP code we want to test (make sure to include the closing?>
) -
--EXPECT--
The literal output that the PHP code should generate
Testing non-deterministic output
We learned that --EXPECT--
isn't the best section to use when our test generats non-deterministic output. We created an error test for the filemtime()
function to illustrate this. We tried to set the --EXPECTF--
section to the following warning.
Warning: filemtime() expects exactly 1 parameter, 0 given in /usr/src/php-src/filemtime_error.phpt on line 5
But we ran into the problem where the line number and file name in the output would change so we used --EXPECTF--
instead so that we could insert substitution characters.
$ vi filemtime_error.phpt
Note: This contrived example is essentially just testing that ZPP works (which is already very well tested) so this isn't a real-world test you'd want to create.
--TEST--
filemtime() - test error case
--FILE--
<?php
echo filemtime();
?>
--EXPECTF--
Warning: filemtime() expects exactly 1 parameter, 0 given in %s on line %d
Skipping tests
We discovered that there are situations where tests weren't able to run. This issue came up when we tried to create a test for the curl_init()
function but we didn't have the curl extension installed. We implemented the --SKIPIF--
section to alleviate this.
$ vi curl_init_basic.phpt
--TEST--
curl_init() - creates a resource
--SKIPIF--
<?php if(!extension_loaded('curl')) die('skip ext/curl required'); ?>
--FILE--
<?php
$ch = curl_init();
var_dump(is_resource($ch));
curl_close($ch);
?>
--EXPECT--
bool(true)
$ make test TESTS=curl_init_basic.phpt
Note: Make sure the
--SKIPIF--
section outputs the word "skip" if you want the test to skip. Just usingexit()
/die()
won't skip the test alone.
Give yourself some credit
We added a --CREDITS--
section to carve our name into PHP history.
--CREDITS--
Sammy Kaye Powers me at sammyk dot me
# TestFest Chicago PHP UG 2017-07-14
Some tests have README's
Some of the tests require environment variables and other quirks in order to run. Check out if the tests
folder you're in contains a README
.
cat ext/pdo_mysql/tests/README
Resources
-
PHP Internals Book: The
.phpt
file structure - Test section reference
- Test file naming conventions
- Take part in PHP TestFest 2017
- I'll be giving talks about writing tests for PHP source at NEPHP 2017 and ZendCon 2017. Join me! :)
- The Docker setup I used in these screencasts
All posts in this series
- 01: Compiling PHP from source
- 02: Running the test suite
- 03: All about
.phpt
files - 04: Debugging failed tests
- 05: Finding untested code
- 06: Submitting a PR to php-src