内需思索提供各个分歧景观的值来循环测试该函数公海赌船网址

  在Visual Studio中,Coded UI
Test已经不是何等新个性了,较早版本的Visual
Studio中就曾经有其一东东了。它首要用来支援自动化测试程序员和开垦职员确认保障程序在UI方面向来不别的难题。那在那之中包罗了丰硕的始末。在那前边,作者直接对自动化测试的职业以及怎样是自动化测试管中窥豹,具备自动化测试编码技巧的技术员所左右的技术在某种程度上要远超程序开荒职员和设计人士,对于这点,作者早有据悉!但结束亲身感受本身才确信,测试职业远未有大家想像得那么粗略。开辟人员大概花上数时辰即可落成项目中某三个单独模块并使其在早晚限制内平日运维,但是,自动化测试程序员只怕会花上或多或少天的命宫来编排对应的自动化测试代码来保障这一效应运维如常。

  有关如何是Coded UI Test以及怎么着采用Coded UI
Test可以查阅本身的另壹篇小说:http://www.cnblogs.com/jaxu/p/3706652.html

  Coded UI
Test包蕴了老大丰富的API库,它能够录像和回看UI操作,捕捉UI成分并拿走属性的值,并转移操作代码。测试人员在转换代码的根基上对测试对象的值举办逻辑决断并付诸测试结果。创设一个Coded
UI Test很轻松,大诸多景观下,大家只须求凭借Visual
Studio就足以成功绝超越2/4操作。为了证实1切操作进度,大家借使一个测试须要:

  本文首要介绍怎么着在Coded UI
Test中采取数据驱动测试。思量那样三个场地:开垦人士提交了1个函数,该函数达成了二个数学公式的运算,通过收取七个数字并拓展数学生运动算给出结果。测试人士依照给定的数学公式,须求思索提供各类区别情况的值来循环测试该函数。显著,大家要求提供二个数据源,依据数据源中提供的两样的值来开始展览自动化测试。那是最遍及的数目驱动测试的案例。在依附Coded
UI
Test的Webpage自动化测试中,浏览器包容性难题是日常要思考的,大家能够在数据源(数据源大概是三个记事本只怕3个简练的Excel表格)中提供要测试的浏览器的名号和本子号,然后让Coded
UI
Test自动加载差别的浏览器来循环测试目的页面。上面包车型地铁内容会介绍那一个方法。

在浏览器中打开百度搜索,输入“jaxu cnblogs”关键字,搜索并查看结果的第一条是否为“Jaxu - 博客园”

  那里有两篇文章详细描述了怎样通过[DataSource]特点属性来形成多少驱动Coded
UI
Test。其核心境想是通过在TestMethod前边增多[DataSource]特色属性,并点名数据源的种类和地点,然后Coded
UI Test的测试方法在运维时会自动读取数据源中的数据,在迭代中成就比对。

 

http://blogs.msdn.com/b/mathew_aniyan/archive/2009/03/17/data-driving-coded-ui-tests.aspx

基本操作

http://msdn.microsoft.com/en-us/library/ms182527.aspx

  (本文演示的有着代码和操作均在Visual Sutdio 20壹三和Windows 8.一 + IE
1壹境况下)

  上边那段代码表达了这一动静:

  在Visual Studio中初露创办三个Coded UI Test Project。那很轻易!

[TestMethod]
[DataSource("System.Data.Odbc", @"Dsn=Excel Files;dbq=C:\Box Office Results.xlsx;defaultdir=C:;driverid=1046;maxbuffersize=2048;pagetimeout=5", "BoxOfficeResults$", DataAccessMethod.Sequential)]
public void MyTest()
{
    int rowIndex = this.TestContext.DataRow.Table.Rows.IndexOf(this.TestContext.DataRow);
    string s = this.TestContext.DataRow[0].ToString();
}

公海赌船网址 1

  特征属性[DataSource]有多少个重载,以用来经过不相同的点子钦赐数据源的地点。假如你不知底上述代码中的数据源连接字符串是何许提供的,可以在Visual
Studio中品尝加多数据源操作,然后拷贝当中自动生成的数量源连接字符串。

  工程创设成功后,Visual
Studio会问你是马上开首二个新的UI录像依旧选拔已经录像好的操作。当然你也能够选取撤废,在前边的手续里再初阶UI录像。

  1. 在Visual Studio中通过VIEW->Other Windows->Data
    Sources张开数据源窗口
  2. 点击增多一个新的数据源,选取Database
  3. 点击New Connection…在张开的窗口中通过ODBC方式选取Excel文件,Visual
    Studio会自动为您转移连接字符串
  4. 拷贝该连接字符串

公海赌船网址 2

公海赌船网址 3

  工程默许生成CodedUITest一.cs文书。在起首录像UI操作在此之前,对基本概念做一下介绍:

公海赌船网址 4

  1. Coded UI
    Test工程的运转是从包蕴有[CodedUITest]特征属性的类初叶的。2个工程中可以有四个如此的类。
  2. 与一般的工程不相同,大家不能够由此F5也许点击Visual
    Studio中的运营开关来调治或直接运转为工人身份程,Coded UI
    Test工程必须经过Test
    Explorer可能在包蕴有[CodedUITest]本性属性的类中来摘取运营相应的测试方法。
  3. 在带有[CodedUITest]性情属性的类中,全部的测试方法都不可能不含有[TestMethod]特色属性,以代表它是1个实惠的测试方法,能够直接运行。
  4. 经过甄选TEST->Windows->Test Explorer能够张开Test
    Explorer窗口,在Test
    Explorer窗口中得以查看工程中持有的测试方法并选拔运转。当然,你也能够在蕴藏[TestMethod]特点属性的测试方法的代码块中右键采纳运转该测试方法。
  5. 测试方法一样能够调弄整理。在选择运维测试方法时,你会看出有Debug
    Test的菜系,调节和测试的长河和在平时工程中一样。

  运营方面包车型客车代码,你会发觉其实数据读取职业是在迭代中产生的。也正是说测试方法会被频频地迭代,直到数据源中全部行均被读取实现。数据迭代的办法可因而枚举DataAccessMethod来内定,壹共二种方法:顺序读取或随便读取。

