日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

3.5 基本属性测试

發布時間:2024/3/13 编程问答 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3.5 基本属性测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

3.5 基本屬性測試

開始編寫測試時要注意的另一個重要功能是ZIO Test支持開箱即用的基于屬性的測試。
在基于屬性的測試中,測試框架不是您手動生成輸入并驗證期望的輸出,而是從您指定的潛在輸入分布中生成輸入的整個集合,并驗證所有輸入的期望是否成立。
基于屬性的測試可以極大地提高開發人員編寫測試的效率,并捕獲直到生產才發現的錯誤,因為它可以使測試框架立即生成大量測試用例,其中包括開發人員最初可能沒有考慮過的用例。
但是,必須小心進行屬性測試,以確保使用正確的生成值分布,包括足夠數量的“拐角案例”(例如,空集合,具有最小值和最大值的整數)以及足夠的生成值空間覆蓋生產中可能看到的值的范圍(例如,長字符串,非ASCII字符集中的字符串)。
ZIO Test通過其Gen數據類型和運算符檢查家族來支持屬性。 Gen [R,A]代表需要環境R的A值的生成器。根據實現方式,生成器可以是無限的或有限的,并且可以是隨機的或確定的。
ZIO測試在Gen隨播對象中包含各種標準數據類型的生成器。例如,我們可以使用anyInt生成器創建一個整數值生成器。

import zio.random._val intGen: Gen[Random, Int] = Gen.anyInt// intGen: Gen[Random, Int] = Gen(zio.stream.ZStream$$anon$1@36467acb)

一旦有了生成器,就可以使用check運算符使用該生成器創建測試。例如:

object ExampleSpec extends DefaultRunnableSpec {def spec = suite("ExampleSpec")(testM("integer addition is associative") {check(intGen, intGen, intGen) {(x, y, z) =>val left = (x + y) + zval right = x + (y + z) assert (left)(equalTo(right))}})}

注意,編寫基于屬性的測試的方式與編寫普通測試的方式非常相似。
我們仍然使用testM方法標記測試。基于屬性的測試將始終使用testM而不是test,因為運行基于屬性的測試本身會涉及effect。

在測試中,我們調用check運算符,將要使用的每個生成器指定為參數。 ZIO
Test具有針對不同數量的生成器的檢查運算符的重載變體,因此您可以對單個生成器或多個不同的生成器使用check,如上例所示。
然后,我們提供一個可以訪問每個生成的值并使用assert或assert運算符返回測試結果的函數,就像我們在上面編寫的測試中使用的一樣。然后,測試框架將重復采樣值的組合并測試這些樣本,直到發現失敗或測試“足夠”數量的樣本而未發現失敗。
檢查運算符有幾種變體。最重要的是checkM,它類似于check,不同之處在于它允許我們在基于屬性的測試中執行效果。還有checkN變體,可以指定要測試的樣本數量,而checkAll變體可以測試有限生成器中的所有樣本。
編寫基于屬性的測試的許多工作往往是編寫生成器本身。如果我們要生成的值是ZIO或Scala標準庫中的數據類型,并且我們不需要任何特殊的分布,那么我們通常可以使用現有的生成器,就像上面使用的intGen一樣。
當我們需要為自己的數據類型創建生成器時,可以使用現有的Gen構造函數和Gen上的運算符來創建所需的生成器。到目前為止,從我們對ZIO的了解中,我們已經對其中許多操作感到熟悉。
舉例來說,假設我們要為已定義的User數據類型創建生成器。

final case class User(name: String, age: Int)

由于User是一種數據類型,因此我們定義了ZIO測試中不存在用于User的生成器。
此外,基于對域的理解,我們知道User值必須滿足某些在類型簽名中未捕獲的屬性。

  • 名稱始終由ASCII字符組成

  • 對于成年人來說,年齡總是屬于自然壽命,例如18歲和120.

  • 我們可以使用現有的anyASCIIString為名稱實現生成器。

    val genName: Gen[Random with Sized, String] = Gen.anyASCIIString// genName: Gen[Random with Sized, String] = Gen( // zio.stream.ZStream$$anon$1@3ae44cd1// )

    此生成器需要一個我們從未見過的服務,它是ZIO
    Test特有的服務,它可以控制所生成值的“大小”,例如,我們應該生成一個列表的大小,或者在這種情況下,一個String的大小。
    。 對于年齡生成器,我們可以使用int構造函數,該構造函數生成指定范圍內的整數值。

    val genAge: Gen[Random, Int] = Gen.int(18, 120) // genAge: Gen[Random, Int] = Gen(zio.stream.ZStream$$anon$1@41877d79)

    實現這兩個生成器后,剩下的就是將它們組合起來,從概念上從genName采樣一個名稱,從genAge采樣一個年齡,然后將兩者結合以生成User值。 Gen數據類型支持許多我們已經熟悉的運算符,包括map,flatMap和zipWith,因此我們實際上可以很容易地做到這一點。

    val genUser: Gen[Random with Sized, User] = for {name <- genNameage <- genAge} yield User(name, age)// genUser: Gen[Random with Sized, User] = Gen( // zio.stream.ZStream$$anon$1@695a724a// )

    我們現在有了一個User值生成器,可以在任何check變量中使用它來為基于屬性的測試生成User值!

    總結

    以上是生活随笔為你收集整理的3.5 基本属性测试的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。