CodeUI Test_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > CodeUI Test

CodeUI Test

 2014/7/28 15:15:40  我是小凯哥  程序员俱乐部  我要评论(0)
  • 摘要:简要:CodeUITest是一个集成在VS2010和更高的版本上的一个公共的自动化测试API,由于它不是.NetFrameWork的一个部分,而是作为VS的一个公共组件,所以对于VS版本的依赖很大,只有在2010的Premiun和Ultimate已经更高的版本中才可以使用,对于这两个版本在安装的过程中,也会出现一些问题,导致安装路径下缺少相关的一些程序集,后期也很容易出现问题。近期由于在接触CodeUI自动化测试工具开发的项目
  • 标签:

简要:

     CodeUI Test 是一个集成在VS2010和更高的版本上的一个公共的自动化测试API,由于它不是.NetFrameWork的一个部分,而是作为VS的一个公共组件,所以对于VS版本的依赖很大,只有在2010PremiunUltimate已经更高的版本中才可以使用,对于这两个版本在安装的过程中,也会出现一些问题,导致安装路径下缺少相关的一些程序集,后期也很容易出现问题。近期由于在接触CodeUI自动化测试工具开发的项目,所以对CodeUI的这一整体技术先在原理和内部实现机制上做一个学习总结。


 Agenda:

   1. CodeUI 基本实现框图。

   2. Sample 基本演示代码。

   3.CodeUI 实现代码深度分析。


 

 1. CodeUI 基本实现框图:

 

 


 

   2. Sample 基本演示代码:

         2.0 CodeUI已经有了一套录制操作步骤生成测试代码的功能,可以将功能测试的一些动作录制并生成测试代码,但生成的往往不会是我们最满意的效果,所以我们需要修改调整,然后执行测试时,能够模拟用户的一些功能更性操作,比如登陆,点击,录入等实现自动化测试。

         2.1首先我们创建一个Winform小程序,实现加法的一个简易计算的界面,采用四个操作用例去验证它的界面计算的功能,然后我们新建一个CodeUI测试项目,自动打开我们刚刚写好的winForm小程序,然后在界面录入数据,模拟用例点击的界面用户事件,在每一个操作完成后,添加断言验证预期与实际输出是否一致。

                                       图1:创建的测试winform计算程序

 

     2.2 新建一个CodeUI测试项目:

      

   2.3  打开执行刚才的winForm程序,然后新增测试项目时,选择录制:

   

  2.4 开始录制功能测试的操作,和数据录入:

             在 “txt_num1” 文本框 中键入“12345”在 “txt_num2” 文本框 中键入“45678” 单击 “Calculate” 按钮

            在 “txt_num1” 文本框 中键入“0.123”在 “txt_num2” 文本框 中键入“12344” 单击 “Calculate” 按钮

            在 “txt_num1” 文本框 中键入“12345.123”在 “txt_num2” 文本框 中键入“0.123” 单击 “Calculate” 按钮

            在 “txt_num1” 文本框 中键入“1233”在 “txt_num2” 文本框 中键入“232332”单击 “Reset” 按钮

     

    生成代码得到的几个重要文件如下:这也是我们最后要深入理解的程序集和文件。

   

  

   

 核心源程序:

class="code_img_closed" src="/Upload/Images/2014072815/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('251c801d-999b-4d8c-883f-a103ab5d076b',event)" src="/Upload/Images/2014072815/2B1B950FA3DF188F.gif" alt="" />
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Input;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;


namespace myCodedUITest
{
    /// <summary>
    /// CodedUITest1 的摘要说明
    /// </summary>
    [CodedUITest]
    public class CodedUITest1
    {
        // public resource
       private Process process;
       private const string path = @"C:\myCodeUISample.exe";
        public CodedUITest1()
        {

        }

        [TestMethod]
        public void CodedUITestMethod1()
        {
            process= new Process();
            inistallTest();
            this.UIMap.RecordedMethod1();
            closeTest();
        }

      

        /// <summary>
        /// 
        /// </summary>
        public void closeTest() {
            process.Close();
        
        }
        public void inistallTest() {

            System.Diagnostics.Process.Start(path);

        }
        #region 附加测试特性

        // 编写测试时,可以使用以下附加特性: 

        ////运行每项测试之前使用 TestInitialize 运行代码 
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{        
        //    // 若要为此测试生成代码,请从快捷菜单中选择“为编码的 UI 测试生成代码”,然后选择菜单项之一。
        //}

        ////运行每项测试之后使用 TestCleanup 运行代码
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{        
        //    // 若要为此测试生成代码,请从快捷菜单中选择“为编码的 UI 测试生成代码”,然后选择菜单项之一。
        //}

        #endregion

        /// <summary>
        ///获取或设置测试上下文,该上下文提供
        ///有关当前测试运行及其功能的信息。
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }
        private TestContext testContextInstance;

        public UIMap UIMap
        {
            get
            {
                if ((this.map == null))
                {
                    this.map = new UIMap();
                }

                return this.map;
            }
        }

        private UIMap map;
    }
}
myCodedUITest
// ------------------------------------------------------------------------------
//  <auto-generated>
//      此代码由编码的 UI 测试生成器生成。
//      版本: 12.0.0.0
//
//      如果重新生成代码,则更改此文件可能会导致错误的行为,
//      并将丢失这些更改。
//  </auto-generated>
// ------------------------------------------------------------------------------

namespace myCodedUITest
{
    using System;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Text.RegularExpressions;
    using System.Windows.Input;
    using Microsoft.VisualStudio.TestTools.UITest.Extension;
    using Microsoft.VisualStudio.TestTools.UITesting;
    using Microsoft.VisualStudio.TestTools.UITesting.WinControls;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;
    using Mouse = Microsoft.VisualStudio.TestTools.UITesting.Mouse;
    using MouseButtons = System.Windows.Forms.MouseButtons;
    
    
    [GeneratedCode("编码的 UI 测试生成器", "12.0.21005.1")]
    public partial class UIMap
    {
        
        /// <summary>
        /// Test The Calculate function is performance well
        /// </summary>
        public void RecordedMethod1()
        {
            #region Variable Declarations
            WinEdit uITxt_num1Edit = this.UIForm1Window.UITxt_num1Window.UITxt_num1Edit;
            WinEdit uITxt_num2Edit = this.UIForm1Window.UITxt_num2Window.UITxt_num2Edit;
            WinButton uICalculateButton = this.UIForm1Window.UICalculateWindow.UICalculateButton;
            WinEdit uITxt_sumEdit = this.UIForm1Window.UITxt_sumWindow.UITxt_sumEdit;
            WinButton uIResetButton = this.UIForm1Window.UIResetWindow.UIResetButton;
            #endregion

            // 未录制上一个鼠标操作。

            // 在 “txt_num1” 文本框 中键入“12345”
            uITxt_num1Edit.Text = this.RecordedMethod1Params.UITxt_num1EditText;

            // 在 “txt_num2” 文本框 中键入“45678”
            uITxt_num2Edit.Text = this.RecordedMethod1Params.UITxt_num2EditText;

            // 单击 “Calculate” 按钮
            Mouse.Click(uICalculateButton, new Point(19, 18));

            AssertMethod1();

            // 单击 “txt_sum” 文本框
            Mouse.Click(uITxt_sumEdit, new Point(49, 7));

            // 在 “txt_num1” 文本框 中键入“0.123”
            uITxt_num1Edit.Text = this.RecordedMethod1Params.UITxt_num1EditText1;

            // 在 “txt_num2” 文本框 中键入“12344”
            uITxt_num2Edit.Text = this.RecordedMethod1Params.UITxt_num2EditText1;

            // 单击 “Calculate” 按钮
            Mouse.Click(uICalculateButton, new Point(45, 14));

            AssertMethod1();

            // 在 “txt_num1” 文本框 中键入“12345.123”
            uITxt_num1Edit.Text = this.RecordedMethod1Params.UITxt_num1EditText2;

            // 在 “txt_num2” 文本框 中键入“0.123”
            uITxt_num2Edit.Text = this.RecordedMethod1Params.UITxt_num2EditText2;

            // 单击 “Calculate” 按钮
            Mouse.Click(uICalculateButton, new Point(46, 13));

            AssertMethod1();

            // 单击 “Reset” 按钮
            Mouse.Click(uIResetButton, new Point(64, 12));

            AssertMethod2();

            // 在 “txt_num1” 文本框 中键入“1233”
            uITxt_num1Edit.Text = this.RecordedMethod1Params.UITxt_num1EditText3;

            // 在 “txt_num2” 文本框 中键入“232332”
            uITxt_num2Edit.Text = this.RecordedMethod1Params.UITxt_num2EditText3;

            // 单击 “Reset” 按钮
            Mouse.Click(uIResetButton, new Point(50, 7));

            AssertMethod2();
        }
        
