How to simulate file upload at php command line

I am new to PHPUnit testing framework.

since we know that the move_uploaded_file() function of PHP will not work until the file is uploaded using the http POST method

So the question is how to simulate this on a PHP command line

Note: using selenium, we can simulate webform .. but I need another alternative.

+6
source share
5 answers

You basically need to make your code more verified. Break it down so that you can test the simple act of uploading a file via HTTP separately from the rest of the code. The main use of move_uploaded_file is to add an extra security stop so that you cannot be tricked by moving any other file, move_uploaded_file just ensures that the file was loaded in the same request and then moved. You can simply move the file using rename . Thus, break the application to have one Request object that submits and encapsulates the current HTTP request, including forcing it to check downloaded files using is_uploaded_file . After that, you can use rename instead of move_uploaded_file . In your tests, you can then mock the Request object and check your other code.

You can also just make move_uploaded_file mockable, for example as follows:

 class Foo { public function do() { ... $this->move_uploaded_file($from, $to); ... } protected function move_uploaded_file($from, $to) { return move_uploaded_file($from, $to); } } 

In your tests, you can extend / mock a class and override Foo::move_uploaded_file always return true , for example.

+7
source

Here is the PHP Testing Framework (PHPT). It installs with PEAR and allows you to send HTTP requests, I / O, file downloads, etc. In a PHP script, by writing a .phpt file and executing it with run-phpt or pear run-tests <file.phpt> . You can also run them using PHPUnit using PhptTestCase and PhptTestSuite .

To simulate a file download, you need to use the --POST_RAW-- section with the same data that the browser sends. This is an example from the PHP QAT website:

Important: Unfortunately, the example on your site ends without explanation.

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 

Launch

 pear run-tests --cgi=PHPCGI is_uploaded_file.phpt 

Manuel Pichler wrote an example in a post, but he also fails.

+3
source

If you want to use PHPUnit to test file downloads without mocking the actual check of move_uploaded_file , you can use test cases .phpt that PHPUnit can execute, so simulate a web request.

Basically you create a .phpt file that looks like this:

Standalone example: 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) 

run with phpunit uploadTest.phpt


For a full explanation, check out the blog post for details:

http://qafoo.com/blog/013_testing_file_uploads_with_php.html

Also: There is working sample code over at github


A more detailed example of the real world:

 --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) 
+2
source

Personally, I like the deceze answer above.

However, another possibility is to use a namespace .

The code for this is on Github .

+1
source

You can upload files from the command line using cURL :

 curl --form input-name=@filename http://localhost/upload.php 

with input-name being the name of the input field in commonly used HTML and filename - the path and name of the file to be uploaded - don't forget to put them in quotation marks or avoid a special character if they contain some.

However, this explicitly requires running the script from the web server, and apparently this is not what you want, so see How to write tests to upload files in PHP? for ways to test file downloads using PHPUnit.

0
source

All Articles