單元測試與Nunit的基本使用

来源:http://www.cnblogs.com/zwt-blog/archive/2016/08/19/5788222.html
-Advertisement-
Play Games

一、單元測試是什麼 單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。對於單元測試中單元的含義,一般來說,要根據實際情況去判定其具體含義,如C語言中單元指一個函數,C#里單元指一個類,圖形化的軟體中可以指一個視窗或一個菜單等。總的來說,單元就是人為規定的最小的被測功能 ...


 一、單元測試是什麼

單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。對於單元測試中單元的含義,一般來說,要根據實際情況去判定其具體含義,如C語言中單元指一個函數,C#里單元指一個類,圖形化的軟體中可以指一個視窗或一個菜單等。總的來說,單元就是人為規定的最小的被測功能模塊。單元測試是在軟體開發過程中要進行的最低級別的測試活動,軟體的獨立單元將在與程式的其他部分相隔離的情況下進行測試。

單元測試(模塊測試)是開發者編寫的一小段代碼,用於檢驗被測代碼的一個很小的、很明確的功能是否正確。通常而言,一個單元測試是用於判斷某個特定條件(或者場景)下某個特定函數的行為。

二、為什麼需要單元測試

在我們現在的編程思維中一直都是編碼=>編譯=>調試,一直迴圈,直到要處理的功能完成,每一個功能完成都是如此,且有的功能是嚴重依賴於上一個功能。在如此處理中存在幾個問題。

  1. 編譯通過後,運行程式出現的bug難以定位。
  2. 修改一個bug,容易引進其他bug。
  3. Bug越到後期發現,越難以修改。
  4. 後期系統的複雜性,導致代碼難以修改和重構,使得系統難以維護。
  5. 開發人員常認為編譯功過,進行了幾次手工測試就等於測試通過(認為詳細的測試是測試人員的工作,非開發人員的工作)。
  6. 在完全依賴外部系統的情況下,難以進行有效的測試。
  7. 手工測試效率低下,針對性不強,測試不能重用。

有了單元測試在開發過程中起到的作用。

  1. 大大節約了測試和修改的時間,有效且便於測試各種情況。
  2. 能快速定位bug(每一個測試用例都是具有針對性)。
  3. 能使開發人員重新審視需求和功能的設計(難以單元測試的代碼,就需要重新設計)。
  4. 強迫開發者以調用者而不是實現者的角度來設計代碼,利於代碼之間的解耦。
  5. 自動化的單元測試能保證回歸測試的有效執行。
  6. 使代碼可以放心修改和重構。
  7. 測試用例,可作為開發文檔使用(測試即文檔)。
  8. 測試用例永久保存,支持隨時測試。

既然單元測試有這些好處,為什麼我們不去用呢。可以歸納為以下幾個理由。

  1. 對單元測試存在的誤解,如:單元測試屬於測試工作,應該由測試人員來完成,所以單元測試不屬於開發人員的職責範圍。答:雖然單元測試雖然叫做"測試",但實際屬於開發範疇,應該由開發人員來做,而開發人員也能從中受益。
  2. 沒有真正意識到單元測試的收益,認為寫單元測試太費時,不值得。

    答:在開發時越早發現bug,就能節省更多的時間,降低更多的風險。單元測試先期要編寫測試用例,是需要多耗費些時間,但是後面的調試、自測,都可以通過單元測試處理,不用手工一遍又一遍處理。實際上總時間被減少了。

  3. 項目經理或技術主管沒有要求寫單元測試,所以不用寫。

    答:寫單元測試應該成為開發人員的一種本能,開發本身就應該包含單元測試。

  4. 不知道有單元測試這回事,不知道如何用。經過這篇文檔的說明,就基本知道如何處理單元測試。

結論:

只進行手工測試,只是臨時性的單元測試,代碼測試覆蓋率要超過70%都很困難,未覆蓋的代碼可能遺留大量的細小的錯誤,這些錯誤還會互相影響,當bug暴露出來的時候難於調試,大幅度提高後期測試和維護成本。可以說,進行充分的單元測試,是提高軟體質量,降低開發成本的必由之路。