        /// <summary>
        /// AssertMethod1 - 使用“AssertMethod1ExpectedValues”将参数传递到此方法中。
        /// </summary>
        public void AssertMethod1()
        {
            #region Variable Declarations
            WinEdit uITxt_num1Edit = this.UIForm1Window.UITxt_num1Window.UITxt_num1Edit;
            WinEdit uITxt_num2Edit = this.UIForm1Window.UITxt_num2Window.UITxt_num2Edit;
            WinEdit uITxt_sumEdit = this.UIForm1Window.UITxt_sumWindow.UITxt_sumEdit;
            WinButton uIResetButton = this.UIForm1Window.UIResetWindow.UIResetButton;
            #endregion

            // 点击计算后断言
            Assert.AreEqual(Double.Parse(uITxt_num1Edit.Text) + Double.Parse(uITxt_num2Edit.Text), Double.Parse(uITxt_sumEdit.Text), 0);

        }

        public void AssertMethod2() {

            #region Variable Declarations
            WinEdit uITxt_num1Edit = this.UIForm1Window.UITxt_num1Window.UITxt_num1Edit;
            WinEdit uITxt_num2Edit = this.UIForm1Window.UITxt_num2Window.UITxt_num2Edit;
            WinEdit uITxt_sumEdit = this.UIForm1Window.UITxt_sumWindow.UITxt_sumEdit;
            WinButton uIResetButton = this.UIForm1Window.UIResetWindow.UIResetButton;
            #endregion

            // 确认 “Reset” 按钮 等于“Reset”的“Name”属性
            Assert.AreEqual("", uITxt_num1Edit.Text.Trim() + uITxt_num2Edit.Text.Trim() + uITxt_sumEdit.Text.Trim(), true, "Test Runed Failed");
        
        }
        
        #region Properties
        public virtual RecordedMethod1Params RecordedMethod1Params
        {
            get
            {
                if ((this.mRecordedMethod1Params == null))
                {
                    this.mRecordedMethod1Params = new RecordedMethod1Params();
                }
                return this.mRecordedMethod1Params;
            }
        }
        
        public virtual AssertMethod1ExpectedValues AssertMethod1ExpectedValues
        {
            get
            {
                if ((this.mAssertMethod1ExpectedValues == null))
                {
                    this.mAssertMethod1ExpectedValues = new AssertMethod1ExpectedValues();
                }
                return this.mAssertMethod1ExpectedValues;
            }
        }
        
        public UIForm1Window UIForm1Window
        {
            get
            {
                if ((this.mUIForm1Window == null))
                {
                    this.mUIForm1Window = new UIForm1Window();
                }
                return this.mUIForm1Window;
            }
        }
        #endregion
        
        #region Fields
        private RecordedMethod1Params mRecordedMethod1Params;
        
        private AssertMethod1ExpectedValues mAssertMethod1ExpectedValues;
        
        private UIForm1Window mUIForm1Window;
        #endregion
    }
    
    /// <summary>
    /// 要传递到“RecordedMethod1”中的参数
    /// </summary>
    [GeneratedCode("编码的 UI 测试生成器", "12.0.21005.1")]
    public class RecordedMethod1Params
    {
        
        #region Fields
        /// <summary>
        /// 在 “txt_num1” 文本框 中键入“12345”
        /// </summary>
        public string UITxt_num1EditText = "12345";
        
        /// <summary>
        /// 在 “txt_num2” 文本框 中键入“45678”
        /// </summary>
        public string UITxt_num2EditText = "45678";
        
        /// <summary>
        /// 在 “txt_num1” 文本框 中键入“0.123”
        /// </summary>
        public string UITxt_num1EditText1 = "0.123";
        
        /// <summary>
        /// 在 “txt_num2” 文本框 中键入“12344”
        /// </summary>
        public string UITxt_num2EditText1 = "12344";
        
        /// <summary>
        /// 在 “txt_num1” 文本框 中键入“12345.123”
        /// </summary>
        public string UITxt_num1EditText2 = "12345.123";
        
        /// <summary>
        /// 在 “txt_num2” 文本框 中键入“0.123”
        /// </summary>
        public string UITxt_num2EditText2 = "0.123";
        
        /// <summary>
        /// 在 “txt_num1” 文本框 中键入“1233”
        /// </summary>
        public string UITxt_num1EditText3 = "1233";
        
        /// <summary>
        /// 在 “txt_num2” 文本框 中键入“232332”
        /// </summary>
        public string UITxt_num2EditText3 = "232332";
        #endregion
    }
    
