通过一段时间的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 DeclarationsWpfComboBox 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 boxuIIPComboBox.EditableItem = this.LoginUserErrorParams.UIIPComboBoxEditableItem;// Type '{Tab}' in 'PART_EditableTextBox' text boxKeyboard.SendKeys(uIPART_EditableTextBoxEdit, this.LoginUserErrorParams.UIPART_EditableTextBoxEditSendKeys, ModifierKeys.None);// Type '60005' in 'Port' text boxuIPortEdit.Text = this.LoginUserErrorParams.UIPortEditText;// Select 'admin2' in 'User' combo boxuIUserComboBox.EditableItem = this.LoginUserErrorParams.UIUserComboBoxEditableItem;// Move 'Password' text boxMouse.StartDragging(uIPasswordEdit, new Point(54, 13));Mouse.StopDragging(uIPasswordEdit, -49, 2);// Type '********' in 'Password' text boxKeyboard.SendKeys(uIPasswordEdit, this.LoginUserErrorParams.UIPasswordEditSendKeys, true);// Select '记住密码' check boxuI记住密码CheckBox.Checked = this.LoginUserErrorParams.UI记住密码CheckBoxChecked;// Click '登录' buttonMouse.Click(uI登录Button, new Point(72, 19));// Click '确定' buttonMouse.Click(uI确定Button, new Point(38, 24));}/// <summary>/// LoginPortError - Use 'LoginPortErrorParams' to pass parameters into this method./// </summary>public void LoginPortError(){#region Variable DeclarationsWpfComboBox 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 boxuIIPComboBox.EditableItem = this.LoginPortErrorParams.UIIPComboBoxEditableItem;// Type '60001' in 'Port' text boxuIPortEdit.Text = this.LoginPortErrorParams.UIPortEditText;// Select 'admin' in 'User' combo boxuIUserComboBox.EditableItem = this.LoginPortErrorParams.UIUserComboBoxEditableItem;// Type '{Tab}' in 'PART_EditableTextBox' text boxKeyboard.SendKeys(uIPART_EditableTextBoxEdit, this.LoginPortErrorParams.UIPART_EditableTextBoxEditSendKeys, ModifierKeys.None);// Type '********' in 'Password' text boxKeyboard.SendKeys(uIPasswordEdit, this.LoginPortErrorParams.UIPasswordEditSendKeys, ModifierKeys.Control, true);// Type '********' in 'Password' text boxKeyboard.SendKeys(uIPasswordEdit, this.LoginPortErrorParams.UIPasswordEditSendKeys1, true);// Select '记住密码' check boxuI记住密码CheckBox.Checked = this.LoginPortErrorParams.UI记住密码CheckBoxChecked;// Click '登录' buttonMouse.Click(uI登录Button, new Point(82, 26));// Click '确定' buttonMouse.Click(uI确定Button, new Point(34, 15));}#region Propertiespublic 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 Fieldsprivate LoginUserErrorParams mLoginUserErrorParams;private LoginPortErrorParams mLoginPortErrorParams;private UI用户登录Window mUI用户登录Window;private UI提示Window mUI提示Window;#endregion}

后面熟练了应该是可以考虑手动写这些代码的吧。

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

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

