Dev环境中的集成测试用例执行时上下文环境检查(实战)
Dev环境中的集成测试用例执行时上下文环境检查(实战)
Microsoft.NET 解决方案,项目开发必知必会。
从这篇文章开始我将分享一系列我认为在实际工作中很有必要的一些.NET项目开发的核心技术点,所以我称为必知必会。尽管这一系列是使用.NET/C#来展现,但是同样适用于其他类似的OO技术平台,这些技术点可能称不上完整的技术,但是它是经验的总结,是掉过多少坑之后的觉醒,所以有必要花几分钟时间记住它,在真实的项目开发中你就知道是多么的有帮助。好了,废话不说了,进入主题。
我们在开发服务时为了调试方便会在本地进行一个基本的模块测试,你也可以认为是集成测试,只不过你的测试用例不会覆盖到80%以上,而是一些我们认为在开发时不是很放心的点才会编写适当的用例来测试它。
集成测试用例通常有多个执行上下文,对于我们开发人员来说我们的执行上下文通常都在本地,测试人员的上下文在测试环境中。开发人员的测试用来是不能够连接到其他环境中去的(当然视具体情况而定,有些用例很危险是不能够乱连接的,本文会讲如何解决),开发人员运行的集成测试用例所要访问的所有资源、服务都是在开发环境中的。这里依然存在但是,但是为了调试方便,我们还是需要能够在必要的时候连接到其他环境中去调试问题,为了能够真实的模拟出问题的环境、可真实的数据,我们需要能有一个这样的机制,在需要的时候我能够打开某个设置让其能够切换集成测试运行的环境上下文,其实说白了就是你所要连接的环境、数据源的连接地址。
本篇文章我们将通过一个简单的实例来了解如何简单的处理这中情况,这其实基于对测试用来不断重构后的效果。

1 using System;
2 using Microsoft.VisualStudio.TestTools.UnitTesting;
3
4 namespace OrderManager.Test
5 {
6 using ProductService.Contract;
7
8 /// <summary>
9 /// Product service integration tests.
10 /// </summary>
11 [TestClass]
12 public class ProductServiceIntegrationTest
13 {
14 /// <summary>
15 /// service address.
16 /// </summary>
17 public const string ServiceAddress = "http://dev.service.ProductService/";
18
19 /// <summary>
20 /// Product service get product by pid test.
21 /// </summary>
22 [TestMethod]
23 public void ProductService_GetProductByPid_Test()
24 {
25 var serviceInstance = ProductServiceClient.CreateClient(ServiceAddress);
26 var testResult = serviceInstance.GetProductByPid(0393844);
27
28 Assert.AreNotEqual(testResult, null);
29 Assert.AreEqual(testResult.Pid, 0393844);
30 }
31 }
32 }

这是一个实际的集成测试用例代码,有一个当前测试类共用的服务地址,这个地址是DEV环境的,当然你也可以定义其他几个环境的服务地址,前提是环境是允许你连接的,那才有实际意义。
我们来看测试用例,它是一个查询方法测试用例,用来对ProductServiceClient.GetProductByPid服务方法进行测试,由于面向查询的操作是等幕的,不论我们查询多少次这个ID的Product,都不会对数据造成影响,但是如果我们测试的是一个更新或者删除就会带来问题。
在DEV环境中,测试更新、删除用例没有问题,但是如果你的机器是能够连接到远程某个生产或者PRD测试上时会带来一定的危险性,特别是在忙的时候,加班加点的干进度,你很难记住你当前的机器的host配置中是否还连接着远程的生产机器上,或者根本就不需要配置host就能够连接到某个你不应该连接的环境上。
这是目前的问题,那么我们如何解决这个问题呢 ,我们通过对测试代码进行一个简单的重构就可以避免由于连接到不该连接的环境中运行危险的测试用例。
其实很多时候,重构真的能够帮助我们找到出口,就好比俗话说的:"出口就在转角处“,只有不断重构才能够逐渐的保证项目的质量,而这种效果是很难得的。
提取抽象基类,对测试要访问的环境进行明确的定义。

