Как имитировать загрузку файлов в командной строке php
Я новичок в PHPUnit Testing framework.
как мы знаем, что move_uploaded_file()
функция PHP не будет работать, пока файл не будет загружен через метод HTTP POST
Итак, вопрос в том, как имитировать это в командной строке PHP
Примечание: используя селен, мы можем имитировать webform.. но мне нужна другая альтернатива.
5 ответов
вам в основном нужно сделать ваш код более проверяемым. Разбейте его, чтобы вы могли проверить простой акт загрузки файла через HTTP отдельно от остальной части кода. Основное использование move_uploaded_file
это поставить дополнительную остановку безопасности, чтобы вас нельзя было обмануть, перемещая какой-то другой файл, move_uploaded_file
просто убедитесь, что файл был загружен в том же запросе, а затем перемещает его. Вы можете просто переместить файл с помощью rename
как хорошо. Таким образом, разбейте свое приложение на одно Request
объект, который представляет и инкапсулирует текущий HTTP-запрос, включая проверку загруженных файлов с помощью is_uploaded_file
. Как только это будет подтверждено, вы можете использовать rename
вместо move_uploaded_file
. В ваших тестах вы можете издеваться над Request
объект и проверить другой код.
вы также можете просто сделать move_uploaded_file
mockable, например, вот так:
class Foo {
public function do() {
...
$this->move_uploaded_file($from, $to);
...
}
protected function move_uploaded_file($from, $to) {
return move_uploaded_file($from, $to);
}
}
в ваших тестах вы можете расширить / издеваться над классом и переопределить Foo::move_uploaded_file
всегда return true
, для пример.
вот тут PHP тестирование Framework (PHPT) входит. Он установлен с PEAR и позволяет подавать HTTP-запросы, операции ввода-вывода, загрузки файлов и т. д. к php скрипту, написав .phpt
файл и выполнение его с помощью run-phpt
или pear run-tests <file.phpt>
. Вы также можете запустите их с помощью PHPUnit используя PhptTestCase
и PhptTestSuite
.
для имитации загрузки файла вам нужно использовать --POST_RAW--
раздел С такими же данными браузер отправляет. Это пример с сайта PHP QAT:
важно: к сожалению, пример на их сайте не удается без каких-либо объяснений.
is_uploaded_file.phpt по
--TEST--
is_uploaded_file() function
--CREDITS--
Dave Kelsey <d_kelsey@uk.ibm.com>
--SKIPIF--
<?php if (php_sapi_name()=='cli') die('skip'); ?>
--POST_RAW--
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
content-disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
abcdef123456789
--AaB03x--
--FILE--
<?php
// uploaded file
var_dump(is_uploaded_file($_FILES['pics']['tmp_name']));
// not an uploaded file
var_dump(is_uploaded_file($_FILES['pics']['name']));
// not an uploaded file
var_dump(is_uploaded_file('random_filename.txt'));
// not an uploaded file
var_dump(is_uploaded_file('__FILE__'));
// Error cases
var_dump(is_uploaded_file());
var_dump(is_uploaded_file('a', 'b'));
?>
--EXPECTF--
bool(true)
bool(false)
bool(false)
bool(false)
Warning: is_uploaded_file() expects exactly 1 parameter, 0 given in %s on line %d
NULL
Warning: is_uploaded_file() expects exactly 1 parameter, 2 given in %s on line %d
NULL
под управлением
pear run-tests --cgi=PHPCGI is_uploaded_file.phpt
Мануэль Пихлер написал пример в блоге, но это также терпит неудачу.
если вы хотите использовать PHPUnit для проверки загрузки файла без высмеивания фактического move_uploaded_file
проверьте, что вы можете использовать .phpt
тестовые случаи, которые PHPUnit может выполнить, поэтому имитируйте веб-запрос.
в основном вы создаете .phpt
файл, который выглядит так:
автономный пример: uploadTest.phpt
--TEST--
Example test emulating a file upload
--POST_RAW--
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryfywL8UCjFtqUBTQn
------WebKitFormBoundaryfywL8UCjFtqUBTQn
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain
Qafoo provides quality assurance support and consulting
------WebKitFormBoundaryfywL8UCjFtqUBTQn
Content-Disposition: form-data; name="submit"
Upload
------WebKitFormBoundaryfywL8UCjFtqUBTQn--
--FILE--
<?php
var_dump(is_uploaded_file($_FILES['file']['tmp_name']));
?>
--EXPECT--
bool(true)
выполнить, используя phpunit uploadTest.phpt
для полного объяснения проверьте сообщение в блоге, описывающее подробности:
http://qafoo.com/blog/013_testing_file_uploads_with_php.html
также: There is working sample code over at github
более подробный пример реального мира:
--TEST--
Example test emulating a file upload
--POST_RAW--
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryfywL8UCjFtqUBTQn
------WebKitFormBoundaryfywL8UCjFtqUBTQn
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain
Qafoo provides quality assurance support and consulting
------WebKitFormBoundaryfywL8UCjFtqUBTQn
Content-Disposition: form-data; name="submit"
Upload
------WebKitFormBoundaryfywL8UCjFtqUBTQn--
--FILE--
<?php
require __DIR__ . '/UploadExample.php';
$upload = new UploadExample('/tmp');
$upload->handle('file');
var_dump(file_exists('/tmp/example.txt'));
?>
--EXPECT--
bool(true)
лично мне нравится ответ deceze выше.
однако другой возможностью является использование пространства имен.
код для этого включен Github.
вы можете загружать файлы из командной строки с помощью cURL:
curl --form input-name=@filename http://localhost/upload.php
С input-name
- имя поля ввода в обычно используемом HTML и filename
путь и имя файла для загрузки-не забудьте поместить их в кавычки или избежать специального символа, если они содержат некоторые.
однако это, очевидно, по-прежнему требует запуска скрипта с веб-сервера, и, по-видимому, это не то, что вы хотите, поэтому см. как я могу писать тесты для загрузки файлов в PHP? для способов тестирования загрузки файлов с помощью PHPUnit.