要進行充分的單元測試,應專門編寫測試代碼,並與產品代碼隔離。比較簡單的辦法是為產品工程建立對應的測試工程,為每個類建立對應的測試類,為每個函數(很簡單的除外)建立測試函數。

單元測試是由程式員自己來完成,最終受益的也是程式員自己。可以這麼說,程式員有責任編寫功能代碼,同時也就有責任為自己的代碼編寫單元測試。執行單元測試,就是為了證明這段代碼的行為和我們期望的一致。

對於程式員來說,如果養成了對自己寫的代碼進行單元測試的習慣,不但可以寫出高質量的代碼,而且還能提高編程水平。

三、單元測試工具。

在.Net平臺有三種單元測試工具,分別為MS Test、NUnit、Xunit.Net。

1.MS Test為微軟產品,集成在Visual Studio 2008+工具中。

2.NUnit為.Net開源測試框架(採用C#開發),廣泛用於.Net平臺的單元測試和回歸測試中,官方網址(www.nunit.org)。

3.XUnit.Net為NUnit的改進版。

(以下主要講解NUnit的使用,會了NUnit其他2個測試工具也能快速熟悉)。

任何xUnit工具都使用斷言進行條件的判斷,NUnit自然也不例外,與其它的xUnit(如JUnit、phpUnit、pythonUnit)相比,由於大量使用了Generic、Attribute等語言特征,NUnit提供了更為方面、靈活的測試方法,下麵先介紹一下斷言。

NUnit一共有五個斷言類,分別是Assert、StringAssert、FileAssert、DirectoryAssert、CollectionAssert,它們都在NUnit.Framework命名空間,其中Assert是常用的,而另外四個斷言類,顧名思義,分別對應於字元串的斷言、文件的斷言、目錄的斷言、集合的斷言。理論上,僅Assert類就可以完成所有條件的判斷,然而,如果合理的運用後面的四個斷言,將使代碼更加簡潔、美觀,也更加便於理解和維護。

四、NUnit的使用。

本處演示所使用的NUnit版本為2.6.4,若要使用最新版可以去官網下載。

首先創建一個類庫項目(也可以是其他項目),然後創建一個Test+類庫名稱的項目(也可以是項目名稱+Test),用於代表是測試工程。如下圖:

Demonstration項目中含有一個計算功能類,對應的測試項目含有一個測試計算類,一個計算功能類中方法可能需要多個測試用例來完成檢測。如下展示出了2個類的代碼:

    /// <summary>
    /// 用於演示的一個簡單計算功能
    /// </summary>
    public class Calculate
    {
        /// <summary>
        /// 加法
        /// </summary>
        public int Add(int a, int b)
        {
            return a + b;
        }
        /// <summary>
        /// 減法
        /// </summary>
        public int Subtract(int a, int b)
        {
            return a - b;
        }
        /// <summary>
        /// 乘法
        /// </summary>
        public int Multiply(short a, short b)
        {
            return a * b;
        }
        /// <summary>
        /// 除法
        /// </summary>
        public int Quotient(int a, int b)
        {
            return a / b;
        }
        /// <summary>
        /// 開平方根
        /// </summary>
        public double SquareRoot(int num)
        {
            return Math.Sqrt(num);
        }
        /// <summary>
        /// 四捨五入,取整
        /// </summary>
        public int Round_Off(double num)
        {
            return (int)Math.Round(num);
        }
        /// <summary>
        /// 向上取整
        /// </summary>
        public int UpwardTrunc(double num)
        {
            return (int)Math.Ceiling(num);
        }
        /// <summary>
        /// 平方
        /// </summary>
        public int Square(short num)
        {
            throw new NotImplementedException();
        }
    }
    [TestFixture(Description = "測試示例")]
    public class TestCalculate
    {
        private Calculate calculate;
        private StreamReader reader;
        private string[] sourceData = new string[] { @"..\..\..\Resource\score_1.csv" };
        private short a, b;
        [TestFixtureSetUp]
        public void Initialize()
        {
            Console.WriteLine("初始化信息");
            calculate = new Calculate();
        }
        [TestFixtureTearDown]
        public void Dispose()
        {
            Console.WriteLine("釋放資源");
            if (reader != null)
            {
                reader.Close();
            }
        }
        [SetUp]
        public void SetUp()
        {
            a = 3;
            b = 2;
        }
        [TearDown]
        public void TearDown()
        {
            Console.WriteLine("我是清理者");
        }
        [Test(Description = "加法")]
        [Category("優先順序 1")]
        public void TestAdd()
        {
            Assert.AreEqual(5, calculate.Add(a, b));
        }
        [Category("優先順序 1")]
        [TestCase(1, 2), TestCase(2, 3)]
        public void TestSubtract(int a, int b)
        {
            Assert.AreEqual(a - b, calculate.Subtract(a, b));
        }
        [Category("優先順序 2")]
        [TestCase(1, 2, Result = 2), TestCase(2, 3, Result = 6)]
        public int TestMultiply(short a, short b)
        {
            return calculate.Multiply(a, b);
        }
        [Test]
        [Category("優先順序 2")]
        [ExpectedException(typeof(DivideByZeroException))]
        public void TestQuotient()
        {
            calculate.Quotient(a, 0);
        }
        [Test]
        [Category("優先順序 3")]
        public void TestSquareRoot()
        {
            Assert.Less(1, calculate.SquareRoot(a));
        }
        [Test]
        [Category("優先順序 3")]
        [Sequential]
        public void TestRound_Off([Values(3.4, 4.5, 4.6, 5.5)] double num, [Values(3, 5, 5, 6)] int result)
        {
            Assert.AreEqual(result, calculate.Round_Off(num));
        }
        [Test]
        [Category("優先順序 3")]
        public void TestUpwardTrunc([ValueSource("sourceData")] object fileName)
        {
            reader = new StreamReader((string)fileName);
            string content;
            while ((content = reader.ReadLine()) != null)
            {
                var nums = content.Split(',').Select(c => double.Parse(c)).ToArray();
                Array.ForEach(nums, (num) =>
                {
                    int result = calculate.UpwardTrunc(num);
                    Console.Write(result + "\n");
                });
            }
        }
        [Test]
        public void TestSquare()
        {
            Assert.Throws<NotImplementedException>(() => calculate.Square(b));
        }
        [Test, Explicit]
        [Ignore]
        public void TestFactorial()
        {
            Assert.Fail("未能實現階乘功能");
        }
    }
View Code

 

在粗略看了代碼後,下麵就詳細說明相應的測試標記(屬性)的用法。

  1. [TestFixture(arguments)]屬性標記類為測試類,若沒有填寫參數,則測試類必須含有無參構造函數,否則需要相應的有參構造函數。也可以多個測試[TestFixture(1), TestFixture("a")]
  2. [Test]屬性標記方法為測試方法,中添加Description參數可以給我們測試的功能添加描述信息。
  3. [TestCase(arguments)]屬性標記有參數無返值方法為測試方法(泛型方法一樣標記),想要多次測試可用逗號隔開([TestCase(1,2), TestCase(2,3)])。
  4. [TestCase(arguments,Result = value)屬性標記帶參數與返回值的方法為測試方法,執行的時候把預期的返回值也告訴NUnit,如果返回值不對,測試同樣無法通過。
  5. [Suite](測試套件,僅對屬性與索引器標記有效):可以將多個測試類組合到一起,同時執行多個測試。本版本的開發人員的一個信念就是減少這個的需要,可以使用[Category]來替代它。
  6. [Explicit]屬性標記測試方法需要在UI界面顯式執行,如果不想對某個方法進行單元測試,只是在它被選中時才進行測試的話,可以調用該特性。
  7. [Ignore]屬性標記一個測試方法或一個測試類被忽略,如果測試類被忽略,其內中的測試方法也會被忽略。
  8. [ExpectedException(Type)]屬性標記測試方法在運行時拋出一個期望的異常,如果是則測試通過,否則不通過。
  9. [Category("")]屬性標記用於將測試分類(便於只測試需要的類別),可在方法與類上進行標記,在NUnit-GUI界面的Categories選項卡中對要測試種類進行添加,Run時僅測試該類別的測試。
  10. [TestFixtureSetUp]屬性標記方法為類級別設置(初始化)方法,在整個測試類中執行一次初始化,所有的測試方法共用初始化數據。
  11. [TestFixtureTearDown]屬性標記方法為類級別拆卸方法,在整個測試類中執行一次拆卸.當測試類中的所有測試方法執行完成,就會執行拆卸方法,用於清除數據、釋放資源。
  12. [TearDown]屬性標記方法為函數級別的拆卸方法,在執行完每個測試方法後,執行該拆卸方法。一個測試類可以僅有一個TearDown/Setup/TestFixtureSetUp/TestFixtureTearDown方法。如果有多個定義,測試類也會編譯成功,但是測試時不會運行這些標記過的方法。
  13. [SetUp]屬性標記方法為函數級別的設置方法,在執行每個測試方法前,執行該設置方法。
  14. 每執行一次Run,就是new一個新的實例在測試。
  15. [Maxtime]/[Timeout]屬性標記測試用例的最大執行時間,前者超時時不取消測試,而後者會強行中斷,用法如:[Test, Maxtime(2000)],[Test, Timeout(2000)]。
  16. [Repeat]屬性標記測試方法重覆執行多少次,如:[Test, Repeat(100)]。
  17. [RequiresMTA]/[RequiresSTA]/[RequiresThread]屬性標記測試用例必須的在多線程、單線程、獨立的線程狀態下運行。
  18. [Values]屬性標記測試用例的參數,以參數的形式傳入一組值,NUnit會把這組值分解成相應數量的子測試。當測試用例的2個參數都使用[Values]進行標記,NUnit預設生成2組數量乘積的用例,需要使用[Sequential]標記測試用例才能按順序生成一一對應的n(n=2組中最大數組長度)個子測試用例。
  19. [ValueSource]屬性標記測試用例的參數,指定參數的數據源來自哪裡,在使用[ValueSource]指定數據源時,該數據源必須實現了IEnumerable介面,數據源可以是屬性、無參方法、實例或靜態成員。

更多屬性標記與詳細說明,可以查閱NUnit官網提供的說明文檔。一個方法的測試可能要寫很多個測試用例,這都是正常的,如果一個測試用例包含多個斷言,那些緊跟失敗斷言的斷言都不會執行,因為通常每個測試方法最好只有一個斷言。

在運行單元測試時有3種方式分別為:

  1. 把測試工程的屬性=>調試=>啟動外部程式,設置為NUnit運行程式。在啟用調試時會啟動NUnit界面程式,但NUnit界面沒有測試用例的信息,需要自己添加在File=>Open Project->文件資源管理器,找你的測試工程類庫或程式添加即可。點擊Run運行,根據選中的節點運行該節點下所有的子測試用例(該測試可進行調試)。如下圖:

以上的圖片展示了運行錯誤界面和運行輸出界面。在測試用例的節點中綠色'√'代表通過,黃色'√'代表忽略,紅色'×'代表失敗。

  1. 直接啟動NUnit界面程式,在File=>Open Project->文件資源管理器,添加測試工程類庫或程式,點擊相應的節點進行Run測試,NUnit會根據類庫或程式生成更新,自動更新界面中測試用例節點,但運行的測試用例不能進行調試。效果圖與①中的效果一樣。
  2. 在Visual Studio 2010+的IDE中以插件的方式集成NUnit測試工具,直接在測試工程中點擊滑鼠右鍵,運行測試即可。或者在VS菜單欄的測試中運行NUnit測試。集成與運行效果圖在"第五節"中展示。

五、Nunit常用類和方法

1、Assert(斷言):如果斷言失敗,方法將沒有返回,並且報告一個錯誤。

1)、測試二個參數是否相等

Assert.AreEqual;

Assert.AreEqual;

2)、測試二個參數是否引用同一個對象

