CS客户端单元测试(1) 开始

通过一段时间的B/S后台工作,一定程度上熟悉的单元测试的编写,另外,实际感受到了单元测试的作用。

现在考虑将单元测试应用到C/S客户端上,以保障客户端的长期稳定性。

客户端测试分为两种:服务端协议测试,客户端界面功能测试。协议测试比较简单,就是和服务端通信,测试通信,测试通信结果是否正确;界面测试则比较复杂。

    一、服务端协议测试。

        项目类型:Unit Test Project

        测试流程:


    二、客户端界面功能测试。

        项目类型:Coded UI Test Project(.Net Framework4.0以上支持)

        测试流程:


输出目录:

AppDomain.CurrentDomain.BaseDirectory=D:\SoftwareProjects\TrunkClient2017\TestResults\caiwanwei_DESKTOP-CLV0P90 2018-03-28 14_32_56\Out

项目的目录是:D:\SoftwareProjects\TrunkClient2017 2\Test\Framework.CodedUITest

也就是说,每次测试程序运行都会生成一个输出目录,用当前[用户名_主机名 时间]格式命名。


用Process.Start运行客户端碰到的问题:

    1.注册码文件路径问题

        Environment.CurrentDirectory不是运行的Exe的路径,不能用,要改为AppDomain.CurrentDomain.BaseDirectory

    2.WPF图片路径问题

        在代码中设置的商标图片路径改为UriKind.Absolute

        ImageLogo.ImageSource = new BitmapImage(new Uri("Images\\Login\\" + name, UriKind.Relative));

        改成:

 ImageLogo.ImageSource = new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory + "\\Images\\Login\\" + name, UriKind.Absolute));

实际测试过程:

       新建Coded UI Test Project的时候会自动创建一个CodedUITest1

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Input;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;


namespace Framework.CodedUITest
{
    /// <summary>
    /// Summary description for CodedUITest1
    /// </summary>
    [CodedUITest]
    public class CodedUITest1
    {
        public CodedUITest1()
        {
        }

        [TestMethod]
        public void CodedUITestMethod1()
        {
            // To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
        }

        #region Additional test attributes

        // You can use the following additional attributes as you write your tests:

        Use TestInitialize to run code before running each test 
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{        
        //    // To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
        //}

        Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{        
        //    // To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
        //}

        #endregion

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }
        private TestContext testContextInstance;
    }
}

并打开一个录制的工具栏

OK=>

    这个界面关闭后想打开可以通过Test菜单打开

    

    注意要将编辑光标放在一个[TestMethod]函数中,不然会提示:

    

    录制结果就是插入到这个光标的地方。

按钮功能分别是:开始录制/停止录制,查看录制的步骤,添加控制,生成代码。

0.手动启动服务端。

1.手动打开客户端。


2.点击开始录制。

3.在客户端界面上做一些操作:设置参数,点击登录,退出客户端。

    注意:因为客户端是用管理员权限启动的,测试时VS也要用管理员权限启动,不然无权操作客户端程序。

    我是在开始菜单操作的,右键VS程序,选择以管理员身份运行。

    

    不然会出现错误:

    

4.暂停录制,查看一下录制的步骤,没问题的话就生成代码。

5.点击生成代码。


把名称改为LoginUserError

6.查看生成的代码(或者回到第2步继续录制新的操作)

CodedUITest1里面就多了个测试函数

        [TestMethod]
        public void CodedUITestMethod1()
        {
            // To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
            this.UIMap.LoginUserError();
        }

继续录制新的操作生成的新代码会还是添加在CodedUITestMethod1中,刚刚的LoginSucess后面,并不会生成一个新的测试函数。

    双击UIMap.uitest文件(要先关闭录制窗口)。

    

UIMap的代码

[GeneratedCode("Coded UITest Builder", "14.0.23107.0")]
    public partial class UIMap
    {
        
        /// <summary>
        /// LoginUserError - Use 'LoginUserErrorParams' to pass parameters into this method.
        /// </summary>
        public void LoginUserError()
        {
            #region Variable Declarations
            WpfComboBox uIIPComboBox = this.UI用户登录Window.UIIPComboBox;
            WpfEdit uIPART_EditableTextBoxEdit = this.UI用户登录Window.UIIPComboBox.UIPART_EditableTextBoxEdit;
            WpfEdit uIPortEdit = this.UI用户登录Window.UIPortEdit;
            WpfComboBox uIUserComboBox = this.UI用户登录Window.UIUserComboBox;
            WpfEdit uIPasswordEdit = this.UI用户登录Window.UIPasswordEdit;
            WpfCheckBox uI记住密码CheckBox = this.UI用户登录Window.UI记住密码CheckBox;
            WpfButton uI登录Button = this.UI用户登录Window.UI登录Button;
            WpfButton uI确定Button = this.UI提示Window.UI确定Button;
            #endregion

            // Select '127.0.0.1' in 'IP' combo box
            uIIPComboBox.EditableItem = this.LoginUserErrorParams.UIIPComboBoxEditableItem;

            // Type '{Tab}' in 'PART_EditableTextBox' text box
            Keyboard.SendKeys(uIPART_EditableTextBoxEdit, this.LoginUserErrorParams.UIPART_EditableTextBoxEditSendKeys, ModifierKeys.None);

            // Type '60005' in 'Port' text box
            uIPortEdit.Text = this.LoginUserErrorParams.UIPortEditText;

            // Select 'admin2' in 'User' combo box
            uIUserComboBox.EditableItem = this.LoginUserErrorParams.UIUserComboBoxEditableItem;

            // Move 'Password' text box
            Mouse.StartDragging(uIPasswordEdit, new Point(54, 13));
            Mouse.StopDragging(uIPasswordEdit, -49, 2);

            // Type '********' in 'Password' text box
            Keyboard.SendKeys(uIPasswordEdit, this.LoginUserErrorParams.UIPasswordEditSendKeys, true);

            // Select '记住密码' check box
            uI记住密码CheckBox.Checked = this.LoginUserErrorParams.UI记住密码CheckBoxChecked;

            // Click '登录' button
            Mouse.Click(uI登录Button, new Point(72, 19));

            // Click '确定' button
            Mouse.Click(uI确定Button, new Point(38, 24));
        }
        
