[Elm] 너만의 최강 Fuzzer를 손에 넣어라!
17190 단어 property-based-testingFuzzer테스트Elm
테스트 대상의 함수가 만족해야 하는 성질을 기술하면(자), 그 성질을 조사하기에 적절한 입력 데이터를 자동 생성해 실제로 함수에 맞추어, 그 출력이 예상하고 있는 성질을 채우고 있는지를 체크하는 테스트 기법 입니다.
Elm에서는 elm-test의 Fuzz 모듈을 사용하는 것이 일반적입니다.
Fuzz 모듈의 기본 사용법 자체는 @jinjor 님이 이미 기사를했습니다..
이 기사에서는 Fuzzer의 합성 및 변환에 대해 자세히 파악하여 세계에 하나만 눈에 넣어도 아프지 않는 귀여운 우리 아이와 같은 Fuzzer를 얻을 수있는 방법을 소개합니다.
여기에서 내 귀여운 사랑하는 딸 사쿠라 짱을보십시오.
이후의 내용은,
elm-test 4.20
(Elm 0.18) 를 상정하고 있습니다.레벨 0. 프리미티브 녀석
오리지널
Fuzzer
라고 말할 때, 갑자기 전혀 오리지널이 아닌 녀석입니다.bool : Fuzzer Bool
-- `Int` の値を生成する.
-- `NaN` とか `Infinity` とか `-Infinity` とかは生成しません。
-- 他の Fuzzer もそうだけど、ただの一様分布ではなく、コーナーケースとかよく使われる値を多めに生成してくれます。
int : Fuzzer Int
float : Fuzzer Float
-- `0.0` から `1.0` の値を生成する.
-- もちろんこれもしっかり `0.0` とか `1.0` みたいな値を多めに生成します。
percentage : Fuzzer Float
-- 印字可能なASCII文字の文字列を生成します.
-- `""` も多めに生成します。
-- `""` だと困るようなケースはレベル3で `nonEmptyString` を作りましょう。
string : Fuzzer String
char : Fuzzer Char
레벨 1. 함수 인수로 사용자 정의
먼저
Fuzz
모듈에 제공된 함수에 인수를 제공하여 원래 Fuzzer
를 얻을 수 있습니다.이런 녀석입니다.
intRange : Int -> Int -> Fuzzer Int
floatRange : Float -> Float -> Fuzzer Float
constant : a -> Fuzzer a
다음과 같이 원본
Fuzzer
을 만들 수 있습니다.myInt : Fuzzer Int
myInt = intRange -50 200
{-| さくらちゃんの胃袋のサイズを生成するFuzzer.
マイナスになることはないが、無限に草を食べるので上限が存在しない。
上限が無い場合には `Random.maxInt` を使います。
-}
stomachSize : Fuzzer Int
stomachSize = intRange 0 Random.maxInt
myFloat : Fuzzer Float
myFloat = floatRange -pi pi
{-| 常に同じ文字列を返すFuzzer.
そんなん Property based testing の意味がないじゃん!
ということで、これ単体で使うのではなく、後に紹介する `oneOf` とかと一緒につかいます。
-}
meanLess : Fuzzer String
meanLess = concatant "This always generates same string."
레벨 2. 간단한 합성
레벨 0과 레벨 1의
Fuzzer
에서 Maybe
, Result
, List
와 같은 유형의 Fuzzer
를 만들어 봅시다.maybe : Fuzzer a -> Fuzzer (Maybe a)
result
: Fuzzer error
-> Fuzzer value
-> Fuzzer (Result error value)
list : Fuzzer a -> Fuzzer (List a)
array : Fuzzer a -> Fuzzer (Array a)
{-| 以下のいずれかが生成される.
* `myInt` で生成される `Int` に `Just` をつけたもの
* Nothing
-}
myMaybeInt : Fuzzer (Maybe Int)
myMaybeInt = maybe myInt
myResult : Fuzzer (Result Int Float)
myResult = result myInt myFloat
{-| ランダムな文字列をいくつか並べたリストを生成する.
空リストのこともある。
空リストを含めたくない場合はレベル3の `nonZeroList` を使います。
-}
myList : Fuzzer (List String)
myList = list string
myArray : Fuzzer (Array Bool)
myArray = array bool
레벨 3. 합성 방법을 직접 지정
map : (a -> b) -> Fuzzer a -> Fuzzer b
map2 : (a -> b -> c) -> Fuzzer a -> Fuzzer b -> Fuzzer c
...
andMap : Fuzzer a -> Fuzzer (a -> b) -> Fuzzer b
andThen : (a -> Fuzzer b) -> Fuzzer a -> Fuzzer b
-- 自分で作った型の Fuzzer を作る場合
data Point = Point Int Int
myPoint : Fuzzer Point
myPoint = map2 Point myInt int
-- 特殊な制約がある Fuzzer を作る場合
{-| `""` ではないことが保証されている文字列
1文字目と「空かもしれない文字列」をくっつければ必ず空ではない文字列になります。
-}
nonEmptyString : Fuzzer String
nonEmptyString =
map2
(\c str -> String.fromChar c ++ str)
char string
{-| `[]` ではないListを作る関数
-}
nonZeroList : a -> Fuzzer (List a)
nonZeroList a =
map2 (::) a (list a)
{-| `!` を含まない文字列
逆に限られた文字しか許さない文字列を作りたい場合は、
この方法では空文字列がたくさん生成されてしまうため、レベル4の方法をオススメします。
-}
mySpecialString : Fuzzer String
mySpecialString =
map (String.filter (\c -> c /= '!')) string
레벨 4. 복잡한 사양에 따른 문자열 생성
Parser를 직접 작성하고 테스트하는 경우에 유용합니다.
elm-data-url은 BNF 표기법에 표시된 사양에 따라 문자열을 생성합니다.
그 결과를 다시 문자열로 인코딩한 것과 원래의 문자열이 일치하는지 확인하는 것으로 정상계의 테스트로 하고 있습니다.
BNF로 작성할 필요가 없을 정도로 단순한 것이라면 레벨 3의
String.filter
를 사용한 것으로 충분합니다만, Regex
녀석이라고 생각합니다.-- ListであたえたいずれかのFuzzerを使う
oneOf : List (Fuzzer a) -> Fuzzer a
-- `oneOf` とほぼ同じだけど、Listの要素の各Fuzzerの重要度を指定すると、
-- 重要度が高いFuzzerを優先的に使ってくれる。
frequency : List (Float, Fuzzer a) -> Fuzzer a
겨우, RFC6838의 restricted-name 을 생성하는
Fuzzer
를 만들어 보겠습니다.restrictedName : Fuzzer String
restrictedName =
Fuzz.map2 (++)
restrictedNameFirst
restrictedNameTail
restrictedNameFirst : Fuzzer String
restrictedNameFirst =
Fuzz.map String.fromChar <|
Fuzz.oneOf
[ upper
, lower
, digit
]
restrictedNameTail : Fuzzer String
restrictedNameTail =
Fuzz.map (String.fromList << List.take 126) <|
Fuzz.list <|
Fuzz.oneOf
[ upper
, lower
, digit
, restrictedMark
]
restrictedMark : Fuzzer Char
restrictedMark =
Fuzz.oneOf <| List.map Fuzz.constant [ '!', '#', '$', '&', '-', '^', '_', '.', '+' ]
너만의
Fuzzer
를 얻으십시오!사쿠라 짱에게 밥을 준다.
Reference
이 문제에 관하여([Elm] 너만의 최강 Fuzzer를 손에 넣어라!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/arowM/items/dee354b752472bd9aef3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)