How can I automate the grading of programming assignments? As a TA, the usual workflow for grading programming assignments for an introductory course would be:


Some instructors used email as a submission mechanism (yes, really.)
So, search for submissions in email and download every submission
Organize it to make grading easier later on
Go into each directory, compile it. Realize it doesn't work.
If I email the student, I get a response 'Works on my computer'
Debug it and make it compile on my computer
Due to lack of test cases, every student has demonstrated their work with their own version of output on the console
Decipher their output and hopefully they get a good grade
Partial grading is hard because I have to dig through the code and see what parts are done and how far away they are from a working solution


All in all, it takes about 7-10 minutes per submission if I do things carefully. 100 students, 3 programming problems = 300 submissions. 10 mins per submission = 3000 minutes = 2 days of continuous grading. Impossible.

I have heard instructors make scripts, use some tools. Sometimes, they get super strict on the output of the program so they can grade it easily. Worse, they make problems easier so it's easier to grade.

How can I automate this efficiently?
The degree of automation that you can achieve depends on how you want to grade. The most valuable type of grading (to a student) does not only cover whether the code works or not, but also offers suggestions as to how to make it better, including readability, design, and so no. And that you cannot totally automate. 

You can (and should) automate basic setups, compilation, and  tests, and generally remove as much grading-boilerplate as possible via automation. Todo so, the first step is to make sure that students will follow certain reproducibility guidelines. In my case,


The instructions for assignments always include a specific test environment and test command, that must run. So for example, this could be "jdk 1.7 as installed in the lab" + "javac of your .java files". This allows me to ignore "works for me in my place" excuses -- unless it works in the test environment, it will not receive a passing grade. Note that this is generally not a the development environment; that may be eclipse or whichever other IDE they choose. I generally try to stick to the lowest common bare-metal standard.
JUnit or other unit-testing frameworks are great to assert minimal performance. You can either request them to write their own tests (make sure to specify what these should cover), or provide them with pre-written tests (more effort, but hopefully more in-depth testing). Ryan Nutt's answer also offers good suggestions. Unit-testing is huge not only because it helps you to grade, but also because it makes students aware of their own errors; they will then fix these errors before submitting the assignments, which is a clear win-win.
Mandating command-line friendly build tools (maven, scons, makefiles, scripts, ...) really helps to quickly pass the above tests.
Students must use an online submission system (eg.: Moodle task) to upload their code.


Afterwards, in my grading setup, 


I download all submissions for the assignment, and each will be nicely tucked into files named after the uploading student. I then run a small shell script that extracts each submission into a single folder. After significant frustration, the script has been tweaked to deal with .7z, .rar, and .tgz archives instead of the requested .zip files. 
I write small per-assignment scripts that I can point at a submission and will 


open my favorite IDE pointing at the submission
compare it side-by-side with previous submissions by the same author, assuming that this is an incremental project, using meld or a similar visual diff tool.
launch any corresponding unit tests to see if anything fails

I then write a per-assignment check-list of items that I want to look at in each submission. This gets refined until I have graded 5 or so, when it sort of stabilizes. 
Finally, I get to grade the bulk of submissions, writing comments for students as I go, and often copying and pasting comments from previous submissions. When all are graded (and not before, because I sometimes have to backtrack or refine grading criteria), I copy-and-paste comments and grades to the online submission tool so that students can see them. The most frequent mistakes make the bulk of the next lecture.


So essentially I recommend standardizing as much as possible, and investing some time into per-assignment automation, in order to speed up actual grading.