C# · 12月 31, 2021

c# – 我可以在Visual Studio中为UnitTest / LoadTest创建一个自定义的TestContext定时器吗?

我的一些单元测试有一个在循环中定义的睡眠.我不仅要描述测试的每次迭代,而且要对所有迭代的整体时间进行分析,以显示任何非线性缩放.例如,如果我概述“整体”,它包括睡眠的时间.我可以使用秒表开始/停止,使其只包括doAction().但是,我不能将Stopwatch结果写入TestContext结果. [TestMethod] public void TestMethod1() { TestContext.BeginTimer(“Overall”); for (int i = 0; i < 5; i++) { TestContext.BeginTimer(“Per”); doAction(); TestContext.EndTimer(“Per”); Sleep(1000); } TestContext.EndTimer(“Overall”); }

看来TestContext可以被继承和重新定义.但是,我没有看到任何有关如何写回到事务存储的示例.

有没有实现这个我可以参考,还是另一个想法.我想在Visual Studio为LoadTest提供的同一报告中看到它.否则我必须写我自己的报告.

此外,我已经尝试嗅探将这些写入到LoadTest数据库的sql,但没有成功地找出如何.应该有SPROC呼叫,但我认为是测试结束时的所有数据.

解决方法 那我也有类似的问题.我想在Visual Studio中的最终测试结果中报告一些额外的数据/报告/计数器,我找到了一个解决方案.

首先,这不能用你正在尝试的方式来完成.在TestContext存在的负载测试和单元测试之间没有直接的连接.

第二,你必须了解visual studio如何创建报告.它从OS的performance counters收集数据.您可以编辑这些计数器,删除不需要的计数器,并添加所需的其他计数器.

如何编辑计数器

负载测试配置有两个关于计数器的基本部分.这些是:

>柜台.这些是一组计数器,例如默认添加的代理.如果打开这个计数器,你会看到它收集计数器,如内存,处理器,PhysicalDisk e.t.c.因此,在测试结束时,您可以看到所有代理商的所有数据.如果您想为此计数器添加更多计数器,您可以双击它(从加载测试编辑器,请参见下图),然后选择添加计数器.这将打开一个带有系统所有计数器的窗口,并选择所需的计数器.
>计数器集映射.在这里,您将计数器与您的机器相关联.默认情况下,[CONTROLLER MACHINE]和[AGENT MACHINES]添加了一些默认计数器.这意味着映射到[CONTROLLER MACHINE]的计数器组中包含的所有计数器将从控制器机器收集.同样适用于所有代理商.

您可以添加更多的计数器集和更多的机器.右键单击计数器集映射 – >管理计数器集…新窗口打开如下:

如您所见,我已经添加了名为db_1的额外机器.这是机器的计算机名称,它必须与控制器位于同一个域,才能访问并收集计数器.我也把它标记为数据库服务器并选择了sql计数器集(默认为sql计数器,但您可以编辑它,并添加任何您想要的计数器).现在每次执行此负载测试时,控制器将转到计算机名为db_1的计算机,并收集将在最终测试结果中报告的数据.

现在的编码部分

好的,在这个(大)介绍之后,现在是时候看看如何将你的数据添加到最终的测试结果中.为此,您必须创建自己的custom performance counters.这意味着必须在收集这些数据的机器中创建一个新的Performance Counter Category.在你的情况下,在所有的代理中,因为这是执行单元测试的地方.

在代理程序中创建计数器后,您可以编辑如上所示的代理计数器集,并选择额外的自定义计数器.

以下是有关如何执行此操作的示例代码.

首先为所有代理商创建性能计数器.在每个代理机器上运行此代码一次(或者您可以在load test plugin中添加):

void CreateCounter() { if (PerformanceCounterCategory.Exists(“MyCounters”)) { PerformanceCounterCategory.Delete(“MyCounters”); } //Create the Counters collection and add your custom counters CounterCreationDataCollection counters = new CounterCreationDataCollection(); // The name of the counter is Delay counters.Add(new CounterCreationData(“Delay”,”Keeps the actual delay”,PerformanceCounterType.AverageCount64)); // …. Add the rest counters // Create the custom counter category PerformanceCounterCategory.Create(“MyCounters”,”Custom Performance Counters”,PerformanceCounterCategoryType.MultiInstance,counters);}

在这里你的测试代码:

[TestClass]public class UnitTest1{ PerformanceCounter OverallDelay; PerformanceCounter PerDelay; [ClassInitialize] public static void ClassInitialize(TestContext TestContext) { // Create the instances of the counters for the current test // Initialize it here so it will created only once for this test class OverallDelay= new PerformanceCounter(“MyCounters”,”Delay”,”Overall”,false)); PerDelay= new PerformanceCounter(“MyCounters”,”Per”,false)); // …. Add the rest counters instances } [ClassCleanup] public void CleanUp() { // Reset the counters and remove the counter instances OverallDelay.RawValue = 0; OverallDelay.EndInit(); OverallDelay.RemoveInstance(); OverallDelay.Dispose(); PerDelay.RawValue = 0; PerDelay.EndInit(); PerDelay.RemoveInstance(); PerDelay.Dispose(); } [TestMethod] public void TestMethod1() { // Use stopwatch to keep track of the the delay Stopwatch overall = new Stopwatch(); Stopwatch per = new Stopwatch(); overall.Start(); for (int i = 0; i < 5; i++) { per.Start(); doAction(); per.Stop(); // Update the “Per” instance of the “Delay” counter for each doAction on every test PerDelay.Incerement(per.ElapsedMilliseconds); Sleep(1000); per.Reset(); } overall.Stop(); // Update the “Overall” instance of the “Delay” counter on every test OverallDelay.Incerement(overall.ElapsedMilliseconds); }}

现在,当您的测试执行时,他们会向计数器报告他们的数据.在负载测试结束时,您可以在每个代理机器中看到计数器,并将其添加到图形中.将以MIN,MAX和AVG值报告.

结论

>我认为(经过几个月的研究),这是将测试中的自定义数据添加到最终负载测试报告的唯一方法.
>可能看起来太难了.那么,如果你明白这一点,那就不难做到优化了.我已经将这个功能包装在一个类中,以便更容易地进行初始化,更新和管理计数器.
这是非常有用的.我现在可以从我的测试中看到统计信息,这是不可能的默认计数器.当我们对网络服务的Web请求失败时,我可以抓住错误并更新适当的计数器(例如,超时,服务不可用,请求拒绝…).

我希望我能帮忙.