- Their code is large, messy and bug-laden
- They have very superficial knowledge of their problem domain and their tools
- Their code has a lot of copy and paste, and they have very little interest in techniques that reduce it
- They fail to account for edge cases while inefficiently dealing with the general case
- They're always rushing around putting out fires, trying to look like heroes battling vast problems against impossible odds
- They never have time to comment their code or break it into smaller pieces
- Empirical evidence plays no role in their decisions
It would be hard to self-test, but some clues would be: do you think you're the best programmer in the world? Do you find code with a lot of functions messier and harder to understand than code with only a few large functions? Do you routinely copy code from one place to another and make a few small changes to it? Do your programs tend to be a few huge files or lots of small files? When you're asked to make a change, do you usually have to touch most of the code or just a small chunk of it? If you say 'yes' to most of these, you're probably bad. If not, you're probably alright. :)
Another clue is to go read the CodeSOD articles at The Daily WTF. If you find them funny or horrifying, you're probably alright. If you don't understand what makes them terrible, you're probably bad.
There are known knowns, known unknowns, and unknown unknowns. The problem with really bad programmers, is that the unknown unknowns for them are really large... so they have no ability to gauge just how incompetent they are.
If someone is trying to improve themselves they are at least "not bad". And probably will be good/great some day.