A pipe executes the two sides in parallel. The way you're attempting to do this is conceptually impossible: you can't test the status of the mysqldump command until it's finished if you do this test in parallel with the execution of mysqldump. You need to run mysqldump, wait for it to finish, and then decide whether to run gzip.
Since mysqldump has to finish running, its output has to go somewhere. Presumably you expect the output to be large since you're compressing it. Therefore the sensible option is to compress it. So compress the output unconditionally.
mysqldump -u username -ppassword dbname | gzip > test.gz
Note that I used |, not |&. Using |& here makes no sense: if there are any error messages, they'd end up mixed with the dump and it would be impossible to restore the dump.
The problem that remains to be solved is detecting whether mysqldump succeeded. Assuming that this is a bash or ksh script (i.e. it begins with #!/bin/bash or #!/bin/ksh or the like, not with #!/bin/sh), set the pipefail option, so that the pipeline fails if any part fails. (By default, the status of a pipeline is the status of its rightmost command and the other commands' status is ignored.)
#!/bin/bash set -o pipefail -o errexit tmp="mydump.tmp.$$.gz" trap 'rm -f "$tmp"' ERR INT TERM HUP mysqldump … | gzip >"$tmp" mv "$tmp" mydump.gz
Setting the errexit option ensures that if the pipeline fails then the script exits at that point (with the same error status as the pipeline). Thus a file called mydump.gz is only created if the dump was successful. The trap command sets up a trap so that if the script fails or is killed by one of the listed signals then the temporary file is deleted.