1 namespace OrderManager.Test
2 {
3 public abstract class ProductServiceIntegrationBase
4 {
5 /// <summary>
6 /// service address.
7 /// </summary>
8 protected const string ServiceAddressForDev = "http://dev.service.ProductService/";
9
10 /// <summary>
11 /// service address.
12 /// </summary>
13 protected const string ServiceAddressForPrd = "http://Prd.service.ProductService/";
14
15 /// <summary>
16 /// service address.
17 /// </summary>
18 protected const string ServiceAddressTest = "http://Test.service.ProductService/";
19 }
20 }

对具体的测试类消除重复代码,加入统一的构造方法。

1 using System;
2 using Microsoft.VisualStudio.TestTools.UnitTesting;
3
4 namespace OrderManager.Test
5 {
6 using ProductService.Contract;
7
8 /// <summary>
9 /// Product service integration tests.
10 /// </summary>
11 [TestClass]
12 public class ProductServiceIntegrationTest : ProductServiceIntegrationBase
13 {
14 /// <summary>
15 /// product service client.
16 /// </summary>
17 private ProductServiceClient serviceInstance;
18
19 /// <summary>
20 /// Initialization test instance.
21 /// </summary>
22 [TestInitialize]
23 public void InitTestInstance()
24 {
25 serviceInstance = ProductServiceClient.CreateClient(ServiceAddressForDev/*for dev*/);
26 }
27
28 /// <summary>
29 /// Product service get product by pid test.
30 /// </summary>
31 [TestMethod]
32 public void ProductService_GetProductByPid_Test()
33 {
34 var testResult = serviceInstance.GetProductByPid(0393844);
35
36 Assert.AreNotEqual(testResult, null);
37 Assert.AreEqual(testResult.Pid, 0393844);
38 }
39
40 /// <summary>
41 /// Product service delete search index test.
42 /// </summary>
43 [TestMethod]
44 public void ProductService_DeleteProductSearchIndex_Test()
45 {
46 var testResult = serviceInstance.DeleteProductSearchIndex();
47
48 Assert.IsTrue(testResult);
49 }
50 }
51 }

消除重复代码后,我们需要加入对具体测试用例检查是否能够连接到某个环境中去。我加入了一个DeleteProductSearchIndex测试用例,该用例是用来测试删除搜索索引的,这个测试用例只能够在本地DEV环境中运行(你可能觉得这个删除接口不应该放在这个服务里,这里只是举一个例子,无需纠结)。
为了能够有一个检查机制能提醒开发人员你目前连接的地址是哪一个,我们需要借助于测试上下文。
重构后,我们看一下现在的测试代码结构。

1 using System;
2 using Microsoft.VisualStudio.TestTools.UnitTesting;
3
4 namespace OrderManager.Test
5 {
6 using ProductService.Contract;
7
8 /// <summary>
9 /// Product service integration tests.
10 /// </summary>
11 [TestClass]
12 public class ProductServiceIntegrationTest : ProductServiceIntegrationBase
13 {
14 /// <summary>
15 /// product service client.
16 /// </summary>
17 private ProductServiceClient serviceInstance;
18
19 /// <summary>
20 /// Initialization test instance.
21 /// </summary>
22 [TestInitialize]
23 public void InitTestInstance()
24 {
25 serviceInstance = ProductServiceClient.CreateClient(ServiceAddressForPrd/*for dev*/);
26
27 this.CheckCurrentTestCaseIsRun(this.serviceInstance);//check current test case .
28 }
29
30 /// <summary>
31 /// Product service get product by pid test.
32 /// </summary>
33 [TestMethod]
34 public void ProductService_GetProductByPid_Test()
35 {
36 var testResult = serviceInstance.GetProductByPid(0393844);
37
38 Assert.AreNotEqual(testResult, null);
39 Assert.AreEqual(testResult.Pid, 0393844);
40 }
41
42 /// <summary>
43 /// Product service delete search index test.
44 /// </summary>
45 [TestMethod]
46 public void ProductService_DeleteProductSearchIndex_Test()
47 {
48 var testResult = serviceInstance.DeleteProductSearchIndex();
49
50 Assert.IsTrue(testResult);
51 }
52 }
53 }