        /// <summary>
        /// LoginPortError - Use 'LoginPortErrorParams' to pass parameters into this method.
        /// </summary>
        public void LoginPortError()
        {
            #region Variable Declarations
            WpfComboBox uIIPComboBox = this.UI用户登录Window.UIIPComboBox;
            WpfEdit uIPortEdit = this.UI用户登录Window.UIPortEdit;
            WpfComboBox uIUserComboBox = this.UI用户登录Window.UIUserComboBox;
            WpfEdit uIPART_EditableTextBoxEdit = this.UI用户登录Window.UIUserComboBox.UIPART_EditableTextBoxEdit;
            WpfEdit uIPasswordEdit = this.UI用户登录Window.UIPasswordEdit;
            WpfCheckBox uI记住密码CheckBox = this.UI用户登录Window.UI记住密码CheckBox;
            WpfButton uI登录Button = this.UI用户登录Window.UI登录Button;
            WpfButton uI确定Button = this.UI提示Window.UI确定Button;
            #endregion

            // Select '127.0.0.1' in 'IP' combo box
            uIIPComboBox.EditableItem = this.LoginPortErrorParams.UIIPComboBoxEditableItem;

            // Type '60001' in 'Port' text box
            uIPortEdit.Text = this.LoginPortErrorParams.UIPortEditText;

            // Select 'admin' in 'User' combo box
            uIUserComboBox.EditableItem = this.LoginPortErrorParams.UIUserComboBoxEditableItem;

            // Type '{Tab}' in 'PART_EditableTextBox' text box
            Keyboard.SendKeys(uIPART_EditableTextBoxEdit, this.LoginPortErrorParams.UIPART_EditableTextBoxEditSendKeys, ModifierKeys.None);

            // Type '********' in 'Password' text box
            Keyboard.SendKeys(uIPasswordEdit, this.LoginPortErrorParams.UIPasswordEditSendKeys, ModifierKeys.Control, true);

            // Type '********' in 'Password' text box
            Keyboard.SendKeys(uIPasswordEdit, this.LoginPortErrorParams.UIPasswordEditSendKeys1, true);

            // Select '记住密码' check box
            uI记住密码CheckBox.Checked = this.LoginPortErrorParams.UI记住密码CheckBoxChecked;

            // Click '登录' button
            Mouse.Click(uI登录Button, new Point(82, 26));

            // Click '确定' button
            Mouse.Click(uI确定Button, new Point(34, 15));
        }
        
        #region Properties
        public virtual LoginUserErrorParams LoginUserErrorParams
        {
            get
            {
                if ((this.mLoginUserErrorParams == null))
                {
                    this.mLoginUserErrorParams = new LoginUserErrorParams();
                }
                return this.mLoginUserErrorParams;
            }
        }
        
        public virtual LoginPortErrorParams LoginPortErrorParams
        {
            get
            {
                if ((this.mLoginPortErrorParams == null))
                {
                    this.mLoginPortErrorParams = new LoginPortErrorParams();
                }
                return this.mLoginPortErrorParams;
            }
        }
        
        public UI用户登录Window UI用户登录Window
        {
            get
            {
                if ((this.mUI用户登录Window == null))
                {
                    this.mUI用户登录Window = new UI用户登录Window();
                }
                return this.mUI用户登录Window;
            }
        }
        
        public UI提示Window UI提示Window
        {
            get
            {
                if ((this.mUI提示Window == null))
                {
                    this.mUI提示Window = new UI提示Window();
                }
                return this.mUI提示Window;
            }
        }
        #endregion
        
        #region Fields
        private LoginUserErrorParams mLoginUserErrorParams;
        
        private LoginPortErrorParams mLoginPortErrorParams;
        
        private UI用户登录Window mUI用户登录Window;
        
        private UI提示Window mUI提示Window;
        #endregion
    }
后面熟练了应该是可以考虑手动写这些代码的吧。

7.在VS中运行测试用例。

结果就是将刚刚手动的操作自动执行了一遍,没问题,就算测试成功了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值