Can you elaborate a little in terms of the set up you intend to have for each environment?
As general advice, if your application servers have more spare resources than your DB servers, think about having the mongos processes on the application servers, That at least removes some small burden from the DB hosts.
If this is truly a non-production environment, and you can live with a complete loss, then you can also cut down on the config server requirement by running just one. It has to be configDB x 1 or configDB x 3 - but whatever you do, always run 3 if the shard is in any way precious/valuable/hard to recreate, for production *always* use 3.
If I assume that the answers to my questions above are: No, no virtualization possible, yes we want to use sharding everywhere because that is the intended production environment, and yes we can run with different DBs, separate instances are not required, then a recommended set up given 3 physical hosts would look like this:
To simulate a full sharded environment you will likely want to go with a replica set for each shard (the minimum for functional testing is 1 primary per shard, but that is not representative of a production environment). The minimum for a replica set (that functions correctly) is 1 x Primary, 1 x Secondary and 1 x Arbiter (to avoid non-majority issues if one of the primaries is lost). The arbiters are generally light-weight, the secondaries next, with the primaries having the heaviest load. So, you could do something like this with just 3 actual machines:
host 1: Primary(shard1); Arbiter(shard2);
host 2: Primary(shard2); Arbiter(shard1);
host 3: Secondary(shard1); Secondary(shard2); ConfigDB
host 3 would also be the candidate for a mongos process if not running on your app servers. This leaves the primaries largely unimpeded by other processes, gives you a decent approximation of a production environment and (as long as nothing fails) should not overload a single host.
Adam.