    /// <summary>
    /// 要传递到“AssertMethod1”中的参数
    /// </summary>
    [GeneratedCode("编码的 UI 测试生成器", "12.0.21005.1")]
    public class AssertMethod1ExpectedValues
    {
        
        #region Fields
        /// <summary>
        /// 确认 “txt_num1” 窗口 等于“txt_num1”的“ControlName”属性
        /// </summary>
        public string UITxt_num1WindowControlName = "txt_num1";
        
        /// <summary>
        /// 确认 “txt_sum” 窗口 等于“txt_sum”的“ControlName”属性
        /// </summary>
        public string UITxt_sumWindowControlName = "txt_sum";
        
        /// <summary>
        /// 确认 “Reset” 按钮 等于“Reset”的“Name”属性
        /// </summary>
        public string UIResetButtonName = "Reset";
        #endregion
    }
    
    [GeneratedCode("编码的 UI 测试生成器", "12.0.21005.1")]
    public class UIForm1Window : WinWindow
    {
        
        public UIForm1Window()
        {
            #region 搜索条件
            this.SearchProperties[WinWindow.PropertyNames.Name] = "Form1";
            this.SearchProperties.Add(new PropertyExpression(WinWindow.PropertyNames.ClassName, "WindowsForms10.Window", PropertyExpressionOperator.Contains));
            this.WindowTitles.Add("Form1");
            #endregion
        }
        
        #region Properties
        public UITxt_num1Window UITxt_num1Window
        {
            get
            {
                if ((this.mUITxt_num1Window == null))
                {
                    this.mUITxt_num1Window = new UITxt_num1Window(this);
                }
                return this.mUITxt_num1Window;
            }
        }
        
        public UITxt_num2Window UITxt_num2Window
        {
            get
            {
                if ((this.mUITxt_num2Window == null))
                {
                    this.mUITxt_num2Window = new UITxt_num2Window(this);
                }
                return this.mUITxt_num2Window;
            }
        }
        
        public UICalculateWindow UICalculateWindow
        {
            get
            {
                if ((this.mUICalculateWindow == null))
                {
                    this.mUICalculateWindow = new UICalculateWindow(this);
                }
                return this.mUICalculateWindow;
            }
        }
        
        public UITxt_sumWindow UITxt_sumWindow
        {
            get
            {
                if ((this.mUITxt_sumWindow == null))
                {
                    this.mUITxt_sumWindow = new UITxt_sumWindow(this);
                }
                return this.mUITxt_sumWindow;
            }
        }
        
        public UIResetWindow UIResetWindow
        {
            get
            {
                if ((this.mUIResetWindow == null))
                {
                    this.mUIResetWindow = new UIResetWindow(this);
                }
                return this.mUIResetWindow;
            }
        }
        #endregion
        
        #region Fields
        private UITxt_num1Window mUITxt_num1Window;
        
        private UITxt_num2Window mUITxt_num2Window;
        
        private UICalculateWindow mUICalculateWindow;
        
        private UITxt_sumWindow mUITxt_sumWindow;
        
        private UIResetWindow mUIResetWindow;
        #endregion
    }
    
    [GeneratedCode("编码的 UI 测试生成器", "12.0.21005.1")]
    public class UITxt_num1Window : WinWindow
    {
        
        public UITxt_num1Window(UITestControl searchLimitContainer) : 
                base(searchLimitContainer)
        {
            #region 搜索条件
            this.SearchProperties[WinWindow.PropertyNames.ControlName] = "txt_num1";
            this.WindowTitles.Add("Form1");
            #endregion
        }
        
        #region Properties
        public WinEdit UITxt_num1Edit
        {
            get
            {
                if ((this.mUITxt_num1Edit == null))
                {
                    this.mUITxt_num1Edit = new WinEdit(this);
                    #region 搜索条件
                    this.mUITxt_num1Edit.WindowTitles.Add("Form1");
                    #endregion
                }
                return this.mUITxt_num1Edit;
            }
        }
        #endregion
        
        #region Fields
        private WinEdit mUITxt_num1Edit;
        #endregion
    }
    
    [GeneratedCode("编码的 UI 测试生成器", "12.0.21005.1")]
    public class UITxt_num2Window : WinWindow
    {
        
        public UITxt_num2Window(UITestControl searchLimitContainer) : 
                base(searchLimitContainer)
        {
            #region 搜索条件
            this.SearchProperties[WinWindow.PropertyNames.ControlName] = "txt_num2";
            this.WindowTitles.Add("Form1");
            #endregion
        }
        
