.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.漫長的等待之后可以查看測試結果與關系圖

需要注意的是,做負載測試的時候需要模擬並發請求,這里是占資源的,因此盡量把測試服務放到服務器上測試。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM