Last active
March 30, 2018 07:41
-
-
Save picasso250/562a044148ab175cb9ef78d2a2f4fbd3 to your computer and use it in GitHub Desktop.
a small behavior test framework for php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if (!isset($argv[1])) { | |
echo "Usage: $argv[0] test_file\n"; | |
exit(); | |
} | |
$_cur_test_file = $argv[1]; | |
if (!is_file($_cur_test_file)) { | |
echo "$_cur_test_file not exits\n"; | |
exit(1); | |
} | |
$_error_msgs = []; | |
$ok = true; | |
include $_cur_test_file; | |
foreach (file($_cur_test_file) as $_cur_test_file_line_no => $_cur_test_file_line) { | |
if (preg_match('/^\s*function\s+(test_.+?)\s*\(/', $_cur_test_file_line, $m)) { | |
$_cur_test_func = $m[1]; | |
$_assert_count[$_cur_test_func] = 0; | |
$_assert_count_fail[$_cur_test_func] = 0; | |
$_cur_test_func(); | |
$total = $_assert_count[$_cur_test_func]; | |
$fail = $_assert_count_fail[$_cur_test_func]; | |
$ok = $total - $fail; | |
echo "=== ",("$_cur_test_func ($ok/$total)")," ===\n"; | |
if ($ok !== $total) $ok = false; | |
if ($fail) foreach ($_error_msgs[$_cur_test_func] as $msg) echo "$msg\n"; | |
} | |
} | |
if ($ok) echo "OK.\n"; | |
else { | |
echo "Bomb!!! Failed."; | |
exit(1); | |
} | |
// === lib === | |
function http($line, $headers, $body = null) | |
{ | |
$a = explode(" ", $line); | |
$ch = curl_init(); | |
if (count($a) == 2) { | |
list($method, $url) = $a; | |
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); | |
} else { | |
$url = $a; | |
} | |
curl_setopt($ch, CURLOPT_URL,$url); | |
curl_setopt($ch, CURLOPT_TIMEOUT,2); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
curl_setopt($ch, CURLOPT_HEADER, 1); | |
if ($body !== null) { | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $body); | |
} | |
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); // windows | |
echo "$line ",json_encode($headers)," $body\n"; | |
$ret = curl_exec($ch); | |
assert_equal(curl_errno($ch), 0); | |
assert_equal(curl_error($ch), ""); | |
$info = curl_getinfo($ch); | |
curl_close($ch); | |
$header_size = $info['header_size']; | |
return [$info, substr($ret, 0, $header_size), substr($ret, $header_size)]; | |
} | |
function http_json($line, $headers, $body = null) | |
{ | |
list($info, $_, $ret) = http($line, $headers, $body); | |
assert_equal($info['http_code'], 200); | |
$j = json_decode($ret, true); | |
assert_equal(json_last_error(), JSON_ERROR_NONE); | |
return $j; | |
} | |
function assert_type($type, $value) | |
{ | |
$_cur_test_func = $GLOBALS['_cur_test_func']; | |
$GLOBALS['_assert_count'][$_cur_test_func]++; | |
$func = "is_$type"; | |
$b = $func($value); | |
if (!$b) { | |
$GLOBALS['_assert_count_fail'][$_cur_test_func]++; | |
$GLOBALS['_error_msgs'][$_cur_test_func][] = _get_error_msg_with_func_info("real type is ".gettype($type)); | |
} | |
} | |
function assert_equal($value, $should) | |
{ | |
$_cur_test_func = $GLOBALS['_cur_test_func']; | |
$GLOBALS['_assert_count'][$_cur_test_func]++; | |
if ($value !== $should) { | |
$GLOBALS['_assert_count_fail'][$_cur_test_func]++; | |
$GLOBALS['_error_msgs'][$_cur_test_func][] = _get_error_msg_with_func_info("value is ".json_encode($value)); | |
} | |
} | |
function assert_array_key($arr, $key) | |
{ | |
$_cur_test_func = $GLOBALS['_cur_test_func']; | |
$GLOBALS['_assert_count'][$_cur_test_func]++; | |
if (!isset($arr[$key])) { | |
$GLOBALS['_assert_count_fail'][$_cur_test_func]++; | |
$GLOBALS['_error_msgs'][$_cur_test_func][] = _get_error_msg_with_func_info("array no key $key"); | |
} | |
} | |
function assert_table($table, $titles, $should_table) | |
{ | |
$_cur_test_func = $GLOBALS['_cur_test_func']; | |
$GLOBALS['_assert_count'][$_cur_test_func]++; | |
if (!is_array($table)) { | |
$GLOBALS['_assert_count_fail'][$_cur_test_func]++; | |
$GLOBALS['_error_msgs'][$_cur_test_func][] = _get_error_msg_with_func_info("not array"); | |
return; | |
} | |
foreach ($table as $index => $row) { | |
foreach ($titles as $title) { | |
if (!isset($row[$title])) { | |
$GLOBALS['_assert_count_fail'][$_cur_test_func]++; | |
$GLOBALS['_error_msgs'][$_cur_test_func][] = _get_error_msg_with_func_info("index $index: [".json_encode($row)."] has no title $title"); | |
return; | |
} | |
} | |
} | |
foreach ($should_table as $should_row) { | |
$found = false; | |
foreach ($table as $row) { | |
if (_row_equal($row, $should_row, $titles)) $found = true; | |
} | |
if (!$found) { | |
$GLOBALS['_assert_count_fail'][$_cur_test_func]++; | |
$GLOBALS['_error_msgs'][$_cur_test_func][] = _get_error_msg_with_func_info("index $index has no row ".json_encode($should_row)); | |
return; | |
} | |
} | |
} | |
function _row_equal($row, $should_row, $titles) { | |
$i = 0; | |
foreach ($titles as $title) { | |
if (!(isset($row[$title]) && | |
$should_row[$i++] | |
=== | |
$row[$title])) | |
return false; | |
} | |
return true; | |
} | |
function _get_error_msg_with_func_info($msg) | |
{ | |
$start_push = false; | |
$trace = []; | |
foreach (debug_backtrace() as $dbt) { | |
$function = $dbt['function']; | |
if (strpos($function, 'assert_') === 0) { | |
$start_push = true; | |
} | |
if (strpos($function, 'test_') === 0) { | |
$start_push = false; | |
break; | |
} | |
if ($start_push) | |
$trace[] = $dbt; | |
} | |
$msgs = ["$msg\n"]; | |
foreach ($trace as $i=> $t) { | |
$msgs[] = "\t[$i] $t[file]:$t[line] "._get_line_content($t['file'], $t['line'])."\n"; | |
} | |
return implode("", $msgs); | |
} | |
function _get_line_content($file, $line) { | |
return trim(file($file)[$line-1]); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
新建一个文件 如 test_for_last_month_work.php
然后运行
会自动提取此文件中所有 test_.* 函数,然后执行
输出