.net持續集成測試篇之Nunit that斷言

  • 2019 年 10 月 3 日
  • 筆記

系列目錄

that是Nunit的新語法,語義上不如簡單斷言,使用上也更加複雜,但是其功能更加強大.
其基本語法如下代碼片段示:

        [Test]          public void DemoTest()          {              bool b = 3 + 2 == 5;              Assert.That(b, Is.True);            }

如上代碼片段未,第一部分為要判斷的對象,可以是一個變量,也可以是lambda表達式,第二個是約束條件.如果參數有多個,That語義更加清析.

That幾乎包含所有簡單斷言里的語法,它除了支持變量,還支持表達式,更為強大的是它還支持自定義約束,如果第二個參數預定義的約束無法滿足我們的需求時,我們可以自定義.

That里的約束非常多,很多是和簡單斷言裏面一樣的(比如Is.True與Assert.True()方法一樣,Is.Positive和Assert.Positive方法一樣,類似的還有很多,大家不妨找一找),這裡不再一一列舉,只給出幾個用簡單斷言無法完成或者實現起來很麻煩的斷例子.

例1

先看一下代碼斷

        [Test]          public void DemoTest()          {              double d1 = 1.1;              double d2 = 2.2;              Assert.AreEqual(3.3, d1 + d2);          }

大家猜一下以上測試結果是失敗還是成功?答案是失敗,由於精度的問題,以上很簡單的測試都會失敗

avatar

下面看如何使用That解決這個問題

        [Test]          public void DemoTest()          {              double d1 = 1.1;              double d2 = 2.2;              Assert.That(3.3, Is.EqualTo(d1 + d2).Within(0.000001));          }

Is.EqualTo和areEqual方法類似,但是它支持再串一個Within方法提供一個容差值,這樣測試就能過通了.

例2

先看下面代碼片段

 [Test]          public void DemoTest()          {              string[] strs = { "a", "ab", "abc" };              int[] lengths = { 1, 2, 3 };          }

以上代碼a的長度為1,ab的長度為2,abc的長度為3,我們相要判斷集合strs里的每個元素的長度是否分別對應下面集合元素的值,如果要用普通方法需要很複雜的判斷.下面看看如何使用That結合Nunit提供的方法實現一行代碼判斷

 [Test]          public void DemoTest()          {              string[] strs = { "a", "ab", "abc" };              int[] lengths = { 1, 2, 3 };              Assert.That(new ListMapper(strs).Property(nameof(string.Length)), Is.EqualTo(lengths));          }

分析以上代碼,通過獲取String類的Length屬性,Listmapper把strs集合轉成它的長度屬性值組成的集合,然後再和lengths屬性做比較.

這是官網上的一個例子,並不是一個太好的例子,通過linq方法同樣能實現,並且這個方法語義也不是特別清析,在實際中如果有比較麻煩的問題可以考慮下這個方法.

例子3

集合複雜元素相等性比較
看以下代碼片段

       [Test]          public void DemoTest()          {              List<Person> studs = new List<Person>              {                  new Person {Name = "baidu", Age = 24},                  new Person {Name = "sto", Age = 32},                  new Person {Name = "tencent", Age = 12},                  new Person {Name = "alibaba", Age = 32}              };              List<Person> students = new List<Person>()              {                  new Person {Name = "baidu", Age = 24},                  new Person {Name = "sto", Age = 32},                  new Person {Name = "tencent", Age = 12},                  new Person {Name = "alibaba", Age = 32}              };            }

以上兩個集合的元素都是Person實例,並且它們包含的對應元素名稱和age都要等,如果只要Name和Age相等就認為兩個Person元素相等,我們如何判斷以上兩個集合是否相等呢?

請看以下方法

        [Test]          public void DemoTest()          {              List<Person> studs = new List<Person>              {                  new Person {Name = "baidu", Age = 24},                  new Person {Name = "sto", Age = 32},                  new Person {Name = "tencent", Age = 12},                  new Person {Name = "alibaba", Age = 32}              };              List<Person> students = new List<Person>()              {                  new Person {Name = "baidu", Age = 24},                  new Person {Name = "sto", Age = 32},                  new Person {Name = "tencent", Age = 12},                  new Person {Name = "alibaba", Age = 32}              };              Assert.That(studs, Is.EqualTo(students).Using(new StudentEqualityComparer()));          }

以上代碼測試通過,我們看以上代碼,EqualTo後面串了Using方法,這個方法里接受IComparer,Icomparer,IEqualityComparer,Comparison委託,Func<T,T,bool>委託等豐富的比較器

下面我們把StudentEqualityComparer比較器的代碼貼出來

 public class PersonEqualityComparer : IEqualityComparer<Person>      {          public bool Equals(Person x, Person y)          {              if (x == null || y == null) return false;              return x.Name == y.Name && x.Age == y.Age;          }            public int GetHashCode(Person obj)          {              if (obj.Name == null)              {                  return 0;              }              return obj.Name.GetHashCode();          }      }