如何为公平分配算法创建单元测试?

时间:2011-05-29 14:04:42

标签: c# unit-testing tdd nunit

我有以下算法:
如果列出帐户,我必须在系统用户之间公平分配。
现在,为了减轻用户的工作量,我必须将它们分开几天 因此,如果某个帐户有服务订单,则必须将其插入到将在547天(一年半)内分发的列表中。如果帐户没有服务订单,则必须将其插入将在45天(一个半月)内分发的列表。
我使用a question I asked before中的以下LINQ扩展名:

public static IEnumerable<IGrouping<TBucket, TSource>> DistributeBy<TSource, TBucket>(
this IEnumerable<TSource> source, IList<TBucket> buckets)
{
    var tagged = source.Select((item,i) => new {item, tag = i % buckets.Count});
    var grouped = from t in tagged
                  group t.item by buckets[t.tag];
    return grouped;
}

我可以保证它有效 我的问题是我真的不知道如何对所有这些案件进行单元测试 我可能有5个用户和2个帐户,可能不足以分开一年半甚至一个半月。
我可能有547个帐户和547个系统用户,因此每个系统用户每天都会处理每个帐户 基本上我不知道我应该创建什么样的数据集,因为它似乎有太多的选项,我应该断言什么因为我不知道分布将如何。

2 个答案:

答案 0 :(得分:2)

从边界条件(方法输入的自然限制)和任何已知的拐角情况开始(方法以意外方式运行的地方,并且您需要特殊代码来解释这一点)。

例如:

  • 当帐户为零时,该方法的行为如何?
  • 零用户?
  • 正好一个帐户和用户
  • 547个帐户和547个用户

听起来你已经知道了很多预期的边界条件。最初的角落案例将更难以考虑,但在开发该方法时,您可能会遇到其中一些案例。它们也会自然地通过手动测试 - 每次发现错误时都会进行新的必要测试。

一旦您测试了边界条件和边角情况,您还应该查看其他情况的“公平”样本 - 例如您的5个用户和2个帐户示例。您不能(或至少可以说,不需要)测试方法中的所有可能输入,但您可以测试输入的代表性样本,例如不均衡的会计分配。

答案 1 :(得分:0)

我认为您的部分问题是您的代码描述了您如何解决问题,而不是您尝试解决的问题。您当前的实现是确定性的,并给您一个答案,但您可以轻松地将其与另一个“公平分配器”交换,这将给您一个细节不同的答案(可能不同的用户将被分配不同的帐户),但满足相同的要求(分配是公平的) 一种方法是关注“公平”的含义。而不是检查当前实现的确切输出,可能重新构建它,以便在高级别,它看起来像:

public interface IAllocator
{ IAllocation Solve(IEnumerable<User> users, IEnumerable<Account> accounts); }

并编写测试,以验证用户的帐户的具体实施,但分配是公平的,待定义 - “每个用户应分配相同数量的帐户,加上或减去一个”。定义公平是什么,或者算法的确切目标是什么,应该可以帮助您确定感兴趣的角落案例。解决更高级别的目标(分配应该公平,而不是具体分配)应该允许您轻松交换实现并验证分配器是否正在执行其工作。