How does GPG (or other programs using the OpenPGP file format) verify that it has succeeded with decryption (for symmetrically encrypted data)?

Is something appended to the clear text so there exist some expected data?

For example, I'm using these command lines:

gpg -c test.txt
gpg -d test.txt.gpg

The second command outputs

gpg: decryption failed: bad key

when a wrong key is entered.

How can the program know that it is a bad key? Why doesn't it simply return the random data generated by decrypting with a wrong key?

First I thought that maybe it used letter density to determine if it was plaintext, but then it manages to decrypt binary files too (and complain about wrong keys), and specially key files which should be completely random.

Of course, this is only a heuristic check: One in each $2^{16}$ keys will still look right.

If you need a more certain check of the right key, use either a digital signature (in the encrypted package), or use a "Symmetrically Encrypted Integrity Protected Data Packet" (section 5.13) instead of a plain encrypted packet.