Assert.AreSame;

Assert.AreNotSame;

3)、測試一個對象是否被一個數組或列表所包含

Assert.Contains;

4)、測試一個對象是否大於另一個對象

Assert.Greater;

5)、測試一個對象是否小於另一個對象

Assert.Less;

6)、類型斷言:

Assert.IsInstanceOfType;

Assert.IsAssignableFrom;

7)、條件測試:

Assert.IsTrue;

Assert.IsFalse;

Assert.IsNull;

Assert.IsNotNull;

Assert.IsNaN;用來判斷指定的值是否為數字。

Assert.IsEmpty;

Assert.IsNotEmpty;

Assert.IsEmpty;

Assert.IsNotEmpty;

8)、其他斷言:

Assert.Fail;方法為你提供了創建一個失敗測試的能力,這個失敗是基於其他方法沒有封裝的測試。對於開發你自己的特定項目的斷言,它也很有用。

Assert.Pass;強行讓測試通過

2、字元串斷言(StringAssert):提供了許多檢驗字元串值的有用的方法

StringAssert.Contains;

StringAssert.StartsWith;

StringAssert.EndsWith;

StringAssert.AreEqualIgnoringCase;

3、CollectionAssert類

CollectionAssert.AllItemsAreInstancesOfType;集合中的各項是否是某某類型的實例

