qa:whattotest

This is an old revision of the document!


More information on what to test

You can tell a certain amount from line coverage - but it doesn't really show you exactly what tests there are already for specific functions.

I've put the source code for two scripts below - both are a little unfinished, I will go on tidying them up.

1) This script runs through all of the phpt tests in the source tree and then compares the function calls in the tests with a complete list of PHP's internal functions. At the end it will tell you if there is a function in PHP that is not mentioned in any test case (I get 415). Thanks to Damien Seguy for this.

2) A slight modification to Damien's script. In this case the script will print out what test cases each function is mentioned in. This doesn't mean that the function is properly tested in each one, just that it's used. For example, if you look at the output for 'cos' you will see three tests which are clearly meant to be testing 'cos'. Look at the output for 'var_dump' and you'll see that it's used in 100's of tests - but is it really tested in any of them?

Script number 1

<?php

// define here your PHP source directory
define('PHP_SRC','/home/zoe/BUILDS/php53_dev');

//Get a list of all of the test (phpt) files in the source tree.
$files = array();
get_phpt_files(PHP_SRC, &$file_count, &$files);

//Find all the functions that are called in the test case code
$tested = array();
foreach($files as $file) {
        $tested = array_merge(extract_tests($file), $tested);
}
$tested = array_unique($tested);
//print_r($tested);

//Get a list of all of the internal PHP functions
$internal = get_defined_functions();
$internal = $internal['internal'];

//Compare the list of all function with those that are called from a phpt test case.
$non_tested = array_diff($internal, $tested);
print_r($non_tested);
print count($non_tested). " untested functions\n";


function  extract_tests($file) {
        $code = file_get_contents($file);

        if (!preg_match('/--FILE--\s*(.*)\s*--(EXPECTF|EXPECTREGEX|EXPECT)?--/is', $code, $r)) {
//              print "Unable to get code in ".$file."\n";
                return array();
        }

        $tokens = token_get_all($r[1]);
        $functions = array_filter($tokens, 'filter_functions');
        $functions = array_map( 'map_token_value',$functions);
        $functions = array_unique($functions);

        return $functions;
}

function filter_functions($x) {
        return $x[0] == 307;
}

function map_token_value($x) {
        return $x[1];
}
function get_phpt_files($dir, &$phpt_file_count, &$all_phpt)
{
        $thisdir = dir($dir.'/'); //include the trailing slash
        while(($file = $thisdir->read()) !== false) {
                if ($file != '.' && $file != '..') {
                        $path = $thisdir->path.$file;
                                if(is_dir($path) == true) {
                                        get_phpt_files($path , $phpt_file_count , $all_phpt);
                                } else {
                                        if (preg_match("/\w+\.phpt$/", $file)) {
                                                $all_phpt[$phpt_file_count] = $path;
                                                $phpt_file_count++;
                                        }
                                }
                }
        }
return;
}

Script number 2

<?php
// define here your PHP source directory
define('PHP_SRC','/home/zoe/BUILDS/php53_dev');

//Get a list of all of the test (phpt) files in the source tree.
$files = array();
get_phpt_files(PHP_SRC, &$file_count, &$files);


$tests_by_function=array();

//Get a list of all of the internal PHP functions
$internal = get_defined_functions();
$internal = $internal['internal'];
foreach($internal as $function) {
        $tests_by_function[$function] = array();
}

//Find all the functions that are called in the test case code
$tested = array();
$temp_array = array();

foreach($files as $file) {
        $temp_array = extract_tests($file);
        $tested = array_merge($temp_array, $tested);
        foreach($temp_array as $function) {
                if(array_key_exists($function, $tests_by_function)) {
                        array_push($tests_by_function[$function],$file);
                }
        }
}
$tested = array_unique($tested);
print_r($tests_by_function);


function  extract_tests($file) {
        $code = file_get_contents($file);

        if (!preg_match('/--FILE--\s*(.*)\s*--(EXPECTF|EXPECTREGEX|EXPECT)?--/is', $code, $r)) {
//              print "Unable to get code in ".$file."\n";
                return array();
        }

        $tokens = token_get_all($r[1]);
        $functions = array_filter($tokens, 'filter_functions');
        $functions = array_map( 'map_token_value',$functions);
        $functions = array_unique($functions);

        return $functions;
}

function filter_functions($x) {
        return $x[0] == 307;
}

function map_token_value($x) {
        return $x[1];
}
function get_phpt_files($dir, &$phpt_file_count, &$all_phpt)
{
        $thisdir = dir($dir.'/'); //include the trailing slash
        while(($file = $thisdir->read()) !== false) {
                if ($file != '.' && $file != '..') {
                        $path = $thisdir->path.$file;
                                if(is_dir($path) == true) {
                                        get_phpt_files($path , $phpt_file_count , $all_phpt);
                                } else {
                                        if (preg_match("/\w+\.phpt$/", $file)) {
                                                $all_phpt[$phpt_file_count] = $path;
                                                $phpt_file_count++;
                                        }
                                }
                }
        }
return;
}
?>
qa/whattotest.1210070709.txt.gz · Last modified: 2017/09/22 13:28 (external edit)