公海赌船网址 5

  大家将方面代码中的Excel文件放到C盘根目录,然后调节和测试代码。Excel中的第三行默许会被当作标题,数据默许会从第一行起先读取,所以率先次迭代的时候DataRow[0]回去的是Excel中A二单元格的剧情。TestContext对象被作为数据源上下文,通过它你可以找到数据源的片段性质。举例通过地点代码中的第②行获得到数据源的行索引。这里是msdn上关于DataRow属性的认证http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.testcontext.datarow.aspx

  然后,大家开端一个UI摄像。在工程中增添1个Coded UI Test
Map文件。创制成功后Visual Studio会自动在显示器的右下角张开Coded UI Test
Builder窗口,以有益我们进行UI录像操作。

公海赌船网址 6

公海赌船网址 7

公海赌船网址 8

  借用MSDN上的图样来对Coded UI Test
Builder窗口上按键的法力做一下简便的认证:

  将数据源连接字符串直接写在代码里并不是怎样明智之举,那有没有啥方法能够将它移到安插文件中吗?答案是迟早的!通过msdn的那篇文章我们得以摸清如何将数据源连接字符串移到布置文件中http://msdn.microsoft.com/en-us/library/ms243192.aspx

  • Record icon – 最先一个UI操作的录像。举例菜单导航、按键点击等操作。
  • Edit steps – 对录像的步骤进行编辑,调度依然去除冗余的步调。
  • Add assertions –
    不仅仅是加多断言,通过点击该按键并拖放到测试对象的UI上以选择控件,然后您能够增加断言。
  • Generate code –
    这一步很关键,在做到上述全体的操作后,通过点击该按键Visual
    Studio会自动为你转移代码。生成的代码在.uitest文件上面包车型地铁.Desinger.cs文件中能够见到。留神不要手动修改自动生成的代码,那会招致下次经过Coded
    UI Test Builder窗口对.uitest文件进行修改时或多或少对象或操作分化台。
  • Close to finish recoding – 在关闭Coded UI Test
    Builder窗口在此以前,确定保障所做的改换已经更换了相应的代码。假使要修改.Designer.cs文件中自动生成的代码,能够在Solution
    Explorer中右键选取.uitest文件,然后采纳艾德it With Coded UI Test
    Builder。在前边的步调中大家会讲到那点。

  首先在工程中加多Application Configuration File,即App.config。

公海赌船网址 9

公海赌船网址 10

  UI Action的摄像和UI控件的挑3拣四操作是分手的。让大家先初步UI
Action的录制。

  内容如下:

  1. 点击Coded UI Test Builder窗口中的浅绿按键
  2. 开发IE浏览器,在地方栏中输入http://www.baidu.com以导航到百度搜索引擎
  3. 输加入关贸总协定协会键字“jaxu cnblogs”,点击“百度时而”
  4. 在Coded UI Test Builder窗口中式点心击Pause,然后点击Edit
    steps,删除不须求的步调。笔者删除了操作中的第肆步和第陆步。
  5. 选择Generate code,对所要生成的不二法门取个名字,然后点击Add and
    Generate开关。Visual
    Studio为大家所摄像的UI操作步骤生成了对应的代码。
  6. 关闭Coded UI Test Builder窗口,在Visual Studio中查看刚才生成的代码。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="microsoft.visualstudio.testtools" type="Microsoft.VisualStudio.TestTools.UnitTesting.TestConfigurationSection, Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
  </configSections>

  <connectionStrings>
    <add name="MyExcelConn" providerName="System.Data.Odbc" connectionString="Dsn=Excel Files;dbq=C:\Box Office Results.xlsx;defaultdir=C:;driverid=1046;maxbuffersize=2048;pagetimeout=5"/>
  </connectionStrings>
  <microsoft.visualstudio.testtools>
    <dataSources>
      <add name="BoxOfficeResults" connectionString="MyExcelConn" dataTableName="BoxOfficeResults$" dataAccessMethod="Sequential"/>
    </dataSources>
  </microsoft.visualstudio.testtools>
</configuration>

公海赌船网址 11

  注意microsoft.visualstudio.testtools节中type属性的版本号大概会出于选拔的.NET
Framework版本的不等有所改动。二.0为八.0.0.0,叁.五为玖.0.0.0,叁.伍上述应该是10.0.0.0。在App.config文件中加上上述配置消息之后,将测试方法的[DataSource]特色属性改成

公海赌船网址 12

[DataSource("BoxOfficeResults")]

  在Solution
Explorer中张开UIMap一.uitest文件,选择并开发UIMap1.Designer.cs文书,能够见见刚才所生成的代码。是还是不是很想明日就运转一下,来看望那些自动生成的代码怎么着运行?今后还相当,因为唯有的UI
Action运营未有其他意义,Coded UI
Test的实在意义是通过UI操作来牢固到UI上的某四个一定成分,并最后通过断言来分明该因素的习性是不是和预期的值格外。

  借使Excel文件中设有几个表,则足以在安顿文件的<dataSources>中加多四个<add>节点,指明区别的数据表名称和数码读取格局。

  为了能够手动修改.Designder.cs文件中生成的代码,大家必要将它们移到.cs文件中。在Solution
Explorer中双击UIMap一.uitest文件,在开采的窗口中大家得以看出左边是UI
Actions所生成的步子,左边是UI Control
Map(稍后我们会用到它)。在左手的UI
Actions中精选根节点RecordedMethod一,然后在顶部的菜单中采纳Move code to
UIMap一.cs,代码会被移到.cs文件以有利于我们开始展览更改。实现该手续之后,大家可以在.cs文件中看出那么些代码并做相应的修改。

  还记得小说一同先波及的应用数据驱动测试来落成多浏览器包容性测试呢?我们得以通过上面包车型客车代码来贯彻。

公海赌船网址 13

