Как имитировать загрузку файлов в командной строке 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.