CollectionAssert.AllItemsAreNotNull:集合中的各項均不為空

CollectionAssert.AllItemsAreUnique;集合中的各項唯一

CollectionAssert.AreEqual;兩個集合相等

CollectionAssert.AreEquivalent;兩個集合相當

CollectionAssert.AreNotEqual;兩個集合不相等

CollectionAssert.AreNotEquivalent;兩個集合不相當

CollectionAssert.Contains;

CollectionAssert.DoesNotContain;集合中不包含某對象

CollectionAssert.IsSubsetOf:一個集合是另外一個集合的子集

CollectionAssert.IsNotSubsetOf:一個集合不是另外一個集合的子集

CollectionAssert.IsEmpty;集合為空

CollectionAssert.IsNotEmpty;集合不為空

CollectionAssert.IsOrdered;集合的各項已經排序

4、FileAssert

FileAssert.AreEqual;

FileAssert.AreNotEqual;

5、DirectoryAssert

DirectoryAssert.AreEqual;

DirectoryAssert.AreNotEqual;

DirectoryAssert.IsEmpty;

DirectoryAssert.IsNotEmpty;

DirectoryAssert.IsWithin;

DirectoryAssert.IsNotWithin;

六、NUnit集成到VS中的使用。

在使用NUnit-GUI處理運行測試用例,是不是感覺比較麻煩,還要使用外部的NUnit應用程式,有沒有簡單點的最好能夠跟VS開發工具緊密結合的方式來進行NUnit單元測試呢?答案是肯定的,有2種方式。