BrowserWindow.CurrentBrowser = this.TestContext.DataRow[0].ToString();

  你只怕已经注意到了,自动生成的代码中稍加对象的名字看起来并不那么好,乃至有个别还蕴藏了国文。你希望修改它们,不过不用在.Designer.cs文件中做其余退换!还记得后面大家讲过的艾德it
With Coded UI Test操作吗?在Solution
Explorer中右键选用UIMap一.uitest文件,右键采用艾德it With Coded UI
Test张开Coded UI Test Builder窗口,然后点击Add
assertions开关(正是尤其用来选取UI Control的开关),然后实行UI Control
Map分界面。如下图,大家得以对内部变化的UI Controls举办编辑和重命名。

  将分化版本的浏览器名称增加到数据源文件中,能够是一个简约的记事本恐怕.csv文件,如:

公海赌船网址 14

BrowserType
IE
firefox
chrome

  完结修改现在再也点击Generate code开关并关闭Coded UI Test
Builder窗口,此时.Designer.cs文件中自动生成的代码已经做了修改。由于后边大家早就将有关的UI
Actions部分的代码移到.cs文件里了,所以重命名的目的我们还索要在.cs文件中手动进行修改,不然编写翻译时会出错。提议在将代码移到.cs文件此前到位自动生成代码的更动工作,以幸免手动修改过多的代码。

  注意第贰行是标题,[DataSource]特点属性在读取数据时始终会将首先行默感到标题行,数据暗中同意是从第二行初阶读取的。浏览器只须要提供名称就可以,大小写未有涉嫌。假设您的测试方法要求在分歧的浏览器中变成测试,则足以尝尝该格局,但自己不有限支撑内部是不是会波及到包容性难题,就如自家在前1篇文章中提到的Coded
UI
Test怎么样在页面上寻觅一个控件,假设搜索的规格存在浏览器包容性难题,则恐怕会抛出卓殊。

  然后我们须求捕捉到百度搜索结果的UI控件,并对个中的结果开始展览判定。依然使用Coded
UI Test Builder窗口。

 

  1. 开荒浏览器并导航到百度,输加入关贸总协定组织键字“jaxu cnblogs”并点击“百度时而”
  2. 在Coded UI Test Builder窗口中点击Add
    assertions开关并拖放到浏览器窗口,同时指向你想要捕捉的控件上。某些控件很难准确捕捉到,未有关联,你能够先选中接近的控件,然后利用Coded
    UI Test
    Builder窗口中的方向开关移动到您所要定位的因素。如下图,我们采用并稳固到了百度搜索结果的DIV成分,并将该控件命名称为UIContent_leftPane。
  3. 在Coded UI Test
    Builder窗口的左上角点击增加选拔的控件,那一点很要紧!忘记这一步则所接纳的控件不会被增加到生成的代码中。
  4. 变迁代码并关闭Coded UI Test Builder窗口。

  固然通过[DataSource]本性属性能够十一分便宜地读取数据源中的数据来造成数据驱动测试,可是有个别景况下那种方法并不适用。思虑一个粗略的供给:被测试页面上有二个表格,其数量出自服务器上的一个Excel文件。通过编写制定基于数据驱动测试的Coded
UI Test方法来检查页面上显得的内容是还是不是与Excel文件1律。

公海赌船网址 15

  由于[DataSource]特点属性是以迭代的措施来张开数据驱动测试的,因而大家不能在数量迭代的进度中去遍历页面UI成分。况且,倘诺迭代中设有Assert断言,也不太有利大家输出测试结果。最终的盼望是,遍历整个UI
Table,通过与事先读取的数据源中的数据实行依次比对来落成全体育项目检查测试试,其经过可能是如此:

  至此,全数的UI Actions和UI
Controls都已经定义落成,接下去我们要编码以成功对搜索结果的决断。借助于自动生成的代码,大家编辑了下边包车型地铁测试方法以完结小说最开首的测试须求。

  1. 读取数据源中的数据并缓存。由于不可能利用[DataSource]特色属性自动读取数据,由此只可以自个儿编写代码来形成数据读取操作。
  2. 找到UI Table实行遍历,将富有单元格的数目缓存。
  3. 将两有个别缓存的多寡举办比对,那大概需求事先提供Mapping以扶植成功多少比对进度。
namespace CodedUITestProject2.UIMap1Classes
{
    using Microsoft.VisualStudio.TestTools.UITesting.HtmlControls;
    using Microsoft.VisualStudio.TestTools.UITesting.WinControls;
    using System;
    using System.Collections.Generic;
    using System.CodeDom.Compiler;
    using Microsoft.VisualStudio.TestTools.UITest.Extension;
    using Microsoft.VisualStudio.TestTools.UITesting;
    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;
    using System.Drawing;
    using System.Windows.Input;
    using System.Text.RegularExpressions;


    public partial class UIMap1
    {
        public void TestSearchResult()
        {
            HtmlDiv resultPanel = this.UINewtabInternetExplorWindow.UIJaxucnblogs_SearchDocument.UIContent_leftPane;
            HtmlDiv resultPanelFirst = (HtmlDiv)resultPanel.GetChildren()[0];
            HtmlHyperlink link = new HtmlHyperlink(resultPanelFirst);
            Assert.AreEqual("Jaxu - 博客园", link.InnerText, "Validation is failed.");
        }

        /// <summary>
        /// RecordedMethod1 - Use 'RecordedMethod1Params' to pass parameters into this method.
        /// </summary>
        public void RecordedMethod1()
        {
            #region Variable Declarations
            WinEdit uIItemEdit = this.UINewtabInternetExplorWindow.UIItemWindow.UIItemEdit;
            HtmlEdit uIWDEdit = this.UINewtabInternetExplorWindow.UIDocument.UIWDEdit;
            HtmlInputButton uISearchButton = this.UINewtabInternetExplorWindow.UIDocument.UISearchButton;
            #endregion

            // Go to web page 'about:Tabs' using new browser instance
            this.UINewtabInternetExplorWindow.LaunchUrl(new Uri("http://www.baidu.com"));

            // Type 'www.baidu{Enter}' in text box
            //Keyboard.SendKeys(uIItemEdit, this.RecordedMethod1Params.UIItemEditSendKeys, ModifierKeys.None);

            // Type 'jaxu cnblogs' in 'wd' text box
            uIWDEdit.Text = this.RecordedMethod1Params.UIWDEditText;

            // Click '百度一下' button
            Mouse.Click(uISearchButton, new Point(61, 18));
        }