我们加入了一个很重要的测试实例运行时方法InitTestInstance,该方法会在测试用例每次实例化时先执行,在方法内部有一个用来检查当前测试用例运行的环境
this.CheckCurrentTestCaseIsRun(this.serviceInstance);//check current test case .,我们转到基类中。

1 using System;
2 using Microsoft.VisualStudio.TestTools.UnitTesting;
3
4 namespace OrderManager.Test
5 {
6 public abstract class ProductServiceIntegrationBase
7 {
8 /// <summary>
9 /// service address.
10 /// </summary>
11 protected const string ServiceAddressForDev = "http://dev.service.ProductService/";
12
13 /// <summary>
14 /// get service address.
15 /// </summary>
16 protected const string ServiceAddressForPrd = "http://Prd.service.ProductService/";
17
18 /// <summary>
19 /// service address.
20 /// </summary>
21 protected const string ServiceAddressTest = "http://Test.service.ProductService/";
22
23 /// <summary>
24 /// Test context .
25 /// </summary>
26 public TestContext TestContext { get; set; }
27
28 /// <summary>
29 /// is check is run for current test case.
30 /// </summary>
31 protected void CheckCurrentTestCaseIsRun(ProductService.Contract.ProductServiceClient testObject)
32 {
33 if (testObject.ServiceAddress.Equals(ServiceAddressForPrd))// Prd 环境,需要小心检查
34 {
35 if (this.TestContext.TestName.Equals("ProductService_DeleteProductSearchIndex_Test"))
36 Assert.IsTrue(false, "当前测试用例连接的环境为PRD,请停止当前用例的运行。");
37 }
38 else if (testObject.ServiceAddress.Equals(ServiceAddressTest))//Test 环境,检查约定几个用例
39 {
40 if (this.TestContext.TestName.Equals("ProductService_DeleteProductSearchIndex_Test"))
41 Assert.IsTrue(false, "当前测试用例连接的环境为TEST,为了不破坏TEST环境,请停止用例的运行。");
42 }
43 }
44 }
45 }

在检查方法中我们使用简单的判断某个用例不能够在PRD、TEST环境下执行,虽然判断有点简单,但是在真实的项目中足够了,简单有时候是一种设计思想。我们运行所有的测试用例,查看各个状态。

