读书人

【散300分】一个简单的压力测试引擎代

发布时间: 2012-03-12 12:45:33 作者: rapoo

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

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

假设测试用例的原型定义是这样:

C# code
        private class TestCaseType        {            public TestCaseDelegate proc;  //测试程序            public string desc;            //测试程序的标题(摘要说明)        }        private delegate void TestCaseDelegate();

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

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

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

于是我要演示的压力测试的引擎代码就是:
C# code
        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>();            for (var i = 0; i < 倍数; i++)                c.Add(new TestCaseType { desc = t.desc, proc = t.proc });            return c;        }        //单独执行一个测试用例并记录耗时。如果可能,Test应该在一个Master机辅助下分布到不同的Worker机上执行。        private static TestCaseTestType Test(TestCaseType p)        {            var wt = new Stopwatch();            wt.Start();            p.proc();            wt.Stop();            return new TestCaseTestType { proc = p.proc, desc = p.desc, mi = wt.ElapsedMilliseconds };        }        static public void ForEach<T>(this IEnumerable<T> array, Action<T> proc)        {            foreach (T obj in array)                proc(obj);        }


这里如果不写 AsParallel() 就是普通的顺序执行测试,而写上就可以利用多核多进程的能力并行执行了。

这个算法的过程是:找到相关的测试用例,然后重复执行的次数,并行执行,然后统计出每一个测试用例的平均执行时间,最后按照执行时间从高到低的顺序打印出来。

如果你的计算机有多核,或者如果Test方法分布到其它计算集群执行主机上,就可以大大提高性能。

[解决办法]
帮顶~谢谢楼主分享~
[解决办法]

[解决办法]
学习啦~~~~
[解决办法]
关注,帮顶,学习!
[解决办法]

[解决办法]
靠,作为sp1234资深粉丝+研究者,我的确来晚了。。。。
[解决办法]
收藏并学习
[解决办法]
探讨


代码一次性写成,以后我就从来没有优化过。也用不着太多考虑优化!这就是Linq的好处。


[解决办法]
得 学习LINQ
[解决办法]
学习。
[解决办法]
mark
[解决办法]
学习一下!!
[解决办法]
顶,刚接触LINQ。
[解决办法]
PLinq是个好东西啊,现在就等2010发布了
[解决办法]
mARK
[解决办法]
没怎么看懂这个引擎,原理是什么呢? 1234大侠能多给点注释吗
[解决办法]

[解决办法]
谢谢,学习了
[解决办法]
学习
[解决办法]
Linq 的性能似乎不是很好。
[解决办法]
好东西!谢谢分享,收藏!
[解决办法]
学习了,感谢LZ
[解决办法]
哈哈,学习
[解决办法]
uppppppppp

读书人网 >.NET

热点推荐