        public virtual RecordedMethod1Params RecordedMethod1Params
        {
            get
            {
                if ((this.mRecordedMethod1Params == null))
                {
                    this.mRecordedMethod1Params = new RecordedMethod1Params();
                }
                return this.mRecordedMethod1Params;
            }
        }

        private RecordedMethod1Params mRecordedMethod1Params;
    }
    /// <summary>
    /// Parameters to be passed into 'RecordedMethod1'
    /// </summary>
    [GeneratedCode("Coded UITest Builder", "12.0.21005.1")]
    public class RecordedMethod1Params
    {

        #region Fields
        /// <summary>
        /// Go to web page 'about:Tabs' using new browser instance
        /// </summary>
        public string UINewtabInternetExplorWindowUrl = "about:Tabs";

        /// <summary>
        /// Type 'www.baidu{Enter}' in text box
        /// </summary>
        public string UIItemEditSendKeys = "www.baidu{Enter}";

        /// <summary>
        /// Type 'jaxu cnblogs' in 'wd' text box
        /// </summary>
        public string UIWDEditText = "jaxu cnblogs";
        #endregion
    }
}

  我们以http://www.cnblogs.com/jaxu/p/3635634.html页面中的表格为例来看望哪些贯彻那1经过。

  大多数代码是由Coded UI Test
Builder自动生成的,大家只编写了TestSearchResult()方法,用来探求控件并赢获得其中的值来举行判断。测试结果的论断通过Assert断言来产生,Assert提供了二种措施以帮助大家落到实处不相同的推断,具体的剧情能够参考msdn。然后对RecordedMethod1()方法做了合适修改。TestSearchResult()方法中对此怎么搜索和遍历UI控件在稍后的章节中会商量到。然后大家将具备代码的调用放到CodedUITest一.cs文本中施行。

  下边是UIMap2.uitest中的完整代码:

[TestMethod]
public void CodedUITestMethod1()
{
    UIMap1 uimap = new UIMap1();
    uimap.RecordedMethod1();

    uimap.TestSearchResult();
}
public partial class UIMap2
{
    public void LaunchPage()
    {
        this.UIExcelInteractiveViewWindow.LaunchUrl(new Uri("http://www.cnblogs.com/jaxu/p/3635634.html"));
    }

    public void TestTableData()
    {
        HtmlTable targetTable = this.UIExcelInteractiveViewWindow.UIExcelInteractiveViewDocument.UICnblogs_post_bodyPane.UIItemTable;
        HtmlRow rowall = new HtmlRow(targetTable);
        UITestControlCollection rows = rowall.FindMatchingControls();
        Dictionary<int, Dictionary<int, string>> PageTableDataCache = new Dictionary<int, Dictionary<int, string>>();
        int rowCount = rows.Count;

        for (int i = 0; i < rowCount; i++)
        {
            HtmlCell allTD = new HtmlCell(rows[i]);
            UITestControlCollection TDs = allTD.FindMatchingControls();
            Dictionary<int, string> cellsDictionary = new Dictionary<int, string>();

            int tdCount = TDs.Count;
            for (int j = 0; j < tdCount; j++)
            {
                cellsDictionary.Add(j, ((HtmlCell)TDs[j]).InnerText);
            }

            PageTableDataCache.Add(i, cellsDictionary);
        }

        Dictionary<int, Dictionary<int, string>> ExcelDataCache = GetExcelData(ConfigurationManager.AppSettings["ExcelPath"], "BoxOfficeResults");
        // load mapping
        MappingRow[] mappingRows = GetMappingRowCollection();

        string msg = string.Empty;

        for (int i = 0; i < mappingRows.Length; i++)
        {
            Dictionary<int, string> pageRowCellsDictionary = PageTableDataCache[mappingRows[i].PageTableTrIndex];
            Dictionary<int, string> excelRowCellsDictionary = ExcelDataCache[mappingRows[i].ExcelRowNum];
            MappingColumn[] mappingColumns = mappingRows[i].MappingColumn;
            for (int j = 0; j < mappingColumns.Length; j++)
            {
                string excelValue = excelRowCellsDictionary[mappingColumns[j].ExcelColumnNum];
                string pageValue = pageRowCellsDictionary[mappingColumns[j].PageTableTdIndex];

                Assert.AreEqual(excelValue, pageValue, string.Format("Validation failed at row {0} column {1}", mappingRows[i].ExcelRowNum, mappingColumns[j].ExcelColumnNum));
            }
        }
    }

    private Dictionary<int, Dictionary<int, string>> GetExcelData(string filePath, string sheetName)
    {
        Dictionary<int, Dictionary<int, string>> sheetDataDic = new Dictionary<int, Dictionary<int, string>>();
        Application excel = new Application();
        excel.Visible = false;
        excel.UserControl = true;

        try
        {
            Workbook wb = (Workbook)excel.Application.Workbooks.Open(filePath,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value,
                Missing.Value
                );

            foreach (var worksheet in wb.Worksheets)
            {
                Worksheet ws = ((Worksheet)worksheet);
                if (ws.Name.Equals(sheetName))
                {
                    int rowscount = ws.UsedRange.Cells.Rows.Count;
                    int colscount = ws.UsedRange.Cells.Columns.Count;

                    for (int i = 0; i < rowscount; i++)
                    {
                        Dictionary<int, string> cellsDictionary = new Dictionary<int, string>();
                        for (int j = 0; j < colscount; j++)
                        {
                            Range range = ws.Cells.get_Range(ConvertNumberToName(j) + (i + 1));
                            string cellText = ((object)range.Text) == null ? "" : ((object)range.Text).ToString();
                            cellsDictionary.Add(j, cellText);
                        }
                        sheetDataDic.Add(i, cellsDictionary);
                    }
                    break;
                }
            }
        }
        finally
        {
            excel.Application.Workbooks.Close();
            excel.Quit();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
            excel = null;
            GC.Collect();
        }

        return sheetDataDic;
    }