一目了然,更为重要的是它不会影响你对其他用例的执行。当你在深夜12点排查问题的时候,你很难控制自己的眼花、体虚导致的用例执行错误带来的大问题,甚至是无法挽回的的错误。
此文献给那些跟我一样的.NET程序员们,通过简单的重构,我们解放了自己。
Dev环境中的集成测试用例执行时上下文环境检查(实战)的更多相关文章
- .NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上下文环境检查(实战)
Microsoft.NET 解决方案,项目开发必知必会. 从这篇文章开始我将分享一系列我认为在实际工作中很有必要的一些.NET项目开发的核心技术点,所以我称为必知必会.尽管这一系列是使用.NET/C# ...
- linux环境中安装NRPE插件执行远程"本地资源"检查?NRPE安装?
需求描述: 在安装完nagios之后,需要对本地资源进行监控,比如磁盘空间的使用,进程数,swap空间,等等.这些都不是通过网络提供出来的, 所以,都是本地资源,可以通过NRPE插件实现在客户端中采集 ...
- Crontab 执行时没有环境变量!
Crontab 执行时没有环境变量! Crontab 执行时没有环境变量! Crontab 执行时没有环境变量! 重要的事情说三遍,浪费我半天时间去找问题!! 非系统默认工具,执行时候需要加全路径!!
- js中当call或者apply传入的第一个参数是null/undefined时,js函数内执行的上下文环境是什么?
在js中我们都知道call/apply,还有比较少用的bind;传入的第一个参数都是改变函数当前上下文对象; call/apply区别在于传的参数不同,一个是已逗号分隔字符串,一个以数组形式.而bin ...
- 关于开发环境中的消息在download时没有下载下来时的问题
业务场景:在开发环境改了一些代码,现在需要将这些代码(包括class和数据库对象)移植到开发环境,整理出了Objectlist(就是该模块定义了哪些数据库对象),然后上传到FTP服务器上时,再执行do ...
- 在win10环境中安装xilinx vivado IDE时出现的问题及解决方法
1.问题:There is no valid Xilinx installation that this Update can be applied to. 解决方法一:下载的是更新包,如果设备没有预 ...
- JavaScript 上下文环境和作用域,以及 call、apply 和 bind【转载+翻译+整理】
--看到这篇文章,翻译国外的,虽说写得有点矫情,但总体来看,还是相当不错的- 本文内容 我在哪儿?你又是谁 ? this? 用 apply 和 call 掌控上下文环境 bind 之美 本文将说明上下 ...
- 敏捷:你能区分DevOps中的“集成、部署、交付、上线、发布”吗?
在DevOps中,你可能经常会听到类似这样的一些话: 功能还没集成进来. 功能还没部署上去. 功能还没交付. 功能还没上线. 功能还没发布. 请问,以上“集成”.“部署”. “交付”.“上线”.“发布 ...
- 在 SharePoint Server 2016 本地环境中设置 OneDrive for Business
建议补丁 建议在sharepoint2016打上KB3127940补丁,补丁下载地址 https://support.microsoft.com/zh-cn/kb/3127940 当然不打,也可以用O ...
随机推荐
- 关于TCP/IP协议栈(转)
1. TCP/IP协议栈 与OSI参考模型不同,TCP/IP协议栈共有4层,其中网络接口层对应OSI中的物理层和数据链路层,应用层对应OSI中的应用层.表示层和会话层. 在网络接口层的主要协议有:AR ...
- JavaEE(24) - JAAS开发安全的应用
1. 安全域.角色和用户组 容器提供的两种安全性控制:声明式安全控制和编程式安全控制 安全域是指用户.用户组和ACL的逻辑集合.服务器支持的两种常用安全域:RDBMS安全域和文件系统安全域. 2. J ...
- WIN8 、WIN7 下IIS7.5、IIS8 的rewrite 伪静态功能设置方法
原文 WIN8 .WIN7 下IIS7.5.IIS8 的rewrite 伪静态功能设置方法 win7和win8系统都自带有iis的功能.关于IIS的安装,上一篇已经讲述,这里就不重复了. 下面说下在w ...
- 离robots.txt启动网络爬虫之旅
要成为一个网络爬虫或搜索引擎(在这里,共同蜘蛛)它不会陌生,在搜索引擎爬虫的第一个文件或者访问该网站上浏览robots.txt该.robots.txt文件讲述了蜘蛛server哪些文件要观看正在. 当 ...
- hdu 4407 Sum 容斥+当前离线
乞讨X-Y之间p素数,,典型的纳入和排除问题,列的求和运算总和的数,注意,第一项是最后一个项目数. 如果不改变到第一记录的答案,脱机处理,能保存查询,候,遇到一个操作1,就遍历前面的操作.把改动加上去 ...
- 注解配置的Spring MVC
基于注解配置的Spring MVC 简单的HelloWorld实例应用 2.1 问题 使用注解的方式重构helloworld应用案例. 2.2 方案 1. @RequestMapping注解应用 ...
- 使用Hadoop的MapReduce与HDFS处理数据
hadoop是一个分布式的基础架构,利用分布式实现高效的计算与储存,最核心的设计在于HDFS与MapReduce,HDFS提供了大量数据的存储,mapReduce提供了大量数据计算的实现,通过Java ...
- IOS View传统的价值观之间
1.采用NSUserDefaults通过值,这样的方法不限于传送少量数据的: 比方你要传一个float的值.在须要传的时候用 [[NSUserDefaults standardUserDefaults ...
- 乘法逆元...Orz
最近打的几场比赛,都出现了有关逆元的题目,今天就整理了一下... 求乘法逆元的几种方法:http://www.cnblogs.com/james47/p/3871782.html 博文转载链接:htt ...
- PHP图片等比缩放,并添加Logo水印特定代码和盯
<? php //PHP图片等比缩放,并添加Logo水印 --->百度 "美日汇" /** * 等比缩放函数(以保存的方式实现) * @param string $pi ...