This is pretty straightforward tweak to the Trac Workflow. The documentation for adding optional testing is quoted below:
By adding the following to your
[ticket-workflow] section of trac.ini
you get optional testing. When the
ticket is in new, accepted or
needs_work status you can choose to
submit it for testing. When it's in
the testing status the user gets the
option to reject it and send it back
to needs_work, or pass the testing and
send it along to closed. If they
accept it then it gets automatically
marked as closed and the resolution is
set to fixed. Since all the old work
flow remains, a ticket can skip this
entire section.
testing = new,accepted,needs_work,assigned,reopened -> testing
testing.name = Submit to reporter for testing
testing.permissions = TICKET_MODIFY
reject = testing -> needs_work
reject.name = Failed testing, return to developer
pass = testing -> closed
pass.name = Passes Testing
pass.operations = set_resolution
pass.set_resolution = fixed
Now all tickets must go through the "testing" state before the "pass" state.
To ensure that only certain testers can change a ticket from "testing" to "pass", create a new permission called TICKET_PASS (the trac admin can do this in the web UI), and add the following to your the workflow section of your trac.ini:
pass.permissions = TICKET_PASS
IMHO, it's sufficient to just require that tickets go through testing before they pass. Any reasonable developer knows that they shouldn't move a ticket from the "testing" state to the "passing" state unless it's passed whatever quality control you do. And since there's a history of their actions, they can be blamed for inappropriately marking tickets as "pass". Restricting the privileges will probably get in the way (distracting the trac admin) more than it helps.
[NB: I had to remove all but one of the hyperlinks to documentation b/c my rep is too low. Sigh.]