Fork me on GitHub
持续集成实践:使用Visual Studio 2010 Coded UI Test 制作能自动安装/卸载UI应用的程序

前言

Coded UI Test是Visual Studio 2010对于Testing Project(测试工程)提供的关于UI自动化测试的框架,支持Win32/Web/WPF等UI的自动化测试,在介绍它之前,先简单介绍一下持续集成。大家如果对持续集成不感兴趣的话,可以直接跳到第3节。

 

1:持续集成

持续集成由软件工程大师Martin Fowler提出,他对技术集成下的定义是:持续集成是一种软件开发实践,即团队开发成员经常集成它们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。

按照持续集成的思想,代码可以也应该能够在一天里可以多次通过“构建”,从而能在一天之内提供多个可供测试的版本。

这里面讲的构建不单单是代码的编译通过,它应该包含下面的步骤:

  • 所有最新代码从配置管理工具中取出.
  • 所有的代码从干净的状态开始编译。
  • 将编译结果链接并部署,以备执行。
  • 执行部署的应用并运行测试套件。

如果上述所有操作没有任何错误,没有人工干预,并通过了所有测试,才认为这是一次成功的构建。

对于第4步而言,如果应用程序是一个需要安装到桌面的UI应用,那么就需要保证它可以成功的部署,这样才能提供可以测试的环境。

 

2:我的持续集成实践

我公司使用敏捷开发,使用CruiseControl进行代码控制,当代码被Check In 后, 会自动编译,并生成一个压缩后的exe文件,然而而当需要测试该exe文件时,需要手工从文件服务器下载,然后手工卸载已有的程序,再运行该exe安装新的程序,确保安装后的程序/服务正确运行后,方能进行软件的测试。

也就是说,我们已经实现了前三步的自动化,而最后一步,由于涉及UI界面、服务卸载,一直没有能够自动化,这其中的一个难点就是该exe是一个较庞大且复杂的压缩程序,在安装时可以使用十分灵活多样的配置,每一样配置都会导致不同的安装结果,如果要把所有常用的安装方式自动化,编程的代价比较大。

在了解了Visual Studio 2010提供的Coded UI test功能后,以上问题初步得以解决,从而在技术层面,使用较小的C#代码就完成了UI界面安装、服务卸载等问题,从而将上述第四步与前面的三步串联起来,初步满足了持续集成的要求。

最后形成的大致步骤是

1:开发人员提交代码

2:编译服务器开始编译,并在文件服务器上生成installer,并发出通知

3:C#程序去文件服务器下载installer,拷贝至测试服务器

4:C#程序卸载测试服务器上的原程序/服务

5:C#程序根据测试需要/测试参数安装installer,直到完成部署进行

6:C#程序调动自动化脚本(QTP/SilkTest/Seleium),进行自动化测试

7:检查测试结果

第3-6步都是由一个C#程序完成的,下面我主要介绍一下第5步,也就是软件自动安装的实现原理,在掌握了自动安装之后,第4步,也就是软件的自动卸载也就同样得到解决了。

 

3: Coded UI test使用

Coded UI Test是对UI进行的测试,使用方法和很多支持UI自动化测试的工具(QTP、SilkTest)一样,都支持UI的录制、回放、识别、断言,与这类工具相比,它主要还有如下的好处:

1:基于.Net framework,且同时支持Win32/Web/WPF,利于代码的扩展和复用

2:可以编译成exe文件,脱离Visual Studio运行。

3:除了支持Web/Win应用外,还支持WPF(很多自动化工具对WPF的支持并不是太好)。

 

3.1 录制一个Coded UI test测试

一个复杂的installer,除了有复杂的安装配置之外,UI界面往往也比较复杂,在不了解Coded UI test这个办法之前,如果专门为installer写一个控制安装程序会是一件比较费时费力的工作,特别是当这个installer有多个设置窗口和控件时。而使用Coded UI test则可以非常轻松的解决这些问题,代码也便于扩展。

 

下面以notepad++这个大家常用的小工具的安装来说明如果建立一个Coded UI Test(由于我的Visual Studio 2010是英文版的,所以只能提供英文截图和英文名称),在进入下文之前,建议大家再实际下载、运行一下notepad++的安装程序,体验它每一个窗口的功能,以及支持的多种参数设置,并思考如果不使用自动化工具,如何编程实现程序的安装。

我在示例中使用的版本是5.9.6,大家可以去其官方主页http://notepad-plus-plus.org/ 下载5.9.6的版本npp.5.9.6.Installer.exe。

 

