ทั้งสองเป็นกรอบการทดสอบหน่วยที่มีความสามารถ BDD (Behavior Driven Development) สำหรับ Scala ที่เขียนด้วย Scala และข้อกำหนดที่ สร้างขึ้นอาจเกี่ยวข้องกับกรอบงานScalaTest แต่สิ่งที่ Specs เสนอให้ ScalaTest ไม่มี? อะไรคือความแตกต่าง?
ทั้งสองเป็นกรอบการทดสอบหน่วยที่มีความสามารถ BDD (Behavior Driven Development) สำหรับ Scala ที่เขียนด้วย Scala และข้อกำหนดที่ สร้างขึ้นอาจเกี่ยวข้องกับกรอบงานScalaTest แต่สิ่งที่ Specs เสนอให้ ScalaTest ไม่มี? อะไรคือความแตกต่าง?
คำตอบ:
ข้อมูลจำเพาะและ ScalaTest เป็นเครื่องมือที่ดีสำหรับผู้ใช้ที่พึงพอใจ แต่แตกต่างกันในหลายวิธี คุณอาจต้องการเลือกเครื่องมือทดสอบหลักใน Scala แต่ไม่จำเป็นต้องยอมแพ้เพราะคุณสามารถใช้ทั้งสองอย่างได้ ตัวอย่างเช่นหากคุณชอบFeatureSpec
ไวยากรณ์ของ ScalaTest และไวยากรณ์ของ Mockito คุณสามารถใส่ไฟล์ jar ทั้งสองไฟล์ใน classpath ของคุณและใช้ทั้งสองอย่างพร้อมกันได้ ที่นี่ฉันจะพยายามจับความแตกต่างหลักปรัชญาการออกแบบที่ฉันสังเกตเห็นระหว่างข้อมูลจำเพาะและ ScalaTest
อาจเป็นความแตกต่างทางปรัชญาที่สำคัญระหว่างเครื่องมือคือข้อมูลจำเพาะได้รับการออกแบบมาสำหรับ Behavior-Driven Development (BDD) ในขณะที่ ScalaTest มีความกว้างมากกว่า ScalaTest มีลักษณะที่คุณสามารถผสมเข้าด้วยกันเพื่อให้ได้พฤติกรรมที่คุณต้องการในชั้นเรียนทดสอบของคุณรวมถึง BDD และคุณยังสามารถกำหนดพฤติกรรมของคุณเองได้อย่างง่ายดายหากคุณต้องการสิ่งที่แตกต่างออกไป
สนับสนุน ScalaTest BDD ผ่านSpec
, FeatureSpec
, WordSpec
, FlatSpec
และGivenWhenThen
ลักษณะและยังมีลักษณะที่คุณสามารถผสมในการได้รับการจับคู่ที่ดีไวยากรณ์ ถ้าคุณชอบ "ควร" คุณผสมใน ShouldMatchers ถ้าคุณชอบ "ต้อง" MustMatchers
คุณผสมใน แต่ถ้าคุณชอบ BDD แต่ไม่ชอบไวยากรณ์ของตัวจับคู่คุณสามารถใช้ลักษณะ Spec ของ ScalaTest ได้โดยไม่ต้องผสมในลักษณะ matchers Specs มีคลาส Specification ที่คุณขยายและคุณต้องใช้คำว่า "must" ในนิพจน์ตัวจับคู่ของคุณ ความแตกต่างทางปรัชญาที่เห็นได้ชัดคือ ScalaTest ให้ทางเลือกมากมายแก่คุณ เพื่อให้ง่ายต่อการสำรวจพื้นที่นี้ฉันให้แผนผังการตัดสินใจที่นี่:
http://www.scalatest.org/quick_start
ไวยากรณ์การจับคู่ยังแตกต่างกันระหว่าง ScalaTest และข้อกำหนด ใน ScalaTest ฉันพยายามดูว่าฉันจะไปได้ไกลแค่ไหนด้วยสัญกรณ์ตัวดำเนินการและลงเอยด้วยนิพจน์จับคู่ที่อ่านคล้ายประโยคภาษาอังกฤษมากโดยเว้นวรรคระหว่างคำ ไวยากรณ์ตัวจับคู่ข้อมูลจำเพาะเรียกใช้คำร่วมกันมากขึ้นด้วยตัวพิมพ์ใหญ่อูฐ
ข้อมูลจำเพาะมีผู้จับคู่มากกว่า ScalaTest และฉันคิดว่าสะท้อนให้เห็นถึงความแตกต่างในทัศนคติการออกแบบ จริงๆแล้วฉันอาจจะตัด 2/3 ของไวยากรณ์ตัวจับคู่ที่ฉันสร้างและพิจารณาสำหรับการเปิดตัว ฉันจะเพิ่มตัวจับคู่เพิ่มเติมในรุ่นต่อ ๆ ไป แต่อยากให้แน่ใจว่าฉันรู้ว่าผู้ใช้ต้องการบางอย่างจริงๆก่อนที่จะเพิ่ม อย่างไรก็ตามตัวจับคู่ของ ScalaTest มีไวยากรณ์ตัวจับคู่คุณสมบัติแบบไดนามิกจะใช้ค่าหย่อนบางส่วน ตัวอย่างเช่นใน Specs คุณสามารถเขียนบนjava.io.File
:
file must beDirectory
สิ่งนี้จะเรียกisDirectory
และตรวจสอบให้แน่ใจว่าเป็นจริง ScalaTest ไม่มีตัวจับคู่พิเศษสำหรับjava.io.Files
ปัจจุบัน แต่ใน ScalaTest คุณสามารถใช้การตรวจสอบแบบไดนามิกดังนี้:
file must be a ('directory)
เวลาที่คุณผ่านสัญลักษณ์หลังจากbe
นั้นก็จะใช้สะท้อนที่จะมองหา (ในกรณีนี้) วิธีการหรือสาขาที่ชื่อหรือวิธีการตั้งชื่อdirectory
isDirectory
นอกจากนี้ยังมีวิธีสร้างแบบคงที่โดยการกำหนด a BePropertyMatcher
(ซึ่งโดยปกติต้องใช้โค้ดเพียง 2 หรือ 3 บรรทัด) โดยพื้นฐานแล้วใน ScalaTest ฉันพยายามให้ฟังก์ชันการทำงานมากขึ้นโดยใช้ API น้อยลง
ความแตกต่างของทัศนคติในการออกแบบทั่วไปอีกประการหนึ่งระหว่างข้อกำหนดและ ScalaTest เกี่ยวข้องกับการแปลงโดยนัย โดยค่าเริ่มต้นคุณจะได้รับการแปลงโดยนัยเพียงครั้งเดียวเมื่อคุณใช้ ScalaTest ซึ่งเป็นสิ่งที่ทำให้ตัว===
ดำเนินการทุกอย่าง (หากต้องการคุณสามารถ "ปิด" การแปลงโดยนัยนี้ได้ด้วยโค้ดบรรทัดเดียวเหตุผลเดียวที่คุณต้องทำคือถ้าคุณพยายามทดสอบบางอย่างที่มีตัว===
ดำเนินการของตัวเองและคุณได้รับข้อขัดแย้ง ) ScalaTest กำหนด Conversion โดยนัยอื่น ๆ อีกมากมาย แต่หากต้องการใช้คุณจะต้อง "เชิญ" เข้ามาในโค้ดของคุณอย่างชัดเจนโดยการผสมในลักษณะหรือการนำเข้า เมื่อคุณขยายชั้นเรียนSpecification
ในรายละเอียดฉันคิดว่าคุณจะได้รับการแปลงโดยนัยเป็นจำนวนมากโดยค่าเริ่มต้น ฉันไม่แน่ใจว่าจะมีความสำคัญมากแค่ไหนในทางปฏิบัติ แต่ฉันคิดว่าผู้คนจะต้องการทดสอบโค้ดที่ใช้ความหมายของตัวเองและบางครั้งอาจมีความขัดแย้งระหว่างนัยของกรอบการทดสอบและรหัสการผลิต เมื่อเป็นเช่นนั้นฉันคิดว่าการแก้ไขปัญหาใน ScalaTest อาจง่ายกว่าข้อกำหนด
ความแตกต่างในทัศนคติการออกแบบที่ฉันสังเกตเห็นคือความสะดวกสบายกับผู้ปฏิบัติงาน เป้าหมายอย่างหนึ่งที่ฉันมีคือโปรแกรมเมอร์ที่ดูรหัสทดสอบของคนอื่นที่ใช้ ScalaTest จะสามารถเดาความหมายได้โดยไม่ต้องค้นหาอะไรในเอกสาร ScalaTest ฉันต้องการให้รหัสไคลเอนต์ ScalaTest ลดลงอย่างชัดเจน วิธีหนึ่งที่แสดงให้เห็นถึงเป้าหมายคือ ScalaTest มีความระมัดระวังเกี่ยวกับตัวดำเนินการ ฉันกำหนดเพียงห้าตัวดำเนินการใน ScalaTest:
===
ซึ่งหมายความว่าเท่ากับ>
ซึ่งหมายความว่ามากกว่า<
, น้อยกว่า>=
มากกว่าหรือเท่ากับ<=
น้อยกว่าหรือเท่ากับแค่นั้นแหละ. ดังนั้นสิ่งเหล่านี้ดูเหมือนความหมาย หากคุณเห็นในรหัสของคนอื่น:
result should be <= 7
ความหวังของฉันคือคุณไม่จำเป็นต้องเรียกใช้เอกสาร API เพื่อเดาว่ามัน<=
หมายถึงอะไร ในทางตรงกันข้ามข้อมูลจำเพาะจะเป็นอิสระกว่ามากสำหรับตัวดำเนินการ ไม่มีอะไรผิดปกติ แต่มันเป็นความแตกต่าง ผู้ประกอบการสามารถให้รหัสอื่น ๆ กระชับ แต่ถ่วงดุลอำนาจคือการที่คุณอาจต้องใช้เอกสารเมื่อคุณพบสิ่งที่ต้องการ ->-
, >>
, |
, |>
, !
หรือ^^^
(ซึ่งทุกคนมีความหมายพิเศษในรายละเอียด) ในรหัสการทดสอบเพื่อนร่วมงานของคุณ
ความแตกต่างทางปรัชญาอีกประการหนึ่งคือฉันพยายามทำให้ง่ายขึ้นเล็กน้อยใน ScalaTest เพื่อใช้รูปแบบการทำงานเมื่อคุณต้องการแชร์ฟิกซ์เจอร์ในขณะที่ Specs โดยค่าเริ่มต้นจะยังคงประเพณีของsetUp
และtearDown
แนวทางที่ได้รับความนิยมโดย JUnit ซึ่งคุณกำหนด vars ใหม่ ก่อนการทดสอบแต่ละครั้ง อย่างไรก็ตามหากคุณต้องการทดสอบวิธีนั้นก็ทำได้ง่ายมากใน ScalaTest คุณเพียงแค่ต้องผสมในBeforeAndAfter
ลักษณะ
สำหรับข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับ ScalaTest คุณสามารถรับชมการนำเสนอ "Get Higher with ScalaTest" ที่ฉันมอบให้ในการประชุม Devoxx ปี 2009 ได้ที่นี่:
http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about
ความแตกต่างที่สำคัญคือ (ส่วนใหญ่มาจากมุมมองรายละเอียด :-)):
ScalaTest ให้ "รูปแบบการทดสอบ" มากกว่าข้อกำหนด (คุณสามารถไปที่หัวข้อย่อยแต่ละหัวข้อในหน้าเริ่มต้นอย่างรวดเร็วเพื่อดูรายละเอียดของแต่ละสไตล์)
ScalaTest และข้อมูลจำเพาะมีชุดตัวจับคู่ที่แตกต่างกัน คุณสามารถเปรียบเทียบได้ที่นี่สำหรับ ScalaTest และที่นี่สำหรับรายละเอียด ในด้านนั้นข้อมูลจำเพาะมีคุณสมบัติเล็ก ๆ มากมายที่คุณอาจชอบเมื่อเขียนข้อมูลจำเพาะของคุณ: ตัวจับคู่ xml, องค์ประกอบของเมทเชอร์ (วิธีง่ายๆในการนำตัวจับคู่กลับมาใช้ใหม่โดยการแปลงร่าง), ความล้มเหลวที่แม่นยำ, ความแตกต่างโดยละเอียดสำหรับสตริงที่ยาว, .. .
Mockito ได้รับการสนับสนุน BDD ที่ดีในรายละเอียด: Mockito
ข้อมูลจำเพาะมีDataTablesซึ่งอนุญาตให้จัดกลุ่มตัวอย่างขนาดเล็กจำนวนมากในตารางประเภทต่างๆ (หากคุณสามารถยืนตัวดำเนินการที่ใช้เป็นตัวคั่นตารางได้)
ในข้อกำหนดคุณสามารถกำหนดตัวอย่างที่ซ้อนกันเป็น libidum และล้างข้อมูลโดยอัตโนมัติในทุกระดับ
นี่เป็นการเปรียบเทียบบางส่วนและลำเอียงและมีความแตกต่างอื่น ๆ อีกมากมาย (และห้องสมุดยังคงพัฒนาอยู่ ... )
ในตอนท้ายของวันฉันคิดว่ามันขึ้นอยู่กับการทดสอบ / รูปแบบการระบุของคุณจริงๆ ถ้ามันเรียบง่าย (โครงสร้างข้อกำหนดอย่างง่ายการตั้งค่าความคาดหวัง ... ) ไลบรารีทั้งสองจะดูเหมือนกันมาก มิฉะนั้นทั้งคู่จะมีส่วนร่วมในการทำสิ่งต่างๆ ในฐานะที่เป็นตัวอย่างสุดท้ายนี้คุณสามารถมีดูที่การติดแท็ก: ในScalaTestและในรายละเอียด
ฉันหวังว่านี่จะช่วยได้.
เท่าที่ฉันรู้การยกเว้นคุณสมบัติพิเศษบางอย่างมันขึ้นอยู่กับความชอบส่วนบุคคลตามสไตล์
การสนับสนุน IDE อาจเป็นอีกจุดหนึ่ง
ฉันพยายามทำให้ Specs ทำงานร่วมกับ Eclipse ผ่าน JUnit และพบว่าวิธีแก้ปัญหาอย่างเป็นทางการนั้นค่อนข้าง "แฮ็ก" การตั้งค่าข้อกำหนด: http://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specification_with_JUnit4_in_Eclipse
การผสานรวมของ ScalaTest (ผ่าน JUnit) ด้วยดูเหมือนจะแฮ็คน้อยกว่าเล็กน้อย ถึงกระนั้นฉันยังไม่มีพวกมันที่จะทำงานได้ดีเท่ากับ JUnit และ Java
การตั้งค่า ScalaTest: http://groups.google.com/group/scalatest-users/web/running-scalatest-from-eclipse
หากปัจจัยในการตัดสินใจอย่างหนึ่งคือเวลาในการคอมไพล์scalatest น่าจะทำงานได้ดีกว่า
ขณะนี้เรากำลังใช้ spec2 ในโครงการของเรา แต่ประสบปัญหาการคอมไพล์ช้าในการทดสอบ ฉันเพิ่งเสร็จสิ้น POC ในการย้ายไปที่ scalatest และเห็นเวลาในการคอมไพล์ลดลงประมาณ 0.82 เพียงแค่เปลี่ยน 2 เฟรมเวิร์กในแหล่งข้อมูลบางส่วนของเรา