    private string ConvertNumberToName(int index)
    {
        if (index < 0) { throw new Exception("invalid parameter"); }

        List<string> chars = new List<string>();
        do
        {
            if (chars.Count > 0) index--;
            chars.Insert(0, ((char)(index % 26 + (int)'A')).ToString());
            index = (int)((index - index % 26) / 26);
        } while (index > 0);

        return String.Join(string.Empty, chars.ToArray());
    }

    private MappingRow[] GetMappingRowCollection()
    {
        Mapping mapping = null;
        MappingRow[] mappingRowCollection = null;

        XmlSerializer serializer = new XmlSerializer(typeof(Mapping));

        using (FileStream fs = new FileStream(ConfigurationManager.AppSettings["MappingsPath"], FileMode.Open))
        {
            using (XmlReader reader = XmlReader.Create(fs))
            {
                mapping = (Mapping)serializer.Deserialize(reader);
            }
        }

        if (mapping != null)
        {
            mappingRowCollection = mapping.MappingRow;
        }

        return mappingRowCollection;
    }
}

  今后得以由此Test
Explorer窗口或然间接使用测试方法的上下文菜单运营或调试该测试方法。要是经过测试,测试方法前面会来得深紫的Logo,不然会来得红棕的叉。Visual
Studio会为每一次测试生成对应的测试报告,在工程目录下的TestResults文件夹中得以找到全数的测试报告。

  当中有七个public方法:LaunchPage()用来导航到对象页面;TestTableData()用来遍历目的页面上的报表并与数据源Excel中的数据举行比对,给出测试结果。

 

  私有方法GetExcelData()用来读取Excel文件中的数据,当中使用了Microsoft.Office.Interop.Excel程序聚集的靶子,供给在工程中单独加多引用。数据按行和列的办法存放到Dicitionary字典目标中,字典中的Key为每1行的行号,Value则是另三个字典,包蕴该行全部的列。事实上,程序中的其余地方也运用了那种多少存款和储蓄结构。

有关Assert断言

  在TestTableData()方法中,1共达成了三个步骤:

  在自动化测试中,Assert断言一旦境遇测试退步的场馆就会抛出卓殊,从而致使接下去的测试方法或职责不会继续施行。也等于说,如若一个测试工程中涵盖了无数测试方法,平日的景色是三个测试工程中会包涵繁多少个测试类,每种类针对差别的测试用例,而各样测试类中又富含了重重个分化的测试方法。面对那样大幅度的二个测试工程,日常会花上数十分钟以致数钟头技巧将预订好的具备测试方法跑完,大家自然不期待见到由于某2个测试方法败北而导致剩下的有所测试方法均无法获得实践。在自动化测试中,测试方法测试退步的情景是很广阔的,成功或倒闭都以一种结果,那总比程序运维到3/陆抛出格外要好得多。

  1. 率先遍历页面上的Table,将单元格的剧情缓存到字典对象PageTableDataCache中。该字典对象的数量存储结构与地点讲到的Excel数据存款和储蓄结构同样。值得注意的是,在遍历Table的进度中由于是遍历Table上边全体HtmlRow的成团,此处不分包Header部分,因而Table的表底部分的多寡不会被贮存到字典对象中。
    公海赌船网址 16
  2. 经过GetExcelData()方法将Excel中的数据缓存到字典对象ExcelDataCache中。
  3. 加上三个Mapping,用来对页面上的报表和Excel进行映射。为啥需求Mapping?因为页面上表格中单元格的行和列与Excel中的行和列并不总是各种对应的,所以这里不可不要由此Mapping来张开映射,以分明哪些开展比对。Mapping能够是1个XML文件,在先后中通过反体系化的点子张开读取,该操作由个人方法GetMappingRowCollection()完结。上面是Mapping
    XML文件的剧情,有关如何通过Visual
    Studio自动生成XML反连串化的类,能够查阅那篇小说http://www.cnblogs.com/jaxu/p/3632077.html

    <?xml version="1.0" encoding="utf-8" ?>
    <Mapping>
      <MappingRow ExcelRowNum="1" PageTableTrIndex="0">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
      <MappingRow ExcelRowNum="2" PageTableTrIndex="1">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
      <MappingRow ExcelRowNum="3" PageTableTrIndex="2">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
      <MappingRow ExcelRowNum="4" PageTableTrIndex="3">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
      <MappingRow ExcelRowNum="5" PageTableTrIndex="4">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
      <MappingRow ExcelRowNum="6" PageTableTrIndex="5">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
      <MappingRow ExcelRowNum="7" PageTableTrIndex="6">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
      <MappingRow ExcelRowNum="8" PageTableTrIndex="7">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
      <MappingRow ExcelRowNum="9" PageTableTrIndex="8">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
      <MappingRow ExcelRowNum="10" PageTableTrIndex="9">
        <MappingColumn ExcelColumnNum="0" PageTableTdIndex="0"/>
        <MappingColumn ExcelColumnNum="1" PageTableTdIndex="1"/>
        <MappingColumn ExcelColumnNum="2" PageTableTdIndex="2"/>
        <MappingColumn ExcelColumnNum="3" PageTableTdIndex="3"/>
        <MappingColumn ExcelColumnNum="4" PageTableTdIndex="4"/>
      </MappingRow>
    </Mapping>
    

    并且,由于程序中需求读取Excel文件以及反系列化Mapping
    XML文件,要求在App.config文件中加多七个布局项。

    <appSettings>
      <add key="MappingsPath" value="..\..\..\CodedUITestProject2\Mapping.xml"/>
      <add key="ExcelPath" value="c:\Box Office Results.xlsx"/>
    </appSettings>
    

    只顾MappingPath的渠道使用的是相对路线,通过将该公文设置为拷贝到输出路线以福利布署。方法是在Visual
    Studio的Solution Explorer中右键选取该公文->Properties,将Copy to
    Output Directory改成Copy
    always。公海赌船网址 17

  4. 遍历Mapping中全体行和列,并比较PageTable和Excel中的数据,通过Assert断言来获取测试结果。由于Assert断言在测试战败时总会抛出10分而停下余下的测试步骤,能够参照小说http://www.cnblogs.com/jaxu/p/3706652.html中关于Assert断言部分对上述代码实行勘误。

  5. 累加测试方法以调用LaunchPage()和TestTableData()
    [TestMethod]
    public void MyTest()
    {
        UIMap2 uimap = new UIMap2();
        uimap.LaunchPage();
        uimap.TestTableData();
    }
    

  然则,Assert断言总会在测试退步的时候抛出非凡,从而终止程序运营。如上边包车型大巴测试方法,假使前多个断言中有别的三个退步以来,则剩下的断言不会被施行。

  上面包车型客车代码由Visual