CS客户端单元测试(1) 开始相关推荐

  1. 如何给影像添加投影_如何在EasyEarth Desktop(CS客户端)进行影像处理

    EasyEarth 三维可视化地理信息云平台是一款完全依托于自主研发的三维 GIS 技术应用平台,以数据管理为核心,以三维可视化应用为特点,围绕影像.地形.矢量.传统三维模型数据.实景三维模型数据.点 ...

  2. cs客户端 实时权限_【CS学习笔记】7、SMBbean的作用

    0x00 SMB Beacon 简介 SMB Beacon 使用命名管道通过一个父 Beacon 进行通信.这种对等通信对同一台主机上的 Beacon 和跨网络的 Beacon 都有效.Windows ...

  3. Easy Connect无法连接的情况,当前IE代理启用了自动配置脚本,不允许使用CS客户端登录

    这是王秀秀的第16篇博客 Easy Connect无法连接的情况,当前IE代理启用了自动配置脚本,不允许使用CS客户端登录 由于最近需要访问校园网,所以需要使用easy connect 进行连接.可是 ...

  4. CS 客户端不引用AE

    cs版,在服务端引用AE的各个reference. USL层传入参数,server端分析出结果,然后以DataTable, 数组.或者类的方式方法.返回载体不要包含AE的类型. 这样,客户端不用安装A ...

  5. cs客户端接收网页传来的数据_3.爬取数据-urllib库

    1. 小试牛刀 怎样扒网页呢? 其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS.CSS,如果把 ...

  6. CS客户端登入CAS(单点登入)方案

    最初的方案将各个连在CAS的上的应用配置成代理模式,当CS端要调用这些应用时向应用发送一个一次性票据(ticket)!后来发现这个方案有个缺陷,就是被调用的应用无法调用其它应用,原因是CS端登入时没有 ...

  7. Java 在CS客户端做网页连接

    bottomTitle = new JLabel("努力工作,认真学习--我是antkingwei"); bottomTitle.setForeground(Color.blue) ...

  8. 咏南CS插件开发框架也可BS方式部署

    在几分钟的时间内,CS客户端也可以BS方式部署.

  9. CS架构和BS架构的发展趋势即在图像处理软件中的应用

    趋势:总体来讲有融合的趋势,你中有我,我中有你.前后端分离的技术大行其道,前端更像是把原来桌面上的工作搬到浏览器中实现. websocket能像桌面一样工作: javascript的语法增加了clas ...

  10. 漏洞payload 靶机_【CS学习笔记】5、如何建立Payload处理器

    这一小节学起来感觉有些吃力,里面很多概念理解的不是很清楚,如果有大佬看到描述错误的地方欢迎留言指正,避免误导他人. 再次声明,这只是我的个人学习笔记,不要当成教程去看,建议想学习CS的小伙伴可以看看A ...

最新文章

  1. 网络通信模型(IO模型)
  2. 【Crash Course Psychology】1. Intro to psychology笔记
  3. ListT 排序学习
  4. 内部类的分类及其定义
  5. 构建高性能服务(三)Java高性能缓冲设计 vs Disruptor vs LinkedBlockingQueue--转载
  6. matlab/simulink常见问题汇总
  7. java native code_原生代码(native code)
  8. python 爬网页 发布wordpress 包含图片_使用python批量插入wordpress-从理清表结构开始...
  9. 一体化点焊机将要取代分体式焊钳在汽车制造生产线上的使用
  10. 计算机网址登录教程,melogincn电脑登录教程
  11. stat在python中_stat模块接口
  12. linux多进程介绍和示例
  13. CountDownLatch和Semaphore使用场景
  14. Xen Server 7.0 一直无法退出维护模式
  15. 第15条:使可变性最小化
  16. 毕设题目:Matlab答题卡识别
  17. 非线性相关系数 matlab,matlab多元非线性回归系数的确定
  18. c#窗体应用程序:100以内的素数,每8个数为一行
  19. HBase技术与应用实践 | HBase2.0重新定义小对象实时存取
  20. HTTP之URL详解

热门文章

  1. Android本地默认IP
  2. gazebo构建仿真场景并制作机器人模型
  3. android百度输入法切换,百度输入法输入模式怎么切换 快速一键切换输入法模式方法教程...
  4. java环境变量配置_Java环境变量配置终极版
  5. python获取北京时间
  6. 聚类——谱聚类算法以及Python实现
  7. APP推广渠道下载量统计方案
  8. python中的pika模块
  9. 2021-09-09md
  10. 电子警察的系统结构和功能设计