日期:2014-05-20  浏览次数:20887 次

【散300分】一个简单的压力测试引擎代码
我在这里还是简单描述一个压力测试引擎代码(而不是全部具体实现),同时用来演示 Parallel Extensions to the .NET Framework 这个东东的作用。

所谓压力测试,表面上看不过是运行一个或者几个测试用例一定次数(例如100次、1000次、5000次),然后统计不同压力下平均响应时间,并从时间变化的曲线拐点上来分析。

假设测试用例的原型定义是这样:
        private class TestCaseType
        {
            public TestCaseDelegate proc;  //测试程序
            public string desc;            //测试程序的标题(摘要说明)
        }

        private delegate void TestCaseDelegate();

可见测试用例就是一个没有参数并且没有返回值的方法。

接下来,假设你已经可以实现如下定义的一个获取测试用例的方法:
private static IEnumerable<TestCaseType> GetTestCases(this  Assembly[] assembly)
{
    。。。。
}

这个方法对于输入的一组 Asembly,可以遍历所有 class,反射其所有 Method,找出标记(Attribute)为测试用例的那些方法,并且返回为一组 TestCaseType。(这个过程与本文主旨无关,我省略了)

于是我要演示的压力测试的引擎代码就是:
        private static void StressTest(this  Assembly[] assembly, int 次数)
        {
            var tps = GetTestCases(assembly);
            if (tps.Count() == 0)
            {
                System.Console.WriteLine("******** 没有测试用例 ********");
                return;
            }

            var map = tps.AsParallel().SelectMany(tp => Clone(tp, 次数)).Select(tp => Test(tp));
            var reduce = from t in map
                         group t by t.proc into g
                         orderby g.Average(p => p.mi) descending
                         select new { proc = g.Key, desc = g.First().desc, mi = (long)g.Average(p => p.mi) };
            int testCnd = 0;
            reduce.ForEach(r => { System.Console.WriteLine("{0} 平均{1}毫秒\t{2}", ++testCnd, r.mi, r.desc.Description); });
        }

        //将测试用例重复多次
        private static IEnumerable<TestCaseType> Clone(TestCaseType t, int 倍数)
        {
            var c = new List<TestCaseType>();