.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.0 | 1.1 | 1.2 | 1.3 | 1.4 | 1.5 | 1.6 | 2.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.漫长的等待之后可以查看测试结果与关系图
需要注意的是,做负载测试的时候需要模拟并发请求,这里是占资源的,因此尽量把测试服务放到服务器上测试。
作 者:
陈珙
出 处:http://www.cnblogs.com/skychen1218/
关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!