Visual Studio 2010 Ultimate Web性能测试和负载测试虚拟用户帐户

时间:2010-07-27 04:07:04

标签: visual-studio load-testing

我需要加载测试一个网站。它使用群组身份验证进行身份验证。

我创建了一个Visual Studio 2010测试项目并创建了一个Web性能测试,该测试使用我在录制测试时使用的用户名和密码登录。我附加了一个访问数据库,其中包含一个名为Users的表,我已将其绑定到登录表单,测试套件对users表中的每一行数据运行测试。

这一切都正如我所料。

现在我想运行最多250个并发用户的负载测试。如何告诉Visual Studio为负载测试中的每个虚拟用户使用不同的用户名和密码。

简而言之,我想在负载测试中为每个虚拟用户设置一个配置文件。

1 个答案:

答案 0 :(得分:4)

我会创建一个Web测试,一次只使用一个登录来登录。然后,您可以在webtest中创建一小段代码,以便从数据库中“随机”登录代码中的列表以选择登录。

如果您需要为每项测试提供唯一的登录信息,则必须估算需要登录的次数并预填充多次。

从数据库中选择的问题是虚拟用户共享线程,测试中的任何阻塞代码都会阻止多个虚拟用户。 可以在内存中创建一个包含所有登录详细信息的列表,但在高度多线程环境中管理共享对象需要小心。

对于我们来说,我们创建了一个存储过程,它将获取下一个登录密码和用户名,然后调用以下方法来获取下一次登录。

   public static bool GetNextLogin(out string userName, out string password)
    {
        bool result = false;

        using (SqlConnection connection = new SqlConnection(loadTestLoginsConnection))
        {
            using (SqlCommand command = new SqlCommand("GetNextID", connection))
            {
                connection.Open();
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        userName = reader["UserName"].ToString().Trim();
                        password = reader["Password"].ToString().Trim();
                        result = true;
                    }
                }
            }
        }

        return result;
    }

这对我们没有问题,返回的值可以添加到正确的表单post参数中。如果使用普通身份验证,则可以在负载测试构造函数中使用相同的代码来更改WebTest.UserName和WebTest.Password属性。

我们的存储过程处理可用登录列表和一个名为CurrentLoginID

的int字段的表
BEGIN TRANSACTION
        BEGIN TRY
            DECLARE @CurrentID AS INT
                UPDATE CurrentLoginID SET Number = Number+1
                SELECT @CurrentID = Number FROM CurrentLoginID
                SELECT [Password], UserName FROM AvailableLogins WHERE AvailableLogins.ID = @CurrentID
            COMMIT
            END TRY
        BEGIN CATCH
                DECLARE @ErrorMessage NVARCHAR(4000);
                DECLARE @ErrorSeverity INT;
                DECLARE @ErrorState INT;

                SELECT 
                    @ErrorMessage = ERROR_MESSAGE(),
                    @ErrorSeverity = ERROR_SEVERITY(),
                    @ErrorState = ERROR_STATE();

                -- Use RAISERROR inside the CATCH block to return error
                -- information about the original error that caused
                -- execution to jump to the CATCH block.
                RAISERROR (@ErrorMessage, -- Message text.
                           @ErrorSeverity, -- Severity.
                           @ErrorState -- State.
                           );
            ROLLBACK TRAN                 
        END CATCH