PHP Notice: Undefined index: test in /var/www/Testing.php on line 171 PHP Notice: Undefined index: test2 in /var/www/Testing.php on line 171
またはこれでさえ:
PHP Fatal error: Cannot use object of type stdClass as array in /var/www/Testing.php on line 171
1つの大きなプロジェクトの開発中に、適切に送信されたパラメーターについて記述されたメソッドのテストを開始する必要がありました。
私の場合、クラスとその契約をテストしましたが、テストのイデオロギーは同じです。
入力パラメーターを配列として使用して、いくつかの要素を処理するために使用される関数があるとします。
例:
PHP Warning: mysql_affected_rows() expects parameter 1 to be resource, string given in /var/www/Testing.php on line 177
関数のテストに役立つ簡単なクラスを作成しました。intから始まり、nullをダウンロードしてランダムデータを生成します。
彼のコードは次のとおりです。
class tester { public static $useRandom = true; public static $randMin = 1; public static $randMax = 50; public static $stringDefaultPreffix = 'string_'; public static $mode = 'real'; const T_INTEGER = 0; const T_STRING = 1; const T_ARRAY = 2; const T_OBJECT = 3; const T_BOOLEAN = 4; const T_FUNCTION = 5; const T_NULL = 6; /** * "" * */ public static $allowedTytes = array(self::T_INTEGER,self::T_STRING); public static function getRand() { $dice = array_rand(self::$allowedTytes, 1); /* * =( * */ switch ($dice) { /** * int */ case self::T_INTEGER : return self::getInt(); break; /** * */ case self::T_STRING: return self::getString(); break; /** * */ case self::T_ARRAY: return self::getArray(); break; /** * */ case self::T_OBJECT: return self::getObject(); break; /** * ! */ case self::T_BOOLEAN: return self::getBoolean(); break; /** * , ? */ case self::T_FUNCTION: return self::getFunction(); break; /** * null? */ case self::T_NULL: return self::getNull(); break; default: return true; break; } } /** * null * @static * @return null */ public static function getNull() { return null; } /** * * @static * @return array */ public static function getArray() { $array = array(); $arrayLength = mt_rand(self::$randMin, self::$randMax); while (count($array) < $arrayLength) { /** * self::getRand(); =( * =) */ $array[] = mt_rand(self::$randMin, self::$randMax); } return $array; } /** * * @static * @return stdClass */ public static function getObject() { return new stdClass(); } /** * * @static * @param bool $default * @return bool */ public static function getBoolean($default = true) { if (self::$useRandom) { return (mt_rand(0, 1) ? true : false); } else { return $default; } } /** * * @static * @param int $default * @return int */ public static function getInt($default = 42) { if (self::$useRandom) { return mt_rand(self::$randMin, self::$randMax); } else { return $default; } } /** * * @static * @param string $default * @return string */ public static function getString($default = 'string_1234567') { if (self::$useRandom) { return uniqid(self::$stringDefaultPreffix); } else { return $default; } } /** * * @static * @return string */ public static function getFunction() { /** * , * http://php.net/manual/en/function.create-function.php */ return create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);'); } /** * , * @param $errno * @param $errstr * @param $errfile * @param $errline * @return bool */ public function errorHandler($errno, $errstr, $errfile, $errline) { echo '-----ERROR----', PHP_EOL; echo $errstr, PHP_EOL; echo 'Line:', $errline, ' in file: ', $errfile, PHP_EOL; echo '-------------', PHP_EOL; return true; } /** * * @static * @return void */ public static function setErrorHandler() { set_error_handler(array(new self(), "errorHandler")); } /** * * @static * @param string $className * @param null $method * @return void */ public static function test($className = 'stdClass', $method = null) { if (class_exists($className, true)) { $obj = new ReflectionClass($className); /** * */ $methods = $obj->getMethods(ReflectionMethod::IS_PUBLIC); foreach ($methods as $method) { $argsCount = $method->getNumberOfParameters(); $args = array(); for ($i = 0; $i < $argsCount; $i++) { $args[] = self::getRand(); } if ($method->isStatic()) { $result = call_user_func(array($className, $method->getName()), $args); } else { $obj = new $className(); $result = call_user_func(array($obj, $method->getName()), $args); } } } } }
これは非常に簡単ですが、多くの時間を節約できます。
使用例:
class badWritenClass { public function testFunc1($param) { echo count($param),PHP_EOL; } public function testFunc2($param) { $calcVar = $param['test'] / $param['test2'] * 50; echo $calcVar ,PHP_EOL; } public static function goodWritenFunc($param) { if (is_array($param) && isset($param['name'])) { echo 'Hello ', $param['name'],PHP_EOL; } else { echo 'Hello Guest!',PHP_EOL; } } } function testFunc1($param) { echo count($param) ,PHP_EOL; } function testFunc2($param) { $calcVar = $param['test'] + $param['test2'] * 50; echo $calcVar ,PHP_EOL; } /** * */ tester::setErrorHandler(); tester::$allowedTytes = array(tester::T_INTEGER, tester::T_STRING, tester::T_ARRAY, tester::T_OBJECT, tester::T_BOOLEAN, tester::T_FUNCTION, tester::T_NULL); /** * */ testFunc1(tester::getRand()); testFunc2(tester::getRand()); /** * */ tester::test('badWritenClass');
要約すると、私が「サイクル」したテスト方法はファジングと呼ばれています。
いくつかの関連リンク:
www.vr-online.ru/?q=content/fuzzing-tehnologija-ohoty-za-bagami-752
wiki.xakep.ru/Default.aspx?Page=fuzzing&AspxAutoDetectCookieSupport=1
psハブに関する私の最初のトピック、少し面倒で、おそらく多くの間違いです。あまりキックしないでください。すべてのコメントを考慮し、改善します。
updはvr-online.ruへのリンクを追加しました
upd2は、コメントからのコメントを考慮して、クラスを少し書き直しました