我有一個創建在次(math.random * x)
次對象N
該方法將創建對象M
,其餘的給定x
2種不同的情況下(M, N)
的方法。單元測試的概率
我已經寫單元測試與嘲笑隨機數,所以我可以保證該方法的行爲如預期。但我不確定如何(如果)測試的概率是準確的,例如,如果x = 0.1
我期望在10個案例中有1個返回實例M.
如何測試此功能?
我有一個創建在次(math.random * x)
次對象N
該方法將創建對象M
,其餘的給定x
2種不同的情況下(M, N)
的方法。單元測試的概率
我已經寫單元測試與嘲笑隨機數,所以我可以保證該方法的行爲如預期。但我不確定如何(如果)測試的概率是準確的,例如,如果x = 0.1
我期望在10個案例中有1個返回實例M.
如何測試此功能?
拆分測試。第一個測試應該允許你定義隨機數生成器返回的內容(我假設你已經有了)。這部分測試只是滿足「如果隨機數發生器會返回一些值,我會得到預期的結果」。
第二個測試應該使用一些統計分析功能(如計算它多久返回每個值),只需運行隨機數發生器。
我建議與返回「創建M」和「創建N」的包裝來包裝真實發生器(或可能只是0和1)。這樣的話,你可以使用它的地方(這將創建兩個不同的實例應該不需要知道發電機是如何初始化或你如何將真實結果爲「創造X」的代碼是分開執行。
你不說的語言,所以我會做到這一點在Python的形式,而無需使用額外的最佳實踐測試樣板首先描述的功能:
def binomial_process(x):
'''
given a probability, x, return M with that probability,
else return N with probability 1-x
maybe: return random.random() > x
'''
然後,在TDD中,測試的精神對於這種功能(是的,誰不能只是先寫功能?):
import scipy.stats
import random
trials = 1000000
def binom(x):
return random.random() > x
然後寫你的測試功能,首先設定功能將數據從一個昂貴的過程放在一起:
def setUp(x, n):
counter = dict()
for _ in xrange(n):
result = binom(x)
counter[result] = counter.get(result, 0) + 1
return counter
那麼實際測試:
def test_binomial_process():
ps = (.01, .1, .33, .5, .66, .9, .99)
x_01 = setUp(.01, trials)
x_1 = setUp(.1, trials)
x_33 = setUp(.1, trials)
x_5 = setUp(.5, trials)
x_66 = setUp(.9, trials)
x_9 = setUp(.9, trials)
x_99 = setUp(.99, trials)
x_01_result = scipy.stats.binom_test(x_01.get(True, 0), trials, .01)
x_1_result = scipy.stats.binom_test(x_1.get(True, 0), trials, .1)
x_33_result = scipy.stats.binom_test(x_33.get(True, 0), trials, .33)
x_5_result = scipy.stats.binom_test(x_5.get(True, 0), trials)
x_66_result = scipy.stats.binom_test(x_66.get(True, 0), trials, .66)
x_9_result = scipy.stats.binom_test(x_9.get(True, 0), trials, .9)
x_99_result = scipy.stats.binom_test(x_99.get(True, 0), trials, .99)
setups = (x_01, x_1, x_33, x_5, x_66, x_9, x_99)
results = (x_01_result, x_1_result, x_33_result, x_5_result,
x_66_result, x_9_result, x_99_result)
print 'can reject the hypothesis that the following tests are NOT the'
print 'results of a binomial process (with their given respective'
print 'probabilities) with probability < .01, {0} trials each'.format(trials)
for p, setup, result in zip(ps, setups, results):
print 'p = {0}'.format(p), setup, result, 'reject null' if result < .01 else 'fail to reject'
然後寫你的函數(好吧,我們已經沒有):
def binom(x):
return random.random() > x
和運行測試:
test_binomial_process()
其中關於最後輸出給了我:
can reject the hypothesis that the following tests are NOT the
results of a binomial process (with their given respective
probabilities) with probability < .01, 1000000 trials each
p = 0.01 {False: 10084, True: 989916} 4.94065645841e-324 reject null
p = 0.1 {False: 100524, True: 899476} 1.48219693752e-323 reject null
p = 0.33 {False: 100633, True: 899367} 2.96439387505e-323 reject null
p = 0.5 {False: 500369, True: 499631} 0.461122365668 fail to reject
p = 0.66 {False: 900144, True: 99856} 2.96439387505e-323 reject null
p = 0.9 {False: 899988, True: 100012} 1.48219693752e-323 reject null
p = 0.99 {False: 989950, True: 10050} 4.94065645841e-324 reject null
感謝Aaaron,我沒加腳本語言,因爲它是比較測試的東西,可能不一致失敗的一個假設性的問題(理論上數學隨機是不可預測的,你預計有一半的電話會返回到0.5以上,但是你不能在測試中對此進行轉接)。我正在使用actionscript + asmock,並希望聽到有關處理與概率有關的測試的正確方法。謝謝 – Eran