摘要:分錢的方法 - 單元測試 (2)
[TestMethod]
public void TestEasy()
{
BaseDivider divider = new MyDivider2();
// 比例隨機建立,100人, 分100000, 最小單位0.1
randomFactorsTest(divider, 100, 100000, 1);
// 比例隨機建立,3人, 分100000000, 最小單位1
randomFactorsTest(divider, 3, 100000000, 1);
// 比例隨機建立,3人, 分100.01, 最小單位1
randomFactorsTest(divider, 3, 100.01M, 1);
// 比例隨機建立,1000000人, 分10, 最小單位1
randomFactorsTest(divider, 1000000, 10, 1);
}
// 注意: 若使用多執行緒測試,將會發生下列bug
// http://connect.microsoft.com/VisualStudio/feedback/details/587390/threadabortexception-when-running-two-tests-in-parallel-one-taking-40-seconds
// 需將數量級減少,縮短測試時間
[TestMethod]
public void TestStrongSmall()
{
BaseDivider divider = new MyDivider2();
Random rnd = new Random();
// 比例隨機建立,1~100000人, 分0~10, 最小單位0~0.1^10, 100次
for (int i = 0; i < 1000; i++)
randomFactorsTest(divider, rnd.Next(1, 100000), rnd.Next(0, 10), rnd.Next(10));
}
[TestMethod]
public void TestStrongBig()
{
BaseDivider divider = new MyDivider2();
Random rnd = new Random();
// 比例隨機建立, 1~100000人, 分100000~int.MaxValue, 最小單位0~0.1^10, 100次
for (int i = 0; i < 1000; i++)
randomFactorsTest(divider,
rnd.Next(1, 100000), rnd.Next(100000, int.MaxValue), rnd.Next(10));
}
private void randomFactorsTest(BaseDivider divider, int count, decimal totalValue, int digits)
{
decimal[] factors = getFactors(count);
decimal[] values = divider.Divide(factors, totalValue, digits);
roleTest(factors, values, totalValue, digits);
}
private static void roleTest(decimal[] factors,decimal[] values, decimal totalValue, int digits)
{
decimal vUnit = totalValue / factors.Sum(); // (Vs / Fs)
decimal minUnit = (decimal)Math.Pow(0.1, digits);
// 限制3: 總共分配的的值必須要是最小單位的最大整數倍
Assert.AreEqual(values.Sum(), Math.Truncate(totalValue / minUnit) * minUnit);
decimal Dmax = -minUnit;
decimal Dmin = minUnit;
for (int i = 0; i < factors.Length; i++)
{
decimal d = values[i] - factors[i] * vUnit;
// 限制1: 每筆的誤差不能大於最小單位
Assert.IsTrue(Math.Abs(d) < minUnit);
if(d > Dmax)
Dmax = d;
if(d < Dmin)
Dmin = d;
}
// 限制4(公平性限制) Dmax - Dmin <= p
Assert.IsTrue(Dmax - Dmin <= minUnit);
}
private decimal[] getFactors(int count)
{
Random rnd = new Random();
decimal[] factors = new decimal[count];
for (int i = 0; i < count; i++)
factors[i] = rnd.Next(100000);
return factors;
}