        #region Properties
        public WinEdit UITxt_num2Edit
        {
            get
            {
                if ((this.mUITxt_num2Edit == null))
                {
                    this.mUITxt_num2Edit = new WinEdit(this);
                    #region 搜索条件
                    this.mUITxt_num2Edit.WindowTitles.Add("Form1");
                    #endregion
                }
                return this.mUITxt_num2Edit;
            }
        }
        #endregion
        
        #region Fields
        private WinEdit mUITxt_num2Edit;
        #endregion
    }
    
    [GeneratedCode("编码的 UI 测试生成器", "12.0.21005.1")]
    public class UICalculateWindow : WinWindow
    {
        
        public UICalculateWindow(UITestControl searchLimitContainer) : 
                base(searchLimitContainer)
        {
            #region 搜索条件
            this.SearchProperties[WinWindow.PropertyNames.ControlName] = "btn_Calculate";
            this.WindowTitles.Add("Form1");
            #endregion
        }
        
        #region Properties
        public WinButton UICalculateButton
        {
            get
            {
                if ((this.mUICalculateButton == null))
                {
                    this.mUICalculateButton = new WinButton(this);
                    #region 搜索条件
                    this.mUICalculateButton.SearchProperties[WinButton.PropertyNames.Name] = "Calculate";
                    this.mUICalculateButton.WindowTitles.Add("Form1");
                    #endregion
                }
                return this.mUICalculateButton;
            }
        }
        #endregion
        
        #region Fields
        private WinButton mUICalculateButton;
        #endregion
    }
    
    [GeneratedCode("编码的 UI 测试生成器", "12.0.21005.1")]
    public class UITxt_sumWindow : WinWindow
    {
        
        public UITxt_sumWindow(UITestControl searchLimitContainer) : 
                base(searchLimitContainer)
        {
            #region 搜索条件
            this.SearchProperties[WinWindow.PropertyNames.ControlName] = "txt_sum";
            this.WindowTitles.Add("Form1");
            #endregion
        }
        
        #region Properties
        public WinEdit UITxt_sumEdit
        {
            get
            {
                if ((this.mUITxt_sumEdit == null))
                {
                    this.mUITxt_sumEdit = new WinEdit(this);
                    #region 搜索条件
                    this.mUITxt_sumEdit.WindowTitles.Add("Form1");
                    #endregion
                }
                return this.mUITxt_sumEdit;
            }
        }
        #endregion
        
        #region Fields
        private WinEdit mUITxt_sumEdit;
        #endregion
    }
    
    [GeneratedCode("编码的 UI 测试生成器", "12.0.21005.1")]
    public class UIResetWindow : WinWindow
    {
        
        public UIResetWindow(UITestControl searchLimitContainer) : 
                base(searchLimitContainer)
        {
            #region 搜索条件
            this.SearchProperties[WinWindow.PropertyNames.ControlName] = "btn_Reset";
            this.WindowTitles.Add("Form1");
            #endregion
        }
        
        #region Properties
        public WinButton UIResetButton
        {
            get
            {
                if ((this.mUIResetButton == null))
                {
                    this.mUIResetButton = new WinButton(this);
                    #region 搜索条件
                    this.mUIResetButton.SearchProperties[WinButton.PropertyNames.Name] = "Reset";
                    this.mUIResetButton.WindowTitles.Add("Form1");
                    #endregion
                }
                return this.mUIResetButton;
            }
        }
        #endregion
        
        #region Fields
        private WinButton mUIResetButton;
        #endregion
    }
}
uimap.designer.cs

2.5 执行测试:

    

 

3.CodeUI 实现代码深度分析:

   CodeUI Test的核心我认为其实是如何获取测试环境(程序运行环境)上的UI控件,并能够操作它的属性和方法,而且目前支持WPF,Winform……但这些都得力与开放的一些API,下面我们就来看一下。

   几个重要的程序集:

  Microsoft.VisualStudio.QualityTools.CodedUITestFramework.dll

  Microsoft.VisualStudio.TestTools.UITesting.dll  -----提供了初始化应用程序界面控件的封装。

    ps:我们本次使用的是winform程序,所以为了初始化和获取到界面控件,引入了winControls声明和操作winForm控件属性和方法。

    Microsoft.VisualStudio.TestTools.UITest.Extension.dll  

    Microsoft.VisualStudio.TestTools.UITest.Common.dll  ---主要用户Test代码生成相关的类

  

  今天先写到这里吧,明天再做一些更深入的代码补充。

 

  • 相关文章
发表评论
用户名: 匿名