How can I discourage poor design while using automatic grading of submissions? Automatic grading is great for saving time on marking programming tasks, so there's more time to focus on actual teaching, but I've noticed a few flaws. Since work is essentially marked based on passing unit tests, thoughtful design often gets ignored, and excessively complex solutions are considered just as good as elegant ones.

I recently read this article about how this is a problem on MITx—instead of this solution:

return max(min(hi,x),lo)


A student wrote this:

1 * lo + 0 * x + 0 * hi # too low
0 * lo + 1 * x + 0 * hi # in range
0 * lo + 0 * x + 1 * hi # too high


Automatic testing would find these equivalent,  but clearly one is incomprehensible and the other is relatively logical and sound.

This is also recognised in Using Test-Driven Development in the Classroom:


  Despite its classroom utility, an automatic grading strategy like
  the one embodied in the Curator also has a number of shortcomings:
  
  
  Students focus on output correctness first and foremost;
  all other considerations are a distant second at best (design,
  commenting, appropriate use of abstraction, testing one's
  own code, etc.). This is due to the fact that the most immediate
  feedback students receive is on output correctness [...]
  


Is there any way of evaluating code style and design automatically (or at least detecting very poor solutions)? I've thought about using some static code analysis to try and evaluate solutions (e.g. cyclomatic complexity, or tools like these), although I've not tried them yet. Are there any reliable solutions to this, or must it be done manually? Does static code analysis help in any way?
I am a strong advocate for code interviews.  I make principles of style into about 50% of a lab grade (though I do permit kids to go back and refactor after an interview for full credit.)

For some context, I discuss regularly that there are two audiences of code: computers, and people, and that these audiences have very different needs.

Since my high school class is structured with lab periods, I will grade lab 1 during lab 2 work times (and so on). This gives me class time to get my interviews done. At the start, the code needs a lot of work. However, by the time we have arrived at lab 3, the kids are mostly creating crystal clear code.

Don't drop that autograder! Even with code interviews, it is still tremendously useful. Having a good autograder means that, during the interview, I only need to look for style issues. I can assume that even the strangest of their code (and boy, is there ever strange code at the beginning!) produces the correct output.  That permits the interview process to focus in, laser-like, on how well the student wrote for the second audience.