下面是具体的步骤

1:打开Visual Studio 2010,新建一个类型是Test的工程,如下图

2:删掉自动生成的第一个默认类

3:右击工程,选择Add,然后选择Coded UI Test,这时会弹出一个窗口,在此选择第一项“录制一个新测试”,点击OK按钮

4:此时,在窗口的右下角会弹出一个名为Coded UI Test Builder的窗口,点击第一个红色圆形按钮后,便可以进行一个UI测试的录制,如下图

5:在资源管理器中运行notepad++的安装程序,任意设置安装参数,逐个点击Next按钮,最后直至安装完成。

6:点击窗口右下侧Coded UI Test Builder窗口中第4个按钮,在弹出的窗口中将方法名称修改为DoInstall,然后点击Add and Generate按钮,稍等片刻后,整个程序便会生成了,这时可以关闭Coded UI Test Builder窗口。

7:生成后的工程结构如下图所示:

 

其中CodedUITest1.cs是测试类,而UIMap.uitest则包含了notepad++每个窗口的声明,以及安装的具体步骤,例如DoInstall的主体部分便是具体的每一步操作:

// Click 'OK' button
Mouse.Click(uIOKButton, new Point(40, 10));

// Click '&Next >' button
Mouse.Click(uINextButton, new Point(40, 7));

// Click 'I &Agree' button
Mouse.Click(uIIAgreeButton, new Point(40, 7));

// Click '&Next >' button
Mouse.Click(uINextButton, new Point(40, 7));

// Click '&Next >' button
Mouse.Click(uINextButton, new Point(40, 7));

// Select 'Create Shortcut on Desktop' check box
uICreateShortcutonDeskCheckBox.Checked = this.DoInstallParams.UICreateShortcutonDeskCheckBoxChecked;

// Click '&Install' button
Mouse.Click(uIInstallButton, new Point(40, 10));

// Clear '&Run Notepad++ v5.9.6' check box
uIRunNotepadv596CheckBox.Checked = this.DoInstallParams.UIRunNotepadv596CheckBoxChecked;

// Click '&Finish' button
Mouse.Click(uIFinishButton, new Point(41, 6));

 

8:如果现在按F5,程序无法运行,原因是这段代码里没有运行notepad++安装程序的代码,只是假设安装程序已经运行了,所以我们要在第一个Click动作前面加上下面的代码

string installer = @"c:\share\npp.5.9.6.Installer.exe";
ApplicationUnderTest InstallerWindow = pplicationUnderTest.Launch(installer);

现在再按F5试试?应该可能运行一个完整的安装了。

 

程序说明:

1:在录制第一个操作时,系统已经自动将每一个涉及到的UI界面及其包含的元素加以识别,并记录每一次的操作(点击、键入等),当生成代码时,会把这些东东全部输出下来。

要想查看每一个界面元素的定义,大家可以选择任意一个元素,然后按F12,查看它的声明,并进一步查看它所成的窗口的定义。

例如第一个被点击的按钮uIOKButton,它位于UIInstallerLanguageWindow中,而UIInstallerLanguageWindow则是依靠SearchProperties属性具体定位的。

 

2:我们点击按钮、选中CheckBox,对应的操作就是Mouse.Click或者某CheckBox.Checked,如果我们有复杂的安装需求,可以按照这样的思路进行定制。

 

3:在实际的安装或者参数的设置时,往往有某些控件不可见/不可用,只有满足了某种条件才会可见/ 可用。就象本文的例子中,对于正在进行安装的窗口,其Next按钮是不可用的,见下图:

该按钮会在安装完成后可用,如果程序在这时要点击这个Next按钮,会导致程序报错,这时怎么办呢?

按照很多人的编程习惯,往往会用sleep(5)来解决,但这也有问题,不同的计算机性能不同, 在一台计算机上设置好的时间,在另外一台上可能过短,如果把时间设足够长,又会导致效率下降。
Coded UI Test提供了一系列方法处理这类问题,如下:

WaitForControlCondition():控件满足某种条件后再往下执行
WaitForControlEnabled():控件有效后再往下执行
WaitForControlExist():控件可以被找到后再往下执行
WaitForControlNotExist():控件不存在时再往下执行
WaitForControlPropertyEqual():控件的某个属性等于等值后再往下执行
WaitForControlPropertyNotEqual():控件的某个属性不等于等值后再往下执行
WaitForControlReady():控件准备就序后再往下执行

 

