.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.漫长的等待之后可以查看测试结果与关系图

需要注意的是,做负载测试的时候需要模拟并发请求,这里是占资源的,因此尽量把测试服务放到服务器上测试。
.net core实践系列之短信服务-Api的SDK的实现与测试的更多相关文章
- .net core实践系列之短信服务-目录
前言 经过两周多的业余时间,终于把该系列的文章写完了.第一次写系列,可能部分关键点并没有覆盖到,如果有疑问的朋友可以随时反馈给我.另外也感谢在我发布文章时给予我方案建议与反馈源码BUG的朋友们.下面是 ...
- .net core实践系列之短信服务-Sikiro.SMS.Bus服务的实现
前言 前两篇<.net core实践系列之短信服务-Sikiro.SMS.Api服务的实现>.<.net core实践系列之短信服务-Api的SDK的实现与测试>分别讲解了AP ...
- .net core实践系列之短信服务-架构设计
前言 上篇<.net core实践系列之短信服务-为什么选择.net core(开篇)>简单的介绍了(水了一篇).net core.这次针对短信服务的架构设计和技术栈的简析. 源码地址:h ...
- .net core实践系列之短信服务-Sikiro.SMS.Api服务的实现
前言 上篇<.net core实践系列之短信服务-架构设计>介绍了我对短信服务的架构设计,同时针对场景解析了我的设计理念.本篇继续讲解Api服务的实现过程. 源码地址:https://gi ...
- .net core实践系列之短信服务-架构优化
前言 通过前面的几篇文章,讲解了一个短信服务的架构设计与实现.然而初始方案并非100%完美的,我们仍可以对该架构做一些优化与调整. 同时我也希望通过这篇文章与大家分享一下,我的架构设计理念. 源码地址 ...
- .net core实践系列之短信服务-为什么选择.net core(开篇)
前言 从今天我将会写.net core实战系列,以我最近完成的短信服务作为例子.该系列将会尽量以最短的时间全部发布出来.源码也将优先开源出来给大家. 源码地址:https://github.com/S ...
- .net core实践系列之短信服务-Sikiro.SMS.Job服务的实现
前言 本篇会继续讲解Sikiro.SMS.Job服务的实现,在我写第一篇的时候,我就发现我当时设计的架构里Sikiro.SMS.Job这个可以选择不需要,而使用MQ代替.但是为了说明调度任务使用实现也 ...
- php 阿里云短信服务及阿里大鱼实现短信验证码的发送
一:使用阿里云的短信服务 ① 申请短信签名 ②申请短信模板 ③创建Access Key,获取AccessKeyId 与 AccessKeySecret.(为了安全起见,这里建议使用子用户的Access ...
- PHP开发实用-阿里短信服务(Short Message Service)
步骤 1 使用阿里云短信服务正常发短信需要 短信签名 短信模板 1申请短信签名 根据用户属性来创建符合自身属性的签名信息.企业用户需要上传相关企业资质证明,个人用户需要上传证明个人身份的证明. ...
随机推荐
- Maven 安装 on centos7
本文演示如何在CentOS7上安装maven. 1 准备工作 1.1 进入官网下载栏目 http://maven.apache.org/download.cgi 找到下载列表中 Binary tar. ...
- Javascript 高级程序设计--总结【二】
********************** Chapter 6 ********************** 属性: 数据属性: Configurable: 能否通过delete 删除属性,默认 ...
- python装饰器(新年第一写)
祭奠碌碌无为的2018,想想其实也不算碌碌无为,至少我还搞懂了装饰器,写了一堆有用没用的玩意 原来觉得装饰器挺难的,直到2018年的最后几天,突然就明白了,难道这就是传说中的开天聪么 言归正传,之所以 ...
- 描述性统计的matlab实现
理论讲的再多不会做也白弄 直接上手 一.针对接近正态分布的(均值,方差,标准差,极差,变异系数,偏度,峰度) 这里我必须提前说明一点就是,你在写好函数后,函数的名是dts,你保存的文件名也必须是dts ...
- Django学习---py3下的富文本编辑器的使用
背景说明: Ueditor HTML编辑器是百度开源的HTML编辑器,但是在Python3下调用报错,找不到widgets模块,经查发现,DjangoUeditor是基于Python 2.7的,对Py ...
- C#中类为什么要实例化
在使用C#语言时,发现一下有关类实例化的问题,在此之前先复习一下类和对象的概念,类是一个抽象体,是对一类事物的抽象体:而对象就是一个具体的事物,对象的抽象就是类.车就是一个类,而车包括面包车,小汽车, ...
- ccf-20160903--炉石传说
本题思路如下图: 题目和代码如下: 问题描述 试题编号: 201609-3 试题名称: 炉石传说 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 <炉石传说:魔兽英雄传& ...
- 个人技术博客(a)
- centos iftop iotop htop
centos6.4安装iftopyum install gccyum -y install libpcap libpcap-develyum -y install ncurses ncurses-de ...
- Scrapy中将item字段转为简体or繁体
1. 安装hanziconv安装一个简繁体转换的包: pip install hanziconv 2. 自定义一个itempiples找到项目中的pipelines.py文件 添加自定义的pipeli ...