Studio自动生成并做了少许修改(将byte类型改为int),用来将Mapping
XML举办反系列化。

[TestMethod]
public void CheckVariousSumResults()
{
    Assert.AreEqual(3, this.Sum(1001, 1, 2));
    Assert.AreEqual(3, this.Sum(1, 1001, 2));
    Assert.AreEqual(3, this.Sum(1, 2, 1001));
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Mapping
{

    private MappingRow[] mappingRowField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("MappingRow")]
    public MappingRow[] MappingRow
    {
        get
        {
            return this.mappingRowField;
        }
        set
        {
            this.mappingRowField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class MappingRow
{

    private MappingColumn[] mappingColumnField;

    private int excelRowNumField;

    private int pageTableTrIndexField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("MappingColumn")]
    public MappingColumn[] MappingColumn
    {
        get
        {
            return this.mappingColumnField;
        }
        set
        {
            this.mappingColumnField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public int ExcelRowNum
    {
        get
        {
            return this.excelRowNumField;
        }
        set
        {
            this.excelRowNumField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public int PageTableTrIndex
    {
        get
        {
            return this.pageTableTrIndexField;
        }
        set
        {
            this.pageTableTrIndexField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class MappingColumn
{

    private int excelColumnNumField;

    private int pageTableTdIndexField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public int ExcelColumnNum
    {
        get
        {
            return this.excelColumnNumField;
        }
        set
        {
            this.excelColumnNumField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public int PageTableTdIndex
    {
        get
        {
            return this.pageTableTdIndexField;
        }
        set
        {
            this.pageTableTdIndexField = value;
        }
    }
}

  贰个使得的消除办法是将每2个预见分别放置不一样的测试方法中,如上面包车型客车代码:

  UIMap二.uitest中的代码完毕了Excel数据与页面Table中的内容比对,并最终通过了测试。不过从严酷意义上来讲,那种景色应该不属于数据驱动测试的局面,数据驱动测试的含义在于通过给定的数码来测试程序已部分效益,而上述意况是由此数据源来比对UI中的内容。可是大家依旧能够从中明白到怎么样编写代码来读取数据源并对Webpage中的表格举行Coded
UI test。

[TestMethod]
public void Sum_1001AsFirstParam_Returns3()
{
    Assert.AreEqual(3, this.Sum(1001, 1, 2));
}
[TestMethod]
public void Sum_1001AsMiddleParam_Returns3()
{
    Assert.AreEqual(3, this.Sum(1, 1001, 2));
}
[TestMethod]
public void Sum_1001AsThirdParam_Returns3()
{
    Assert.AreEqual(3, this.Sum(1, 2, 1001));
}

  但是在当先十分之五景观下那只怕没用。例如你供给测试贰个带有十0行的table,对每一行的title列举办text测试,在那种情状下您根本不恐怕为每3个预知编写分裂的测试方法。首先你无法显明测试方法的多寡,其次过多的测试方法会大增爱抚资产。

  另一种自己听见过的化解措施是行使参数化测试,然则据小编所知,Coded UI
Test中好像并不支持。在其余测试碰到中恐怕有更加好的搞定办法。

  恐怕能够选取try-catch语句来收获Assert断言所抛出的老大,使程序能够持续运维下去。然后大家将有所截获到的要命消息输出到自定义的公文中,即自定义测试报告!测试报告能够是随机档案的次序的文书档案,记事本或HTML比较常用。既然能够利用try-catch来收获Assert断言的分外兴奋,那么我们会很当然地想到利用下边包车型大巴办法:

[TestMethod]
public void CheckVariousSumResults()
{
    MultiAssert.Aggregate(
        () => Assert.AreEqual(3, this.Sum(1001, 1, 2)), 
        () => Assert.AreEqual(3, this.Sum(1, 1001, 2)), 
        () => Assert.AreEqual(3, this.Sum(1, 2, 1001)));
}

public static class MultiAssert
{
    public static void Aggregate(params Action[] actions)
    {
        var exceptions = new List<AssertFailedException>();

        foreach (var action in actions)
        {
            try
            {
                action();
            }
            catch (AssertFailedException ex)
            {
                exceptions.Add(ex);
            }
        }

        var assertionTexts = 
            exceptions.Select(assertFailedException => assertFailedException.Message);
        if (0 != assertionTexts.Count())
        {
            throw new
                AssertFailedException(
                assertionTexts.Aggregate(
                    (aggregatedMessage, next) => aggregatedMessage + Environment.NewLine + next));
        }
    }
}

  上边的代码能够很有效地消除难题,但仍会设非常。MultiAssert.Aggreate()方法中过多的预知最终会将具备的不得了音讯抛出,那会大大降低异常音讯的可读性,不太方便大家从测试测试报告中分析失误的缘由。要领悟,测试方法最后的目的不是要让测试程序运营通过,而是通过测试报告来分析被测试目的大概有所的难题。

  下边是二个例子,能够用来有效地缓和位置建议的主题素材。

public static class AssertWrapper
{
    public static string AreEqual<T>(T expected, T actual, string message)
    {
        string result = null;
        try
        {
            Assert.AreEqual(expected, actual, message);
            TestLog.WritePass(message);
        }
        catch (AssertFailedException ex)
        {
            result = ex.Message;
            TestLog.WriteError(message);
        }
        catch (Exception ex)
        {
            result = ex.Message;
            TestLog.WriteError(message);
        }
        return result;
    }

    public static string AreEqual(string expected, string actual, string message)
    {
        string result = null;
        try
        {
            Assert.AreEqual(expected, actual, message);
            TestLog.WritePass(message);

        }
        catch (AssertFailedException ex)
        {
            result = ex.Message;
            TestLog.WriteError(result);
        }
        catch (Exception ex)
        {
            result = ex.Message;
            TestLog.WriteError(result);
        }
        return result;
    }

    public static string AreEqual(string expected, string actual, bool ignorecase, string message)
    {
        string result = null;
        try
        {
            Assert.AreEqual(expected, actual, ignorecase, message);
            TestLog.WritePass(message);

        }
        catch (AssertFailedException ex)
        {
            result = ex.Message;
            TestLog.WriteError(result);
        }
        catch (Exception ex)
        {
            result = ex.Message;
            TestLog.WriteError(result);
        }
        return result;
    }

    public static string Fail(string message)
    {
        string result = null;
        try
        {
            Assert.Fail(message);
        }
        catch (AssertFailedException ex)
        {
            result = ex.Message;
            TestLog.WriteError(result);
        }
        return result;
    }
}

  AssertWrapper类中的方法能够有三个重载,以满足区别的要求,其主导思维便是运用try-catch语句来收获Assert断言所抛出的不胜。TestLog类中的方法担负写测试报告,你能够将测试报告定义成任何款式。然后定义一个TestSettings类用来搜罗测试工程中有所的测试断言。

public class TestSettings
{
    public static void AddResult(List<string> resultList, string result)
    {
        if (result != null)
        {
            if (resultList == null)
            {
                resultList = new List<string>();
            }
            resultList.Add(result);
        }
    }
}

  在每一个.uitest文件的类中,那样使用方面包车型客车不贰秘籍:

public List<string> faillist;

public void ValidateHeader()
{
    TestSettings.AddResult(faillist,AssertWrapper.AreEqual(true, uIHeader.Exists, "test page: Validate Page header text"));
}

  然后,在具备的测试方法中加多上面的代码(faillist为泛型List对象,被定义为TestMethod所在的类的私家变量,同时我们因而faillist.AddRange(testPage.faillist)语句将测试页面类中的泛型List内容增添过来):

if (faillist != null && faillist.Count > 0)
{
    StringBuilder fail = new StringBuilder();
    foreach (string s in faillist)
    {
        fail.AppendLine(s);
    }
    Assert.Fail(fail.ToString());
}

  那样,可以对该测试方法中带有的富有Assert断言进行合并保管。这样做有多少个好处:

  • 确定保障程序可以不荒谬运营
  • 对每叁个测试方法来讲,个中会包括多少个注解办法,而每三个注脚措施中又会含有有多个Assert断言,使用上述办法能够使得处理全体的断言。
  • 自定义测试报告的格式
  • 能够定义测试方法是透过恐怕战败。退步的测试方法通过Assert.Fail()方法来抛出万分,假使二个测试方法中从不丰富抛出,则会被默以为测试成功,就算事实上测试是失利的。

 

Coded UI Test怎样寻找三个控件?

  在Coded UI
Test中,最广大的主题素材是何等找到被测试的控件。唯有找到被测试的目的,才具选择断言来判定其中的属性是还是不是满意预期的值。大许多动静下,大家都会使用Coded
UI Test
Builder窗口来捕获UI上的控件,但稍事景况下大家只能自行检索须要的控件。三个简短的例子,在列表控件中如何搜索第一个子成分中所包蕴的文本。就像本文一齐头交付的测试需要。假如你通过Coded
UI Test
Builder间接寻觅第3个子成分,当中变化的物色条件往往具有特定性,当页面包车型大巴条件爆发变化,特定的索求条件不自然能找到呼应的控件。

  查看.Designer.cs文件中自动生成的代码,全体控件的概念都会包涵类似于上边代码的探求条件:

HtmlEdit  mUIEmailEdit = new HtmlEdit(someAncestorControl); 
mUIEmailEdit.SearchProperties[HtmlEdit.PropertyNames.Id] = "email"; 
mUIEmailEdit.SearchProperties[HtmlEdit.PropertyNames.Name] = "email"; 
mUIEmailEdit.FilterProperties[HtmlEdit.PropertyNames.LabeledBy] = null; 
mUIEmailEdit.FilterProperties[HtmlEdit.PropertyNames.Type] = "SINGLELINE"; 
mUIEmailEdit.FilterProperties[HtmlEdit.PropertyNames.Title] = null; 
mUIEmailEdit.FilterProperties[HtmlEdit.PropertyNames.Class] = null; 
mUIEmailEdit.FilterProperties[HtmlEdit.PropertyNames.ControlDefinition] = "id=email size=25 name=email"; 
mUIEmailEdit.FilterProperties[HtmlEdit.PropertyNames.TagInstance] = "7";

mUIEmailEdit.Find();

  Coded UI
Test会试图通过具备已知的标准化来搜索钦赐的控件,它利用广度优先查找方法(Breadth-First)。全部SearchProperties能够被视为利用AND条件实行检索,倘使经过SearhProperties找到二个或未找到对应的控件,则具备的FilterProperties条件不会被选拔。固然通过拥有的SearchProperties条件找到两个照料的控件,则尝试每种应用给出的FilterProperties条件实行按序相称(Ordered
match),直到找到匹配的控件。借使经过以上给出的装有规则最终找到多余一个的相称项,则第多少个非凡的因素即为找到的控件。

  在地点给出的事例中,会遵守如下顺遂举行寻觅:

  1. 搜索会从someAncestorControl控件起先,因为它被作为要物色控件的上代。注意祖先并不一定是父节点,它能够是被寻觅控件的放4上级控件。
  2. 每贰次遍历寻觅时,会利用全部已定义的SearchProperties条件进行筛选,就算有三个控件均满意寻觅条件,如X一,X二和X3,此时会一连应用剩下的FilterProperties条件进行筛选。
  3. 对控件X①,X2和X三分别接纳已定义的FilterProperties条件实行筛选,直到相称到唯1的控件,或然持有的FilterProperties条件均比较完成。

  上边包车型地铁流程图表达了那一进程:

公海赌船网址 18

  有某个内需专注:

  1. 对Web controls举行搜寻:SearchProperties和FilterProperties均帮助
  2. 对WinForms和WPF controls实行寻觅:仅SearchProperties扶助

  在Web
controls中,找寻条件的选取大概会提到到浏览器包容性问题。如筛选标准最终要求通过InnerText来明确控件,而该属性在一些浏览器上并不扶助,此时可能引发那一个。在先后编码进程中品尝给一定的控件钦点ID属性能够更加好的减轻这一难题,那就须要与程序开采人士实行中用的联络。从那点也得以阅览,测试驱动开辟的重大。

  不要品味通过GetChildren()方法来遍历全部的控件,因为该办法再次来到结果会非常的慢,尤其是当页面中留存大气控件时。可以选拔临近的先人节点对该控件实行定义(构造函数的参数能够用来内定被搜寻控件的祖辈),然后通过给定SearchProperties或FilterProperties来对控件进行筛选,然后采取FindMatchingControls()方法来规定要搜索的控件。如下边包车型大巴代码用来遍历Table成分从而找到表中全数的<th/>和<td/>:

HtmlTable uITable = this.UIRelWindow.UIRelDocument.UITable;
HtmlRow rowall = new HtmlRow(uITable);

UITestControlCollection rows = rowall.FindMatchingControls();

int rowCount = rows.Count;

for (int i = 0; i < rowCount; i++)
{
    HtmlHeaderCell allTH = new HtmlHeaderCell(rows[i]);
    HtmlCell allTD = new HtmlCell(rows[i]);
    UITestControlCollection THs = allTH.FindMatchingControls();
    UITestControlCollection TDs = allTD.FindMatchingControls();

    ... ...
}

 

代码结构调度

  .uitest文件针对的是每2个测试页面,每一种页面都有单独的辨证措施用来测试页面上各类差异的一对,具有卓越结构的代码能够使全部育项目检验试工程看起来思路清晰。假如有需求,你一点1滴能够应用设计方式来进一步简约地组织工程中的测试方法和类。3个壹体化的测试工程代码结构看起来像那样:

public class TestRunner
{
    public TestRunner()
    {
        homePage = new UI.HomePageClasses.HomePage();
    }


    #region Home page actions and validate method

    private UI.HomePageClasses.HomePage homePage;
    public UI.PageClasses.HomePage HomePage
    {
        get
        {
            if ((this.homePage == null))
            {
                this.homePage = new UI.PageClasses.HomePage();
            }
            return this.homePage;
        }
        set
        {
            homePage = value;
        }
    }

    public void LaunchHomePage()
    {
        HomePage.LaunchHomePage(new System.Uri(TestSettings.GetCurrentSiteURL()));
    }
    public void ValidateHomePageText()
    {
        HomePage.ValidateHomePageText();
    }
}

  使用TestRunner类将工程中持有的证实措施和UI
Actions方法实行李包裹装,然后在测试方法中实行调用。

[TestMethod]
public void IncomeStatementsTest()
{
    testrunner.NavigateToTestPage();
    testrunner.ValidateSomething();
}

[TestInitialize()]
public void MyTestInitialize()
{
    testrunner = new TestRunner();
    testrunner.LaunchHomePage();
}

////Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
    testrunner = null;
}

private TestRunner testrunner;

  忘记说Bellamy(Bellamy)些,带有[CodedUITest]特点属性的类中,大家能够借用MyTestInitialize()方法和MyTestCleanup()方法开始展览一些开始化操作和清理专门的学业。不要在此类的构造函数中丰裕任何代码,通过带有[TestInitialize]特点属性的诀要开始展览开始化专业。一样,带有[TestCleanup]特征属性的不二法门能够用来实香港行政局地清理专业。

  其它,和大大多工程同样,Coded UI
Test工程允许选拔App.config文件。在工程中增添该文件并参预<appSettings></appSettings>节点以设置配置消息。

<configuration>
  <appSettings>
    <add key ="" value=""/>
  </appSettings>
</configuration>

 

怎么运用命令行格局运营测试方法?

  除了在Visual
Studio中运维测试方法外,大家还足以因而任何众多主意来运作测试方法。使用测试代理和测试调节器能够对具有的测试方法进行实用管理,并得以将测试方法分发到分化的测试机上单独举办测试,但须要在服务器上进行布置,MSDN上有相应的牵线,那里关键介绍怎么样通过命令行格局来运维测试方法。

  1. 编写翻译Coded UI Test工程,将转移的.dll文件复制到内定的目录下。
  2. 展开Windows命令行窗口,转到目录c:\Program Files (x86)\Microsoft
    Visual Studio 12.0\Common7\IDE
    照旧直接张开Developer Command Prompt for VS二零一二
  3. 运用如下命令行实施测试方法

    MSTest /testcontainer:CodedUITestProject2.dll /test:CodedUITest1.CodedUITestMethod1

  msdn.aspx)上有对MSTest.exe命令行全体参数的申明。有几点要求证实一下:

  • /testcontainer中有不可或缺钦定.dll文件的门道名称
  • /test用来钦定.dll文件中所包涵的测试方法的姓名称。注意那里的全名称包蕴了测试方法所在的类名以及艺术名,类必须包罗[CodedUITest]特点属性,测试方法必须带有[TestMethod]特色属性。

  如若您想分发你的测试工程在任何机器上运维,可以编写.bat文件并将Coded
UI
Test工程生成的.dll文件放到同一文件夹下。.bat文件的内容看起来像上边那样:

@echo off

@set PATH=c:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE;%PATH%

echo ****** This program will start a Coded UI Test Method ******
pause

MSTest /testcontainer:CodedUITest1.dll /test:CodedUITest1.CodedUITestMethod1

echo ****** End Coded UI Test Method ********


pause

 

相关文章