.net core实践系列之短信服务-Api的SDK的实现与测试

前言

上一篇《.net core实践系列之短信服务-Sikiro.SMS.Api服务的实现》讲解了API的设计与实现,本篇主要讲解编写接口的SDK编写还有API的测试。

或许有些人会认为,SDK的编写可以不需要,既然已经用了RESTful web服务与Swagger提供的接口描述,只要选择合适的接口调用框架,找到对应Swagger文档按需调用即可。

这个我赞同,特别在微服务架构下使用了API网关与服务发现。因此本篇也是借用编写SDK来模拟在客户端使用接口框架调用,并增加负载测试的讲解,供需要的朋友们分享。

项目源码地址:https://github.com/SkyChenSky/Sikiro.SMS.git

SDK

Software Development Kit的缩写,翻译中文为软件开发工具包,百度定义为软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等创建应用软件的开发工具的集合。而我们这里的SDK主要是以工具库的形式提供给部门内部使用API。

设计要点

  • 尽量少的依赖
  • 多形式方法重载
  • 高可读性

从上三点得出,高可读的方法注释,方便使用的多重载(单条、多条、异步、同步),如涉及到枚举,不要依赖原有项目的其他库,应拷贝过来完整提供。

组件选择

  • RestSharp
  • .Net Standard

RestSharp

为了良好的调用RESTful API,我选择RestSharp这个RESTful接口调用框架。

源码地址:https://github.com/restsharp/RestSharp

优点

请求调用与响应结果的直观化:

步骤:

  • 传入资源
  • 定义动作
  • 设置表述类型
  • 传入实体参数

注意点

1.默认序列化类型为XML,应手动设置为JSON

RequestFormat = DataFormat.Json 

2.反序列化有缺陷,对于实体内的类类型属性(List<T>、自定义类等),应再构造函数初始化赋默认值

 public class SearchResponse
    {
        public SearchResponse()
        {
            Mobiles = new List<string>();
        }

        public string Content { get; set; }
        public int Type { get; set; }
        public int Status { get; set; }
        public List<string> Mobiles { get; set; }

        [SerializeAs(Name = "_id", Attribute = true)]
        public string Id { get; set; }
    }

示例

public static class Sms
    {
        private static RestClient _client;

        private static string Host { get; set; }

        public static void Init(string host)
        {
            Host = host;
            _client = new RestClient(Host);
        }

        public static async Task<Response> SendAsync(List<SendEntity> sendList)
        {
            var request = new RestRequest("sms", Method.POST) { RequestFormat = DataFormat.Json };

            request.AddBody(sendList);

            var response = await _client.ExecuteTaskAsync(request);

            return ToResponse(response);
        }

        public static async Task<Response> SendAsync(SendEntity sendEntity)
        {
            return await SendAsync(new List<SendEntity> { sendEntity });
        }

        public static Response Send(List<SendEntity> sendList)
        {
            var request = new RestRequest("sms", Method.POST) { RequestFormat = DataFormat.Json };

            request.AddBody(sendList);

            var response = _client.Execute(request);

            return ToResponse(response);
        }

        public static Response Send(SendEntity sendEntity)
        {
            return Send(new List<SendEntity> { sendEntity });
        }

        public static Response<SearchResponse> Get(string id)
        {
            var request = new RestRequest("sms/{id}", Method.GET);

            request.AddUrlSegment("id", id);

            var response = _client.Execute<SearchResponse>(request);

            return ToResponse(response);
        }

        public static Response<List<SearchResponse>> Search(SearchEntity searchModel)
        {
            var request = new RestRequest("sms/_search", Method.POST) { RequestFormat = DataFormat.Json };
            request.AddBody(searchModel);

            var response = _client.Execute<List<SearchResponse>>(request);

            return ToResponse(response);
        }

        private static Response<T> ToResponse<T>(IRestResponse<T> t)
        {
            var msg = t.IsSuccessful ? t.StatusCode.ToString() : t.Content;
            return new Response<T> { Body = t.Data, StateCode = t.StatusCode, Message = t.ErrorMessage ?? msg, IsSuccess = t.IsSuccessful };
        }

        private static Response ToResponse(IRestResponse t)
        {
            var msg = t.IsSuccessful ? t.StatusCode.ToString() : t.Content;
            return new Response { StateCode = t.StatusCode, Message = t.ErrorMessage ?? msg, IsSuccess = t.IsSuccessful };
        }
    }

.Net Standard

公司里除了有新用的.NET Core项目还有大量的存量.NET Framework旧项目。

.NET Standard是一种规范,无法以此建立应用,但他能以库的形式作为支撑。.NET Standard的出现为了解决以编写一次的库来同时支持多个平台(.NET Framework、.NET Core、Xamarin)的使用。

 

为了实现多平台的API标准映射,不同版本的映射与数量也随着不一样

.NET Standard
1.01.11.21.31.41.51.62.0
.NET Core 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0
.NET Framework 4.5 4.5 4.5.1 4.6 4.6.1 4.6.1  4.6.1  4.6.1
Mono 4.6 4.6 4.6 4.6 4.6 4.6 4.6 vNext
Xamarin.iOS 10.0 10.0 10.0 10.0 10.0 10.0 10.0 vNext
Xamarin.Android 7.0 7.0 7.0 7.0 7.0 7.0 7.0 vNext
Universal Windows Platform 10.0 10.0 10.0 10.0 10.0 vNext vNext vNext
Windows 8.0 8.0 8.1          
Windows Phone 8.1 8.1 8.1          
Windows Phone Silverlight 8.0            

.Net Standard编译多版本程序集设置

右键编辑项目.csproj,可见下图原本应该是TargetFramework的节点,改为TargetFrameworks(多了个s),通过分号区分不同的程序集,因为RestSharp需要到.NET Framework4.6支持,因为我填入了net46。

接口测试

单元测试

百度定义:单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。

单元:可以是C语言中单元指一个函数,C#、Java里单元指一个类。总的来说,单元就是人为规定的最小的被测功能模块。

然而我的示例代码里的单元测试并非正统规范的单元测试,而是利用单元测试项目来做接口的测试并做负载测试的可运行代码。因此大家不必学习我的做法。

这里有微软的官方文档XUnit结合了mock框架,可供大家学习传送门

负载测试

百度定义:负载测试是模拟实际软件系统所承受的负载条件的系统负荷,通过不断加载(如逐渐增加模拟用户的数量)或其它加载方式来观察不同负载下系统的响应时间和数据吞吐量、系统占用的资源(如CPU、内存)等,以检验系统的行为和特性,以发现系统可能存在的性能瓶颈、内存泄漏、不能实时同步等问题。

1.对于使用VS2017的可以先到工具-获取工具与功能,勾上Web性能与负载工具

2.添加Web性能和负载测试项目,该项目只能是.NET Framework

3.添加负载测试,并选择本地负载测试,负载测试持续时间是此方案的测试总时间,测试迭代是测试方案的测试总次数

4.输入方案场景名称,并选择思考时间,思考时间可以理解成客户操作的停顿时间。

5.常量负载指模拟的每次测试固定并发数,分级负载则是模拟并发数持续递增。

6.选择需要进行负载测试的单元测试,上面我们编写SDK的单元测试来进行接口测试,因此我们可以选择Send单元测试方法,进行测试接口的性能如何。

7.点击完成,并运行负载测试

8.漫长的等待之后可以查看测试结果与关系图

需要注意的是,做负载测试的时候需要模拟并发请求,这里是占资源的,因此尽量把测试服务放到服务器上测试。

posted @ 2018-09-07 09:38  陈珙  阅读(1384)  评论(2编辑  收藏  举报