一起谈.NET技术,VS2010 测试功能之旅:编码的UI测试(4)-通过编写测试代码的方式建立UI测试(下)

简介:   回顾  最近比较忙,距离上次更新的时间较久,见谅。  在本章上部分,介绍了“添加用户”窗口的测试代码编写。想必大家也看到了,在UIMap.cs文件中实现自定义编码是一件很轻松的事情,接下来将介绍下个部分,查询用户窗体的测试代码的编写,以及他们测试的关联。

  回顾

  最近比较忙,距离上次更新的时间较久,见谅。

  在本章上部分,介绍了“添加用户”窗口的测试代码编写。想必大家也看到了,在UIMap.cs文件中实现自定义编码是一件很轻松的事情,接下来将介绍下个部分,查询用户窗体的测试代码的编写,以及他们测试的关联。

  示例程序介绍

  系统主窗口:(下载点我

  该系统拥有两个功能,“添加用户”和“查询用户”:

  点击添加用户后,进入添加用户子窗体:(“添加用户”窗口的测试代码编写在上部分已经实现

  如果在之前的主窗口,点击查询用户,则进入查询用户子窗体:

  注:系统默认自带了5个用户TestUser1, TestUser2, TestUser3, TestUser4, TestUser5。

  这个窗体不会弹任何提示框,默认进入窗体时,DataGridView里面没有加载数据,现在进行一个说明:

  查询条件-用户名:表示是否按用户名查询(非模糊查询),如果不输入,默认为不按其查询。

  查询条件-用户类型:有三个选项“所有”,“管理员”,“一般用户”。

  查询条件-日期:表示是否按日期查询,如果勾上了日期CheckBox,则旁边的DateTimePicker会启用,然后选择一个具体的日期。

  按钮-查询:就会按以上条件查询。

  按钮-重置:用户名清空,用户类型变成所有,日期取消勾选。

  文本框-用户备注:当查询出数据以后,每选择DataGridView里面中的一行数据,用户备注TextBox会自动加载当前行的用户备注。

  如何设计测试

  现在需要明确的就是,我们既需要检查“查询用户”窗口的基本功能,又需要确定之前在“添加用户”窗口添加的用户是否被添加了进来,所以这里的检查尤其重要,根据刚才的功能描述,现在需要编写测试设计。(在看下面的设计之前大家可以先试着自己设计下) 。

  自动化测试,关键不在技术,而是在测试设计上,所以这里需要设计得比较全面:

步骤序号

操作步骤

检查点

1

在主窗口菜单点击用户查询

检测查询用户子窗口是否弹出

2

用户名为空,用户类型为“所有”,不勾选时间,点击查询,记录查询出的用户行数,程序默认选中第一行,这时我们选中第二行

检测“用户备注”一列的值是否和下方的“用户备注”文本框的值一致

3

加的用户,其他条件不变,点击查询(例如,在上个部分的示例中,我们使用的是”TestUser6”)

查询出用户名为TestUser6的一条数据

4

用户名为一个不存在的用户“testuser100”,其他条件不变,点击查询

未查询出数据

5

将用户名设置为空,其他条件不变,用户类型为“管理员”,记录查询出的行数

查询出所有为“管理员”的用户(注,为了方便,这里没有使用从数据库比对,而只使用查询条件与查询出的数据比对,实际项目中可能使用数据库比对)

6

将用户类型设置为“一般用户”,其他条件不变,记录查询出的行数

查询出所有为“一般用户”的用户

7

使用刚才用户类型分别为“所有”,“管理员”,“一般用户”查询出的数据行数,进行比对

一般用户行数+管理员用户行数=所有用户行数

8

用户名为空,用户类型为“所有”,勾选时间,并进行选择“2008-1-11”

查询出所有添加时间为“2008-1-11”的用户

9

将条件设置为刚才我们在添加用户窗口添加的用户信息(使用我们在上一个示例中使用的值,如”TestUser6”,”一般用户”,时间为添加时间,时间这个需要用到某个变量来记录)

查询出对应的一条数据

10

点击重置按钮

用户名为空,用户类型为“所有”,不勾选时间

11

点击退出

退出窗口

  接下来将以上的检查点转换为代码。

  对测试进行编码

  我们可以接着上次录制的代码来编写,因为在上个部分对于某些编写方式(例如先捕获对象再编写和先录制再转移修改的方式)已经描述得很详细了,下面默认使用这些方式,因此就不一一阐述对象的捕捉过程了。这里只介绍上个部分没有介绍的注意点和和给出主要代码。

  由于是接着上个部分的代码写,这里需要注释掉AddUserUIMap.cs中Step7_CloseWindows的两句代码,以免他在测试结束后将主窗口关闭掉:

 
 
public void Step7_CloseWindows()
{
// 操作步骤
bool isClosed;
Mouse.Click(
this .UI添加用户Window.UI取消Window.UI取消Button, new Point( 1 , 1 ));
// 和WaitForControlExist相反,这里是最长等待他3秒关闭,如果3秒内关闭返回true,否则为false
isClosed = this .UI添加用户Window.WaitForControlNotExist( 3000 );
// 这里添上了注释,以免将主窗口关闭掉
// Mouse.Click(this.UI系统主窗口Window.UI系统主窗口TitleBar.UICloseButton, new Point(1, 1));
// isClosed &= this.UI系统主窗口Window.WaitForControlNotExist(3000);

// 检查点
Assert.IsTrue(isClosed, " 点击退出,检测是否退出添加用户子窗体和主窗体失败 " );
}

  接下来,我们通过在项目中添加新项的方式新建一个SearchUserUIMap.uitest,在这个UIMap的.cs中来编写我们对于“查询用户”这个窗口的操作。

  实现步骤1

步骤序号

操作步骤

检查点

1

在主窗口菜单点击用户查询

检测查询用户子窗口是否弹出

  相信这个很简单,两下就可以通过录制然后修改的方式编写出来:

 
 
public void Step1_ClickSearchUser()
{
WinMenuItem uI查询用户MenuItem
= this .UI系统主窗口Window.UIMenuStrip1MenuBar.UI用户管理MenuItem.UI查询用户MenuItem;
// 操作步骤:Click '用户管理' -> '查询用户' menu item
Mouse.Click(uI查询用户MenuItem, new Point( 1 , 1 ));

// 检查点:检查查询用户子窗口是否弹出
Assert.IsTrue( this .UI查询用户Window.WaitForControlExist( 6000 ), " 点击查询用户,检测查询用户子窗口弹出失败 " );
}

  实现步骤2

步骤序号

操作步骤

检查点

2

用户名为空,用户类型为“所有”,不勾选时间,点击查询,记录查询出的用户行数,程序默认选中第一行,这时我们选中第二行

检测“用户备注”一列的值是否和下方的“用户备注”文本框的值一致

  这一步需要注意的就是,首先这里有一个选行的操作,然后需要从表里单元格当中取值,最后与文本框的值进行比对,这里之所以需要记录这个RowCount,是因为在步骤7的时候会用于比对,这里需要用准星首先捕获到这个GridViewTable,然后将其添加到对象库:

  然后才开始录制并编写代码,如下:

 
 
public int AllUser; // 注意,这里留一个字段来保存行数

public void Step2_SearchWithOutCondition()
{
WinButton uI查询Button
= this .UI查询用户Window.UI查询Window.UI查询Button;
// 操作步骤
Mouse.Click(uI查询Button, new Point( 1 , 1 )); // Click '查询' button
System.Threading.Thread.Sleep( 3000 ); // 等待3秒,应付可能出现的查询延时
AllUser = this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows.Count; // 获取行数
WinRow row2 = this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows[ 1 ] as WinRow;
Mouse.Click(row2.Cells[
0 ], new Point( 10 , 10 )); // 点击第二行第一个单元格,用以将第二行其选中
System.Threading.Thread.Sleep( 1000 ); // 等待1秒,应付可能出现的查询延时

// 检查点:检测“用户备注”一列的值是否和下方的“用户备注”文本框的值一致
Assert.AreEqual( this .UI 查询用户Window.UITbx_MemoWindow.UITbx_MemoEdit.Text, ((WinCell)row2.Cells[ 4 ]).Value, " 检测“用户备注”一列的值是否和下方的“用户备注”文本框的值一致失败 " );
}

  实现步骤3

步骤序号

操作步骤

检查点

3

用户名为刚才我们在添加用户窗口添加的用户,其他条件不变,点击查询(例如,在上个部分的示例中,我们使用的是”TestUser6”)

查询出用户名为TestUser6的一条数据

  步骤3和步骤4是对用户名这个维度来进行测试,需要和上一个模块对接,因为在上一个模块添加了一个用户,所以这里需要检查是否能够查询出来,需要确定的就是RowCount=1并且第一行第一列数据为”TestUser6”才算正确,代码如下:

 
   
public void Step3_SearchWithUidOnly()
{
string NewUser = " TestUser6 " ;
WinEdit uITbx_UserNameEdit
= this .UI查询用户Window.UITbx_UserNameWindow.UITbx_UserNameEdit;
WinButton uI查询Button
= this .UI查询用户Window.UI查询Window.UI查询Button;
// 操作步骤
uITbx_UserNameEdit.Text = NewUser;
Mouse.Click(uI查询Button,
new Point( 1 , 1 )); // Click '查询' button
System.Threading.Thread.Sleep( 3000 ); // 等待3秒,应付可能出现的查询延时

// 检查点:查询出用户名为TestUser6的一条数据
bool isValid = 1 == this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows.Count;
WinCell cell
= ((WinRow)UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows[ 0 ]).Cells[ 1 ] as WinCell;
isValid
&= cell.Value == NewUser;
Assert.IsTrue(isValid,
" 查询出用户名为 " + NewUser + " 的一条数据失败 " );
}

  实现步骤4

步骤序号

操作步骤

检查点

4

用户名为一个不存在的用户“testuser100”,其他条件不变,点击查询

未查询出数据

  这是一个反例的测试,很明显只要RowCount为0就可以通过测试:

 
 
public void Step4_SearchWithUidNotExist()
{
string ErrorUser = " TestUser1000 " ;
WinEdit uITbx_UserNameEdit
= this .UI查询用户Window.UITbx_UserNameWindow.UITbx_UserNameEdit;
WinButton uI查询Button
= this .UI查询用户Window.UI查询Window.UI查询Button;
// 操作步骤
uITbx_UserNameEdit.Text = ErrorUser;
Mouse.Click(uI查询Button,
new Point( 1 , 1 )); // Click '查询' button
System.Threading.Thread.Sleep( 3000 ); // 等待3秒,应付可能出现的查询延时

// 检查点:未查询出数据
Assert.IsTrue( 0 == this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows.Count, " 未查询出数据失败 " );
}

  实现步骤5

步骤序号

操作步骤

检查点

5

将用户名设置为空,其他条件不变,用户类型为“管理员”,记录查询出的行数

查询出所有为“管理员”的用户(注,为了方便,这里没有使用从数据库比对,而只使用查询条件与查询出的数据比对,实际项目中可能使用数据库比对)

  步骤5,6,7是对用户类型这个维度来进行测试,在步骤5中,我们需要遍历每一行中的“用户类型”列,判断他是不是等于“管理员”,并记录一共查询出多少条数据:

 
 
public int AdminUser; // 注意,这里留一个字段来保存管理员用户的行数

public void Step5_SearchWithAdminOnly()
{
string UserType = " 管理员 " ;
WinEdit uITbx_UserNameEdit
= this .UI查询用户Window.UITbx_UserNameWindow.UITbx_UserNameEdit;
WinComboBox uI用户类型ComboBox
= this .UI查询用户Window.UICbx_UserTypeWindow.UI用户类型ComboBox;
WinButton uI查询Button
= this .UI查询用户Window.UI查询Window.UI查询Button;
// 操作步骤
uITbx_UserNameEdit.Text = "" ;
uI用户类型ComboBox.SelectedItem
= UserType;
Mouse.Click(uI查询Button,
new Point( 1 , 1 )); // Click '查询' button
System.Threading.Thread.Sleep( 3000 ); // 等待3秒,应付可能出现的查询延时
AdminUser = this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows.Count; // 获取行数

// 检查点:查询出所有为“管理员”的用户
bool isValid = true ;
foreach (WinRow winrow in this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows)
{
isValid
&= ((winrow.Cells[ 2 ] as WinCell).Value == UserType);
}
Assert.IsTrue(isValid,
" 查询出所有为“管理员”的用户失败 " );
}

  实现步骤6

步骤序号

操作步骤

检查点

6

将用户类型设置为“一般用户”,其他条件不变,记录查询出的行数

查询出所有为“一般用户”的用户

  和步骤5是一样的,需要遍历每一行中的“用户类型”列,判断他是不是等于“一般用户”,并记录一共查询出多少条数据:

 
 
public int NormalUser; // 注意,这里留一个字段来保存一般用户的行数

public void Step6_SearchWithNormalUserOnly()
{
string UserType = " 一般用户 " ;
WinEdit uITbx_UserNameEdit
= this .UI查询用户Window.UITbx_UserNameWindow.UITbx_UserNameEdit;
WinComboBox uI用户类型ComboBox
= this .UI查询用户Window.UICbx_UserTypeWindow.UI用户类型ComboBox;
WinButton uI查询Button
= this .UI查询用户Window.UI查询Window.UI查询Button;
// 操作步骤
uITbx_UserNameEdit.Text = "" ;
uI用户类型ComboBox.SelectedItem
= UserType;
Mouse.Click(uI查询Button,
new Point( 1 , 1 )); // Click '查询' button
System.Threading.Thread.Sleep( 3000 ); // 等待3秒,应付可能出现的查询延时
NormalUser = this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows.Count; // 获取行数

// 检查点:查询出所有为“一般用户”的用户
bool isValid = true ;
foreach (WinRow winrow in this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows)
{
isValid
&= ((winrow.Cells[ 2 ] as WinCell).Value == UserType);
}
Assert.IsTrue(isValid,
" 查询出所有为“一般用户”的用户失败 " );
}

  实现步骤7

步骤序号

操作步骤

检查点

7

使用刚才用户类型分别为“所有”,“管理员”,“一般用户”查询出的数据行数,进行比对

一般用户行数+管理员用户行数=所有用户行数

  现在应该了解之所以需要记录下不同用户类型记录数的原因了吧?代码如下:

 
 
public void Step7_ValidUserCount()
{
Assert.AreEqual(AdminUser
+ NormalUser, AllUser, " 检查'一般用户行数+管理员用户行数=所有用户行数'失败 " );
}

  实现步骤8

步骤序号

操作步骤

检查点

8

用户名为空,用户类型为“所有”,勾选时间,并进行选择“2008-1-11”

查询出所有添加时间为“2008-1-11”的用户

  步骤8是对时间维度进行一个测试,现在如果我们选择了2008-1-11,那么只需要遍历查询出的各行的“时间”一列是不是为2008-1-11:

 
 
public void Step8_SearchWithDateOnly()
{
string DateTimeAsString = " 2008-1-11 " ;
WinEdit uITbx_UserNameEdit
= this .UI查询用户Window.UITbx_UserNameWindow.UITbx_UserNameEdit;
WinComboBox uI用户类型ComboBox
= this .UI查询用户Window.UICbx_UserTypeWindow.UI用户类型ComboBox;
WinCheckBox uI日期CheckBox
= this .UI查询用户Window.UI日期Window.UI日期CheckBox;
WinDateTimePicker uIDtp_AddTimeDateTimePicker
= this .UI 查询用户Window.UIDtp_AddTimeWindow.UIDtp_AddTimeDateTimePicker;
WinButton uI查询Button
= this .UI查询用户Window.UI查询Window.UI查询Button;

// 操作步骤
uITbx_UserNameEdit.Text = "" ;
uI用户类型ComboBox.SelectedItem
= " 所有 " ;
uI日期CheckBox.Checked
= true ;
uIDtp_AddTimeDateTimePicker.DateTimeAsString
= DateTimeAsString;
Mouse.Click(uI查询Button,
new Point( 1 , 1 )); // Click '查询' button
System.Threading.Thread.Sleep( 3000 ); // 等待3秒,应付可能出现的查询延时

// 检查点:查询出所有为“2008-1-11”的用户
bool isValid = true ;
foreach (WinRow winrow in this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows)
{
string [] DateNumbers = DateTimeAsString.Split( ' - ' );
DateTime dt
= Convert.ToDateTime((winrow.Cells[ 3 ] as WinCell).Value);
isValid
&= Convert.ToInt32(DateNumbers[ 0 ]) == dt.Year;
isValid
&= Convert.ToInt32(DateNumbers[ 1 ]) == dt.Month;
isValid
&= Convert.ToInt32(DateNumbers[ 2 ]) == dt.Day;
}
Assert.IsTrue(isValid,
" 查询出所有为“2008-1-11”的用户失败 " );
}

  实现步骤9

步骤序号

操作步骤

检查点

9

将条件设置为刚才我们在添加用户窗口添加的用户信息(使用我们在上一个示例中使用的值,如”TestUser6”,”一般用户”,时间为添加时间,时间这个需要用到某个变量来记录)

查询出对应的一条数据

  步骤9是进行一次复合条件查询的测试,这次测试就用到之前我们在添加用户的时候的数据,需要注意的是,因为添加时间是不确定的,所以我们需要修改之前录制的代码,将他的值赋给一个变量,需要修改的AddUserUiMap.cs中的方法Step6_AddUserSuccess,让其有一个返回值返回当前时间,代码如下:

 
 
public DateTime Step6_AddUserSuccess()
{
// 操作步骤
this .UI添加用户Window.UITbx_UserNameWindow.UITbx_UserNameEdit.Text = " TestUser6 " ;
this .UI添加用户Window.UICbx_UserTypeWindow.UI用户类别ComboBox.SelectedItem = " 一般用户 " ;
this .UI添加用户Window.UITbx_MemoWindow.UITbx_MemoEdit.Text = " Test " ;
Mouse.Click(
this .UI添加用户Window.UI添加Window.UI添加Button, new Point( 1 , 1 ));

// 检查点:首先检查3秒内是否有弹出框弹出,如果有,则检查文本是否是"添加成功!"
this .mUI弹出框Window = new UI弹出框Window();
bool isPopUp = this .UI弹出框Window.UI弹出框Text.WaitForControlExist( 3000 );
Assert.IsTrue(isPopUp
&& this .UI弹出框Window.UI弹出框Text.DisplayText == " 添加成功! " , " 输入正确,检测弹出“添加成功!”失败 " );
Mouse.Click(
this .UIOKWindow.UIOKButton, new Point( 1 , 1 ));
// 这里是新添加的代码
return DateTime.Now;
}

  然后现在在这里引用之前的变量,来进行操作,代码如下:

 
 
public void Step9_SearchWithAllCondition(DateTime addTime)
{
string UserName = " TestUser6 " ;
string UserType = " 一般用户 " ;
string AddTime = addTime.Year + " - " + addTime.Month + " - " + addTime.Day;

WinEdit uITbx_UserNameEdit
= this .UI查询用户Window.UITbx_UserNameWindow.UITbx_UserNameEdit;
WinComboBox uI用户类型ComboBox
= this .UI查询用户Window.UICbx_UserTypeWindow.UI用户类型ComboBox;
WinCheckBox uI日期CheckBox
= this .UI查询用户Window.UI日期Window.UI日期CheckBox;
WinDateTimePicker uIDtp_AddTimeDateTimePicker
= this .UI 查询用户Window.UIDtp_AddTimeWindow.UIDtp_AddTimeDateTimePicker;
WinButton uI查询Button
= this .UI查询用户Window.UI查询Window.UI查询Button;

// 操作步骤
uITbx_UserNameEdit.Text = UserName;
uI用户类型ComboBox.SelectedItem
= UserType;
uI日期CheckBox.Checked
= true ;
uIDtp_AddTimeDateTimePicker.DateTimeAsString
= AddTime;
Mouse.Click(uI查询Button,
new Point( 1 , 1 )); // Click '查询' button
System.Threading.Thread.Sleep( 3000 ); // 等待3秒,应付可能出现的查询延时

// 检查点:查询出用户名为TestUser6的一条数据
bool isValid = 1 == this .UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows.Count;
WinCell cell
= ((WinRow)UI查询用户Window.UIUserGridViewWindow.UIDataGridViewTable.Rows[ 0 ]).Cells[ 1 ] as WinCell;
isValid
&= cell.Value == UserName;
Assert.IsTrue(isValid,
" 查询出用户名为 " + UserName + " 的一条数据失败 " );
}

  实现步骤10

步骤序号

操作步骤

检查点

10

点击重置按钮

用户名为空,用户类型为“所有”,不勾选时间

  这一步很简单,几乎没什么说的,只是需要注意的是最好加个等待时间,代码如下:

 
 
public void Step10_ClickReset()
{
WinEdit uITbx_UserNameEdit
= this .UI查询用户Window.UITbx_UserNameWindow.UITbx_UserNameEdit;
WinComboBox uI用户类型ComboBox
= this .UI查询用户Window.UICbx_UserTypeWindow.UI用户类型ComboBox;
WinCheckBox uI日期CheckBox
= this .UI查询用户Window.UI日期Window.UI日期CheckBox;
WinButton uI重置Button
= this .UI查询用户Window.UI重置Window.UI重置Button;

// 操作步骤
Mouse.Click(uI重置Button, new Point( 25 , 14 ));
System.Threading.Thread.Sleep(
1000 ); // 等待1秒,应付可能出现的查询延时

// 检查点:用户名为空,用户类型为“所有”,不勾选时间
bool isValid = true ;
isValid
&= string .IsNullOrEmpty(uITbx_UserNameEdit.Text);
isValid
&= uI用户类型ComboBox.SelectedItem == " 所有 " ;
isValid
&= ! uI日期CheckBox.Checked;
Assert.IsTrue(isValid,
" 重置失败 " );

}

  实现步骤11

步骤序号

操作步骤

检查点

11

点击退出

退出窗口

  这一步也很简单,和上个部分提到的一样,代码如下:

 
 
public void Step11_CloseWindow()
{
Mouse.Click(
this .UI查询用户Window.UI查询用户TitleBar.UICloseButton, new Point( 1 , 1 ));
Mouse.Click(
this .UI系统主窗口Window.UI系统主窗口TitleBar.UICloseButton, new Point( 1 , 1 ));
Assert.IsTrue(
this .UI系统主窗口Window.WaitForControlNotExist( 3000 ), " 退出失败 " );
}

  总结

  在本章,介绍了通过编码的方式来建立UI测试,,相信大家在看完了以后,应该能够完全自己用VS2010提供的UI测试进行实际项目测试了。如果需要调用刚才所写的方法,只需要再新建一个编码的UI测试,例如将其命名为CodedUITest1.cs,然后在内部添加一个这样的调用即可:

 
 
[TestMethod]
public void CodedUITestMethod1()
{
DateTime addTime;

AddUserUIMapClasses.AddUserUIMap addUserUIMap
= new AddUserUIMapClasses.AddUserUIMap();
addUserUIMap.Step1_LoginSystem();
addUserUIMap.Step2_ClickAddUser();
addUserUIMap.Step3_AddUserWithNoName();
addUserUIMap.Step4_AddUserWithOverlapName();
addUserUIMap.Step5_AddUserWithNoMemo();
addTime
= addUserUIMap.Step6_AddUserSuccess(); // 这里要特别注意,有一个返回值
addUserUIMap.Step7_CloseWindows();

SearchUserUIMapClasses.SearchUserUIMap searchUserUIMap
= new SearchUserUIMapClasses.SearchUserUIMap();
searchUserUIMap.Step1_ClickSearchUser();
searchUserUIMap.Step2_SearchWithOutCondition();
searchUserUIMap.Step3_SearchWithUidOnly();
searchUserUIMap.Step4_SearchWithUidNotExist();
searchUserUIMap.Step5_SearchWithAdminOnly();
searchUserUIMap.Step6_SearchWithNormalUserOnly();
searchUserUIMap.Step7_ValidUserCount();
searchUserUIMap.Step8_SearchWithDateOnly();
searchUserUIMap.Step9_SearchWithAllCondition(addTime);
// 这里要特别注意,有一个参数
searchUserUIMap.Step10_ClickReset();
searchUserUIMap.Step11_CloseWindow();
}

  示例程序的下载:下载点我

  个人录制的源代码下载:下载点我

  在下一章,将会介绍如何建立数据驱动的测试,敬请关注。

目录
相关文章
|
12天前
|
人工智能 开发框架 量子技术
【专栏】.NET 技术:驱动创新的力量
【4月更文挑战第29天】.NET技术,作为微软的开发框架,以其跨平台、开源和语言多样性驱动软件创新。它在云计算、AI/ML、混合现实等领域发挥关键作用,通过Azure、ML.NET等工具促进新兴技术发展。未来,.NET将涉足量子计算、微服务和无服务器计算,持续拓宽软件开发边界,成为创新的重要推动力。掌握.NET技术,对于开发者而言,意味着握有开启创新的钥匙。
|
12天前
|
开发框架 .NET C#
【专栏】理解.NET 技术,提升开发水平
【4月更文挑战第29天】本文介绍了.NET技术的核心概念和应用,包括其跨平台能力、性能优化、现代编程语言支持及Web开发等特性。文章强调了深入学习.NET技术、关注社区动态、实践经验及学习现代编程理念对提升开发水平的重要性。通过这些,开发者能更好地利用.NET构建高效、可维护的多平台应用。
|
12天前
|
机器学习/深度学习 vr&ar 开发者
【专栏】.NET 技术:引领开发新方向
【4月更文挑战第29天】本文探讨了.NET技术如何引领软件开发新方向,主要体现在三方面:1) 作为跨平台开发的先锋,.NET Core支持多操作系统和移动设备,借助.NET MAUI创建统一UI,适应物联网需求;2) 提升性能和开发者生产力,采用先进技术和优化策略,同时更新C#语言特性,提高代码效率和可维护性;3) 支持现代化应用架构,包括微服务、容器化,集成Kubernetes和ASP.NET Core,保障安全性。此外,.NET还不断探索AI、ML和AR/VR技术,为软件开发带来更多创新可能。
|
12天前
|
开发框架 Cloud Native 开发者
【专栏】剖析.NET 技术的核心竞争力
【4月更文挑战第29天】本文探讨了.NET框架在软件开发中的核心竞争力:1) .NET Core实现跨平台与云原生技术的融合,支持多操作系统和容器化;2) 提升性能和开发者生产力,采用JIT、AOT优化,提供C#新特性和Roslyn编译器平台;3) 支持现代化应用架构,包括微服务和容器化,内置安全机制;4) 丰富的生态系统和社区支持,拥有庞大的开发者社区和微软的持续投入。这些优势使.NET在竞争激烈的市场中保持领先地位。
|
12天前
|
开发框架 .NET 开发者
【专栏】领略.NET 技术的创新力量
【4月更文挑战第29天】.NET技术自ASP.NET起历经创新,现以.NET Core为核心,展现跨平台能力,提升性能与生产力,支持现代化应用架构。.NET Core使开发者能用同一代码库在不同操作系统上构建应用,扩展至移动和物联网领域。性能提升,C#新特性简化编程,Roslyn编译器优化代码。拥抱微服务、容器化,内置安全机制,支持OAuth等标准。未来.NET 6将引入更快性能、Hot Reload等功能,预示着.NET将持续引领软件开发潮流,为开发者创造更多机会。
|
12天前
|
物联网 vr&ar 开发者
【专栏】.NET 技术:为开发注入活力
【4月更文挑战第29天】本文探讨了.NET技术的创新,主要体现在三个方面:1) .NET Core实现跨平台开发革命,支持多种操作系统和硬件,如.NET MAUI用于多平台UI;2) 性能提升与生产力飞跃,C#新特性简化编程,JIT和AOT优化提升性能,Roslyn提供代码分析工具;3) 引领现代化应用架构,支持微服务、容器化,内置安全机制。未来,.NET 7将带来更多新特性和前沿技术整合,如量子计算、AI,持续推动软件开发创新。开发者掌握.NET技术将赢得竞争优势。
|
12天前
|
人工智能 前端开发 Cloud Native
【专栏】洞察.NET 技术的开发趋势
【4月更文挑战第29天】本文探讨了.NET技术的三大发展趋势:1) 跨平台与云原生技术融合,通过.NET Core支持轻量级、高性能应用,适应云计算和微服务;2) 人工智能与机器学习的集成,如ML.NET框架,使开发者能用C#构建AI模型;3) 引入现代化前端开发技术,如Blazor,实现前后端一致性。随着.NET 8等新版本的发布,期待更多创新技术如量子计算、AR/VR的融合,.NET将持续推动软件开发的创新与进步。
|
12天前
|
人工智能 前端开发 Devops
【专栏】洞察.NET 技术在现代开发中的作用
【4月更文挑战第29天】本文探讨了.NET技术在现代软件开发中的核心价值、应用及挑战。.NET提供语言统一性与多样性,强大的Visual Studio工具,丰富的类库,跨平台能力及活跃的开发者社区。实际应用包括企业级应用、Web、移动、云服务和游戏开发。未来面临性能优化、容器化、AI集成等挑战,需持续创新。开发者应深入理解.NET,把握技术趋势,参与社区,共创美好未来。
|
12天前
|
开发工具 C# 开发者
【专栏】理解.NET 技术,开创美好未来
【4月更文挑战第29天】本文探讨了.NET技术在软件开发中的关键作用,强调其核心优势,如语言多样性、丰富类库、强大的开发工具和跨平台能力。.NET在现代应用开发中涉及企业级应用、云服务集成、微服务、移动应用和游戏开发。未来,.NET将持续创新,提升性能,拓展应用场景,并促进更紧密的社区合作,通过跨平台框架扩大应用范围。开发者应深入学习.NET,抓住技术趋势,共创美好未来。
|
12天前
|
机器学习/深度学习 人工智能 开发者
【专栏】.NET 技术:为开发带来新机遇
【4月更文挑战第29天】本文探讨了.NET技术如何为软件开发带来新机遇,分为三个部分:首先,.NET的跨平台革命,包括.NET Core的兴起、Xamarin与.NET MAUI的移动应用开发、开源社区的推动及性能优化;其次,介绍了云服务与微服务架构的集成,如Azure云服务、微服务支持、DevOps与CI/CD,以及Docker容器化;最后,讨论了AI与机器学习集成,如ML.NET、认知服务、TensorFlow和ONNX,使开发者能构建智能应用。面对这些机遇,开发者应不断学习和适应新技术,以创造更多价值。

热门文章

最新文章