这样,对上同样例子中的倒数第二行代码,在程序安装时,由于要花费一定的时间,uIRunNotepadv596CheckBox所处的窗口还没有显现,uIRunNotepadv596CheckBox自然还无效,因此,对于性能较的计算机,执行到这句话时可能出错,为了保险,可以在之前增加一行代码:

uIRunNotepadv596CheckBox. WaitForControlReady();

然后再执行后面的:

uIRunNotepadv596CheckBox.Checked = this.DoInstallParams.UIRunNotepadv596CheckBoxChecked;

就可以保证该控件是在有效的情况下执行后面的操作了。  

 

4:控件的名称、窗口的名称都是程序自动生成的,如果觉得命名不好,可以用Visual Studio 提供的重构-改名功能进行替换。

 

5:程序的入口是public void CodedUITestMethod1(),默认是无参数的,如果需要在安装中设置复杂的参数,以及把安装程序的路径传递进去,可以在此增加参数,然后把参数传递到具体的执行方法DoInstall()

 

3.2 让程序脱离Visual Studio执行

以上的代码只能Visual Studio中运行,要想让它脱离Visual Studio也能运行,需要做如下操作。

1:增加一个类,假设名称是TestMagager,加入如下代码

public static void Init()
{
if (!Playback.IsInitialized)
{
Playback.Initialize();
}
}

  

2:新建另一个工程(可以是Windows,也或以是类库),引用上述的测试工程,然后在代码先中调Init(),然后直接调用安装的主程序,如下:

TestMagager.Init();

CodedUITest1 t = new CodedUITest1();
t.CodedUITestMethod1();

  

3:这个新建的工程编译成功后,理论上调用上述的代码可以进行软件的安装,但此时会报错误,提示所需要的DLL文件不存在,其原因是:

对于Test类工程,Visual Studio 可以找到依赖的DLL文件,然而被引用由其它的程序调用后,便不能找到这些文件,只要手工把它们拷贝到一个统一的目录,然后引用到新建的工程就可以了,这些文件是:

Microsoft.VisualStudio.QualityTools.CodedUITestFramework.dll
Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll
Microsoft.VisualStudio.QualityTools.UnitTestFramework.xml
Microsoft.VisualStudio.TestTools.TestSettings.Common.dll
Microsoft.VisualStudio.TestTools.TestSettings.dll
Microsoft.VisualStudio.TestTools.UITest.CodeGeneration.dll
Microsoft.VisualStudio.TestTools.UITest.CodeGeneration.xml
Microsoft.VisualStudio.TestTools.UITest.Common.dll
Microsoft.VisualStudio.TestTools.UITest.Common.xml
Microsoft.VisualStudio.TestTools.UITest.Extension.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.IE.Communication.Interop.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.IE.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.MSAA.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.Uia.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.xml
Microsoft.VisualStudio.TestTools.UITest.Framework.dll
Microsoft.VisualStudio.TestTools.UITest.Playback.dll
Microsoft.VisualStudio.TestTools.UITest.Recorder.dll
Microsoft.VisualStudio.TestTools.UITesting.dll
Microsoft.VisualStudio.TestTools.UITesting.dll

 

在Visual Studio的安装目录下搜索,可以找到这些文件,它们分别存储在\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies和

\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies目录下,把它们拷到一个目录中,然后在应用中全部引用,便可以运行新建的这个工程了。

 

3.3 示例程序

Coded UI Test程序地址是:点击这里

解压缩后,一共有两个文件夹,第一个是Coded UI Test工程,第二个是Winform对它的调用。

因为偷懒,所有Project的文件全是系统默认的,生成的代码也没有重构,Coded UI Test工程用硬代码的方式运行Notepad++的安装程序(c:\share\ npp.5.9.6.Installer.exe),建议大家以参考代码结构为主,自己动手来建立一个类似的运行程序。

如果大家真的要运行示例程序,需要c:\share\ npp.5.9.6.Installer.exe这个程序存在,而且在安装Visual Studio 2010时,安装对测试工程的支持。

最后再说明,我已经把英文Visual Studio 2010的dll文件拷贝到了WindowsFormsApplication1的bin\debug目录下,并且在XP环境下测试通过。

使用上面的思路,还可以实现程序的自动卸载。

 

后记:按照上述方法,我实现了几个应用程序(包括服务)的自动安装、卸载,从而实现了上文提到的自动部署、测试,初步实现持续集成。

本人对Coded UI Test了解也仅限于此,如有不正确的地方,欢迎批评指正,多谢!

posted on 2012-02-08 23:21  HackerVirus  阅读(472)  评论(0编辑  收藏  举报