An alternative is to use pyethereum.tester, pytester for short (and not to be confused with py.test).
pytester is part of pyethereum, the Ethereum Foundation's python client which has undergone a security audit (like Geth) and part of the Ethereum Bounty Program. Agree it's frustrating to chase down simulator problems and I wouldn't classify it as one: it has been very reliable and a bug found using pytester could well be a consensus issue in pyethereum itself and worthy of a bounty.
As you specifically asked about mining, here's an example of mining 105 blocks
from ethereum import tester as t
initial_gas = 0
t.gas_limit = 100000000
s = t.state()
c = s.abi_contract('functions/output.se')
assert(c.submitReportHash(1010101, 3232, -1, 222, 0)==-2), "Nonexistant event check broken"
event1 = c.createEvent(1010101, "new event", 5, 1, 2, 2)
bin_market = c.createMarket(1010101, "new market", 2**58, 100*2**64, 184467440737095516, [event1], 1)
report_hash = c.makeHash(0, 2**64, event1)
print c.submitReportHash(1010101, report_hash, 0, event1, 0)
assert(c.submitReportHash(1010101, report_hash, 0, event1, 0)==1), "Report hash submission failed"
assert(c.submitReport(1010101, 0, 0, 0, 2**64, event1, 2**64)==1), "Report submission failed"
print "Test make reports OK"
pytester also works with Solidity code. The Ethereum Alarm Clock uses pytester to mine many blocks so that it can test, for example, that the clock wakes up far in the future. The
wait_for_block is via Populus, a framework which uses pytester; Populus also has an option of testing using an actual Geth node.
Another Solidity example that suggests the power of pytester to test arbitrarily complex scenarios, is with ether_ad, under Ethereum's dapp-bin.