I have very little knowledge in testing and I wish to seek guidance in the following scenario - I have a piece of code where it takes in some arguments (filename, path etc) and uploads the file specified to a remote ftp server. So, the goal of the testing would be to check if the file is uploaded to the correct directory in the ftp server.
Now, I don't suppose I should involve the remote server in my test script, so should I setup a ftp server locally and mimick the file structure, or is there a mock ftp tool available in python to facilitate these scenarios?
Also, is this unit testing or functional testing?
We have some functional tests that truly do hit a real FTP server that we keep running as part of our staging environment. The config of our Django project is slightly different when running tests, so it hits this 'test' FTP server rather than any of our real servers or any of our client's. Having said that, these are amongst our slowest-to-run tests, so I'm looking to rewrite them to use an ftp server on the localhost, started & shut down by the test that needs it.
A mock ftp server sounds like a good idea. Can't wait to try it out, thanks @Bryce. For third-party servers in general, it might be problematic to be sure that your mocks actually matched the server API, but for FTP, this seems stable and well-understood enough that this shouldn't be a problem.
Functional testing invokes your entire system end-to-end, to check that user-visible behavior is what your spec says it should be, to assure you that your product really works, so you can confidently deploy new versions no matter what changes the code contains. The primary failing of functional tests is to exercise product code in ways that differ from production (e.g. only running part of the code, running against a different database schema or vendor) They generally use real data, are large and hard to write (database setup in particular), and slow to run. It's often very difficult to write enough functional tests to verify your entire program's behavior for all possible permutations of inputs, and if you did write them, they would take forever to run. So instead, you write a small number of judiciously chosen functional tests to demonstrate key user workflows, and then augment these with unit tests:
Unit tests invoke a very small amount of code, such as a single function or method. The primary goal of unit tests is to be fast to run, and easy to write, so that you can write hundreds or thousands of them, get good coverage, and run them all, in a couple of seconds at most, before you commit. (or maybe even every time you hit save from your editor.) The primary failing of unittests is to be slow.
Tests which sound like they are a bit inbetween these two extremes are integration tests, that don't test the whole system end-to-end, but do test several layers or components are integrated properly. Sometimes these are useful, or are the easiest test to write, but they are lacking in the primary virtues of either proving the product as a whole actually works, or being very fast to run. As a result, I think one should strive to write the minimum number of integration tests you can get away with. (personally I think that number is zero for most projects, but other people disagree.)
python test sending files over ftp