ในแบบฝึกหัดฉันต้องการใช้ต้นไม้นิ้ว 2-3 นั่นควรเป็นโอกาสอันดีที่จะลองใช้การทดสอบตามแบบจำลองของ FsCheck ฉันตัดสินใจลองใช้เวอร์ชันทดลองที่ใหม่กว่า
จนถึงตอนนี้ ฉันเขียนโค้ดเพียงคำสั่งเดียวสำหรับเครื่องทดสอบเพราะฉันล้มเหลวในการทำงานนั้น ในทางกลับกัน มันทำให้การโพสต์สั้นลง รหัสเต็มมีอยู่ที่ GitHub
open CmdQ
open Fuchu
open FsCheck
open FsCheck.Experimental
type TestType = uint16
type ModelType = ResizeArray<TestType>
type SutType = FingerTree<TestType>
let spec =
let prepend (what:TestType) =
{ new Operation<SutType, ModelType>() with
override __.Run model =
// Also tried returning the same instance.
let copy = model |> ResizeArray
copy.Insert(0, what)
copy
override __.Check(sut, model) =
let sutList = sut |> Finger.toList
let newSut = sut |> Finger.prepend what
let newSutList = newSut |> Finger.toList
let modelList = model |> Seq.toList
let areEqual = newSutList = modelList
areEqual |@ sprintf "prepend: model = %A, actual = %A (incoming was %A)" modelList newSutList sutList
override __.ToString() = sprintf "prepend %A" what
}
let create (initial:ModelType) =
{ new Setup<SutType, ModelType>() with
override __.Actual () = initial |> Finger.ofSeq
override __.Model () = initial //|> ResizeArray // Also tried this.
}
let rndNum () : Gen<TestType> = Arb.from<uint16> |> Arb.toGen
{ new Machine<SutType, ModelType>() with
override __.Setup =
rndNum()
|> Gen.listOf
|> Gen.map ResizeArray
|> Gen.map create
|> Arb.fromGen
override __.Next _ = gen {
let! cmd = Gen.elements [prepend]
let! num = rndNum()
return cmd num
}
}
[<Tests>]
let test =
[spec]
|> List.map (StateMachine.toProperty >> testProperty "Finger tree")
|> testList "Model tests"
สิ่งที่ฉันเข้าใจคือ: Operation<_>.Run
ถูกรันสองครั้งเพื่อสร้าง ResizeArray
จากองค์ประกอบเดียว จากนั้น Operation<_>.Check
จะถูกรันสองครั้งด้วยตัวเลขเดียวกันเพื่อแทรกลงในองค์ประกอบเดียว FingerTree<_>
ครั้งแรกของทั้งสองผ่านไป ขาเข้าของแผนผังองค์ประกอบเดียว การเพิ่มทำให้เป็นแผนผังสององค์ประกอบ (ถูกต้อง) ซึ่งเปรียบเทียบได้ดีกับโมเดลหลังจากคำสั่งแรก
คำสั่งที่สองคือคำสั่งที่ล้มเหลวเสมอ Check
ถูกเรียกด้วย ResizeList
ที่ใหญ่กว่า (ตอนนี้มี 3 องค์ประกอบ) แต่เป็น Tree องค์ประกอบเดียวเดียวกันกับในคำสั่งแรก แน่นอนว่าการเพิ่มอีกหนึ่งองค์ประกอบไม่ได้ทำให้เป็นขนาด 3 และการทดสอบล้มเหลว
ฉันคาดหวังว่าจะต้องส่งคืนโมเดลที่อัปเดตจาก Check
เพื่อให้คำสั่งมา แต่คุณต้องส่งคืน Property
ดังนั้นจึงไม่สามารถทำได้
ฉันเข้าใจผิดโดยสิ้นเชิงว่าจะเข้าใกล้สิ่งนี้อย่างไร? การทดสอบตามแบบจำลองการทำงานควรเขียนอย่างไร?