我們想要達到的目的是模擬600個客戶端的消息提醒功能,當然我們沒有600個電腦可以拿來測試,我們只有4-5台電腦可以用來測試,那我們就想辦法在一個電腦上執行100來個客戶端,用不通的帳戶登錄,模擬600個並發時的情況.
現在遇到的問題:
1:一個個登錄,每個電腦上登錄100來個用戶是很繁瑣的事情,人都會眼花缭亂。
2:在測試過程中往往會發現一些問題,這時候又需要重新部署服務器端,又要部署客戶端,那是很要命的事情。
3:隨時想測試程序性能的時候,不需要別人的協助,只要自己一個人是否可以順利進行測試,又輕松又快的方式是否可以?總不能要求別人總加班,靠自己。
解決問題的思路:
1:先把數據庫裡的用戶名密碼,都修改為有規律的密碼,由於我們用的是測試數據庫,所以密碼是可以隨便修改的,我們編寫一段程序讓系統中所有的用戶的密碼與用戶名相同,由於密碼在數據庫裡是加密的,所以需要用程序腳本來設置。
2:在設置密碼的同時,我們把自動運行的DOS腳本指令也獲取了,那不是一箭雙雕了不是,那我們就編寫一段程序來實現一下這2個任務。
//--------------------------------------------------------------------
// All Rights Reserved , Copyright (C) 2011 , Hairihan TECH, Ltd.
//--------------------------------------------------------------------
using System.Data;
using System.IO;
using System.Text;
namespace DotNet.Example
{
using DotNet.DbUtilities;
using DotNet.Manager;
using DotNet.Model;
using DotNet.Utilities;
public class UserPassword
{
public void SetPassword()
{
// 檢查密碼強度,默認要檢查比較好,系統安全性高一些
BaseSystemInfo.CheckPasswordStrength = true;
// 打開數據庫
// IDbHelper dbHelper = new OracleHelper("Data Source=KANGFU;user=usercenter;password=usercenter;");
IDbHelper dbHelper = new SqlHelper("Data Source=localhost;Initial Catalog=UserCenterV36;User Id = sa ; Password = Password@sa;");
dbHelper.Open();
// 批處理指令
StringBuilder Batch = new StringBuilder();
// 獲取用戶列表,有效的,沒有被刪除的
BaseUserManager userManager = new BaseUserManager(dbHelper);
DataTable dt = userManager.GetDT(BaseUserTable.FieldDeletionStateCode, "0", BaseUserTable.FieldEnabled, "1");
BaseUserEntity userEntity = null;
foreach (DataRow dataRow in dt.Rows)
{
userEntity = new BaseUserEntity(dataRow);
// 設置密碼
userManager.SetPassword(userEntity.Id.ToString(), userEntity.UserName.ToString());
Batch.AppendLine(string.Format("start D:\\DotNet.Common\\DotNet.CommonV3.6\\DotNet.WinForm\\bin\\Debug\\DotNet.WinForm.exe UserName={0} Password={1}", userEntity.UserName.ToString(), userEntity.UserName.ToString()));
}
dbHelper.Close();
// 將批處理寫入文件
WriterFile(Batch.ToString());
}
/// <summary>
/// 將批處理寫入文件
/// </summary>
/// <param name="batch">指令</param>
private void WriterFile(string batch)
{
// 把批處理結果保存到文件
string writerFileName = "D:\\DotNet.Common\\DotNet.CommonV3.6\\DotNet.WinForm\\bin\\Debug\\RunTest.bat";
StreamWriter streamWriter = new StreamWriter(writerFileName, false, Encoding.Default);
streamWriter.Write(batch);
streamWriter.Close();
}
}
}
得到的DOS批量處理的結果如下RunTest.bat,為了節省篇幅就截取一部份:
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=Administrator Password=Administrator
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=SystemAdmin Password=SystemAdmin
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=UserAdmin Password=UserAdmin
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=jiangyanxiao Password=jiangyanxiao
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=hukuangming Password=hukuangming
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=caoyaping Password=caoyaping
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=gaoyufen Password=gaoyufen
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=xuqianping Password=xuqianping
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=jianglisha Password=jianglisha
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=zhuqingqing Password=zhuqingqing
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=luyizhou Password=luyizhou
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=qianleilei Password=qianleilei
start D:\DotNet.Common\DotNet.CommonV3.6\DotNet.WinForm\bin\Debug\DotNet.WinForm.exe UserName=lijia Password=lijia
3:調試winform程序,讓程序能接受命令行參數,參考代碼如下:
/// <summary>
/// 應用程序的主入口點。
/// </summary>
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// System.Console.WriteLine(WindowsIdentity.GetCurrent().Name);
// 主應用程序集名
BaseSystemInfo.MainAssembly = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;
BaseSystemInfo.StartupPath = Application.StartupPath;
BaseSystemInfo.AppIco = Path.Combine(Application.StartupPath, "Resource/Form.ico");
// 獲取配置信息
GetConfig();
// 這裡檢查是否有外部用戶名密碼傳輸進來過
if (args.Length > 0)
{
for (int i = 0; i < args.Length; i++)
{
if (args[i].ToString().StartsWith("UserName"))
{
BaseSystemInfo.CurrentUserName = args[i].ToString().Substring("UserName".Length + 1);
}
else if (args[i].ToString().StartsWith("Password"))
{
BaseSystemInfo.CurrentPassword = args[i].ToString().Substring("Password".Length + 1);
if (BaseSystemInfo.ClientEncryptPassword)
{
BaseSystemInfo.CurrentPassword = SecretUtil.Encrypt(BaseSystemInfo.CurrentPassword);
}
}
// Console.WriteLine(i.ToString() + ":" + args[i].ToString());
}
}
if (BaseSystemInfo.MultiLanguage)
{
// 多語言國際化加載
ResourceManagerWrapper.Instance.LoadResources(Path.Combine(Application.StartupPath, "Resource/Localization/"));
// 從當前指定的語言包讀取信息
AppMessage.GetLanguageResource();
}
// 初始化服務
DotNetService.Instance.InitService();
// 按配置的登錄頁面進行登錄,這裡需要運行的是主程序才可以
Form mainForm = BaseInterfaceLogic.GetForm(BaseSystemInfo.MainAssembly, BaseSystemInfo.MainForm);
Application.Run(mainForm);
}
4:配置項目工程屬性,模擬輸入命令行參數如下圖:
5:把程序配置為能自動登錄的狀態如下效果圖:
也可以通過手工修改配置文件的方式把 Config.xml 裡的
<!-- 是否自動登錄,默認不自動登錄會好一些 -->
<add key="AutoLogOn"value="True" /> 也可以達到相同的效果.
6:萬事大吉,只要雙擊 RunTest.bat,瞬間幾百個客戶端就自動登錄,能模擬多用戶並發壓力測試了,將來做其它項目還可以反復使用,不用依靠別人自己一個人就可以測試了,省心省事了。
開發軟件很多功能都很簡單,但是一個每個功能實現好都需要幾個小時時間,例如這個自動登錄進行壓力測試的程序也編寫調試了4個小時左右, 一個軟件系統往往需要成白上千的功能點,前後編寫花費的時間就會很長了,需要投入很密集的勞動力.
例如我想購買一個軟件,軟件只有一個要求"姓李的周三不能登錄,姓白的周日不能登錄",就這麼一個軟件,你需要多久能開發好? 其實他沒說這個軟件背後的100個需求,當你開發好了後,客戶會說,怎麼沒有權限管理功能? 怎麼沒有角色管理功能? 怎麼沒設置密碼功能? 怎麼沒鎖定帳戶功能??????????
就像是我想購買一個進銷存,需要分級管理分級授權,你要開價多少? 其實他想要用友軟件的所有功能,同時也想要金蝶的所有的優點之上要結合他們自己在用的系統優點,再加一個分級管理分級授權的功能,所以我們做任何軟件系統,都需要把那些公用的,基礎的1000個功能點都做好了,再去開發第1001個功能,才好滿足客戶的需要。
將權限管理、工作流管理做到我能力的極致,一個人只能做好那麼很少的幾件事情
作者:吉日嘎拉