加载测试,尝试生成随机名称,但为许多虚拟用户获取相同的名称

问题描述 投票:0回答:1

我正在使用Visual Studio性能测试。我想在每个请求之前生成一个随机名称。我正在使用这个WebTestRequestPlugin:

using System;
using System.ComponentModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.WebTesting;

namespace TransCEND.Tests.Performance.Plugins
{
    public class RandomStringContextParameterWebRequestPlugin : WebTestRequestPlugin
    {
        [Description("Name of the Context Paramter that will sotre the random string.")]
        [DefaultValue("RandomString")]
        public string ContextParameter { get; set; }

        [Description("Length of the random string.")]
        [DefaultValue(10)]
        public int Length { get; set; }

        [Description("Prefix for the random string.")]
        [DefaultValue("")]
        public string Prefix { get; set; }

        private readonly string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        private Random _random = new Random();

        public RandomStringContextParameterWebRequestPlugin()
        {
            ContextParameter = "RandomString";
            Prefix = "";
            Length = 10;
        }

        public override void PreRequestDataBinding(object sender, PreRequestDataBindingEventArgs e)
        {
            e.WebTest.Context[ContextParameter] = CreateNewRandomString();            

            base.PreRequestDataBinding(sender, e);
        }

        private string CreateNewRandomString()
        {
            var randomString = new string(Enumerable.Repeat(_chars, Length).Select(s => s[_random.Next(s.Length)]).ToArray()).ToLower();
            return $"{Prefix}{randomString}";
        }
    }
}

我的问题是,当我开始使用多个虚拟用户进行负载测试时,preRequest代码会立即为前几个用户运行,在每次运行时重写RandomName上下文参数。因此,当我的请求实际运行时,它们使用相同的随机名称,导致后端代码发生冲突。

我的问题是,即使用户负载很高,我如何为每个请求生成随机名称?

load-testing msloadtest
1个回答
1
投票

我认为问题是标准的随机数例程不是线程安全的。因此,每个虚拟用户(VU)获得相同的随机种子值,因此获得相同的随机数。有关更全面的解释,请参阅herehere

CreateNewRandomString的代码没有显示在问题中,但它可能使用了具有上述问题的基本C#随机数代码。解决方案是使用更安全的随机数。 This question提供了一些关于更好的随机数生成器的想法。

我在几个性能测试中使用了基于以下代码:

public static class RandomNumber
{
    private static Random rand = new Random(DateTime.Now.Millisecond);
    private static object randLock = new object();

    /// <summary>
    /// Generate a random number.
    /// </summary>
    /// <param name="maxPlus1">1 more than the maximum value wanted.</param>
    /// <returns>Value between 0 and maxPlus1-1 inclusive. Ie 0 .le. returned value .lt. maxPlus1</returns>
    public static int Next(int maxPlus1)
    {
        int result;

        lock (randLock)
        {
            result = rand.Next(maxPlus1);
        }

        return result;
    }
}

将字符串创建方法添加到上面的代码应该很简单,这是在lock{ ... }语句中生成所需字符串的东西。

问题的一部分说明“在每次运行时重写RandomName上下文参数。所以当我的请求实际运行时,它们使用相同的随机名称”是误解了发生了什么。每个VU都有自己的一组CP,只是随机数是相同的。

© www.soinside.com 2019 - 2024. All rights reserved.