1.我們在VS中選擇工具菜單欄下的擴展和更新,選擇聯機併在搜索框中輸入NUnit。出現如下圖的信息,有2個版本的Nunit適配器,分別為NUnit 3.x(最新版為3.4.1)和NUnit 2.x(最新版為2.6.4),都支持Visual Studio 2012+。若想在VS2010中集成,需要安裝NUnit 2.6.4安裝包(可在官網下載)與VS2010 NUnit整合插件(下載地址:

http://visualstudiogallery.msdn.microsoft.com/c8164c71-0836-4471-80ce-633383031099),下載安裝完畢就能在 VS2010 的視圖=>其他視窗中看到 Visual Nunit(或使用快捷鍵Ctrl + F7),打開該視圖,將之拖到合適的位置。

下載安裝NUnit Test Adapter後關閉VS,重啟一下就好了,我們打開類庫項目中的TestCalculate類,在右鍵彈出的菜單中點擊運行測試。運行結束後,會在左側的測試資源管理器當中顯示本次操作的結果。

2.通過ReSharper工具處理NUnit的單元測試,在VS2010+中安裝了ReSharper開發插件,ReSharper內中自帶支持NUnit與MS Test這2個單元測試工具,只要你的測試工程中引用了相應的單元測試類庫(如nunit.Framework.dll)、以及含有測試用例。通過滑鼠右鍵或快捷鍵(Ctrl + T,R),就可以運行單元測試,也可以進行單元測試調試,ReSharper選項圖與運行效果如下圖。

七、後續

上面列出只能單元測試的基本使用,未能說明對Mock等其他功能的使用,也沒有解釋對難以單元測試的代碼進行重新設計的說明,需要後期深入瞭解才能列出相應的文檔說明。能夠更好的使用單元測試才能更好的使用TDD(測試驅動開發)來開展項目,TDD測試驅動開發是測試先行(此測試是單元測試)、是極限編程的一個重要特點,它以不斷的測試推動代碼的開發,既簡化了代碼,同時也保證了軟體指令,另一方面說編寫的測試用例將成為重要文檔(可以作為SDK提供給開發者,測試即文檔)。

-----------------以上內容是根據博客園其他博客的說明與Nunit官方文檔,以及自己測試使用,進行了整理說明。----------------------------


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 補充下上篇文章集合的命令。 上篇地址 博客園蝸牛 http://www.cnblogs.com/tdws/p/5785939.html SCARD Key獲得執行集合中元素的數量。 SDIFFSTORE 目標鍵 keys ... 將集合做DIFF差集操作,並存儲在目標鍵中。 另外同樣有SINTERS ...
  • 通常情況下我們在使用IBatisNet的時候,配置文件和映射文件都是暴露在外的,如果能進入到伺服器,那麼你的程式的操作資料庫的SQL語句,資料庫連接字元串等信息都將很輕鬆的被看到,這樣是很危險的。然而IBatisnet自身也沒有提供配置文件直接加密的方法,但我們可以用變通的方式來儘可能的保護這些文件 ...
  • 本隨筆續接:.NET 實現並行的幾種方式(一) 四、Task 3)Task.NET 4.5 中的簡易方式 在上篇隨筆中,兩個Demo使用的是 .NET 4.0 中的方式,代碼寫起來略顯麻煩,這不 .NET 4.5提供了更加簡潔的方式,讓我們來看一下吧。 /// <summary> /// Task. ...
  • 二三四五還沒寫,先寫六吧(有道友說想看看插件部分)。 這裡是一 從零開始編寫屬於我的CMS:(一)前言 一,首先預定義介面<!--?xml:namespace prefix = "o" ns = "urn:schemas-microsoft-com:office:office" /--> 新建類庫, ...
  • 從本節開始,我們使用SharpGL帶的VS2010擴展,來直接生成SharpGL工程。 如果你新建項目時,沒有看到下麵的SharpGL項目,那麼請事先在SharpGL源代碼中找到一個叫 ”SharpGL 2.0 Visual Studio Extension“目錄 ,安裝名為 SharpGL.vsi ...
  • 驗證碼在軟體中的地位越來越重要,有效防止這種問題對某一個特定註冊用戶用特定程式暴力破解方式進行不斷的登陸嘗試;下麵就是實現驗證碼的基本步驟: 1.在MVC框架中,則需添加一個控制器,代碼如下 前端頁面代碼也簡單,在index添加一個視圖即可 最後在運行時展示的是這樣的一個頁面,而且點擊圖片會實現更新 ...
  • 安裝運行環境 sudoyuminstall libunwind libicu 下載.net core https://www.microsoft.com/net/download 下載完後上傳文件 安裝步驟https://www.microsoft.com/net/core#centos 安裝如下 ...
  • 最近做項目的時候 用戶提出要上傳大圖片 一張圖片有可能十幾兆 本來用的第三方的上傳控制項 有限製圖片上傳大小的設置 以前設置的是2M 按照用戶的要求 以為直接將限製圖片上傳大小的設置改下就可以了 但是當上傳大圖片的時 總是異常: 錯誤消息:超過了最大請求長度 解決方案: 錯誤原因:asp.net預設最 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...