Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

กรณีของชุดทดสอบที่ไม่สม่ำเสมอ

ฉันเพิ่งทำงานกับชุดทดสอบที่น่าผิดหวังมากเมื่อใช้งานเนื่องจากไม่น่าเชื่อถือ

แอปพลิเคชันที่ชุดทดสอบกำหนดเป้าหมายเป็นแอปพลิเคชัน Rails API เท่านั้น การทดสอบเขียนด้วย JavaScript โดยใช้เฟรมเวิร์กที่เรียกว่า Chakram "เฟรมเวิร์กการทดสอบ API ที่ออกแบบมาเพื่อทำการทดสอบแบบ end-to-end บนปลายทาง JSON REST"

ปัญหาของชุดทดสอบคือมันไม่ถูกกำหนด ฟังก์ชันหรือโปรแกรมเป็นตัวกำหนดว่า หากได้รับอินพุตเดียวกัน ให้เอาต์พุตเหมือนกันเสมอ

ชุดทดสอบเฉพาะนี้จะผ่านในการรันครั้งแรก ผ่านในการรันครั้งที่สอง จากนั้นล้มเหลวในการรันครั้งที่สาม โดยไม่มีการเปลี่ยนแปลงใดๆ กับโค้ดแอปพลิเคชันหรือโค้ดทดสอบ

ฉันค้นพบว่าฉันสามารถนำชุดทดสอบกลับมาผ่านได้โดยการทำ rake db:reset . การทดสอบซึ่งดำเนินการบนสภาพแวดล้อมการพัฒนาของแอปพลิเคชัน Rails ไม่ใช่ในสภาพแวดล้อมการทดสอบ ขึ้นอยู่กับฐานข้อมูลของแอปพลิเคชัน Rails ที่อยู่ในสถานะที่แน่นอนเมื่อชุดการทดสอบเริ่มทำงาน

บางครั้งฉันสามารถเริ่มต้นด้วยฐานข้อมูลที่เพาะใหม่ เรียกใช้ชุดทดสอบ แล้วเรียกใช้ชุดทดสอบเป็นครั้งที่สองได้สำเร็จ ฉันอาจจะสามารถเรียกใช้ชุดทดสอบได้สามครั้งหรือมากกว่านั้น แต่บ่อยครั้งที่ชุดทดสอบอาจทำให้ข้อมูลยุ่งเหยิง และฉันต้องทำ rake db:reset อีกครั้ง เพื่อให้ข้อมูลกลับสู่สถานะที่ชุดทดสอบใช้งานได้สำเร็จ

แน่นอนว่านี่ไม่ใช่สิ่งที่ควรจะเป็น ชุดทดสอบควรล้มเหลวด้วยเหตุผลเดียวเท่านั้น:รหัสที่ทดสอบหยุดทำงานอย่างถูกต้อง

สิ่งที่ควรทำแทน

ดังนั้นหากชุดทดสอบนี้ถูกตั้งค่าในลักษณะที่มีปัญหา มันจะเป็นวิธีที่ถูกต้องหรือไม่

ต้นตอของปัญหาคือชุดทดสอบขึ้นอยู่กับการรีเซ็ตฐานข้อมูลที่มนุษย์ทำขึ้นเอง การทดสอบแต่ละรายการในชุดทดสอบควรทำให้ฐานข้อมูลมีสถานะสะอาดและพร้อมโดยอัตโนมัติก่อนที่จะรัน (เป็นเรื่องปกติสำหรับการทดสอบที่จะล้างฐานข้อมูลหลังจากรัน ดังนั้นจึงไม่ "รั่วไหล" ข้อมูลในการทดสอบอื่นๆ ซึ่งไม่จำเป็นอย่างยิ่งหากทุกการทดสอบล้างฐานข้อมูลก่อนเรียกใช้ แต่เป็นมาตรการป้องกันที่ดี )

ชุดทดสอบควรกำหนดเป้าหมายสภาพแวดล้อมการทดสอบของแอปพลิเคชัน Rails ไม่ใช่สภาพแวดล้อมการพัฒนา การกระทำของนักพัฒนาซอฟต์แวร์ในสภาพแวดล้อมการพัฒนาไม่ควรรบกวนการทำงานของชุดทดสอบและในทางกลับกัน

การพึ่งพาที่มีปัญหาประเภทอื่นๆ

ในเรื่องราวของฉัน ปัญหาการพึ่งพาอาศัยกันคือฐานข้อมูลที่ไม่ได้รับการทำความสะอาดอย่างถูกต้อง

การพึ่งพาอาศัยกันที่เป็นปัญหาอีกประเภทหนึ่งคือคำขอเครือข่าย ลองนึกภาพว่าคุณมีชุดทดสอบที่ใช้งานได้กับ Twilio API คุณเรียกใช้ชุดทดสอบในวันอังคารและผ่านไป จากนั้นในวันพุธ คุณเรียกใช้ชุดทดสอบเดียวกันและล้มเหลว โดยที่คุณไม่ทราบ Twilio กำลังมีการหยุดทำงาน และนั่นเป็นสาเหตุที่ชุดทดสอบของคุณล้มเหลว ไม่กี่นาทีต่อมา การหยุดทำงานก็ได้รับการแก้ไข และชุดทดสอบของคุณจะผ่านไปอีกครั้ง

สิ่งนี้ย้อนกลับไปสู่แนวคิดที่ว่าการทดสอบควรล้มเหลวด้วยเหตุผลเดียวเท่านั้น และนั่นคือหากรหัสแอปพลิเคชันของคุณหยุดทำงาน

หากคุณต้องการเขียนการทดสอบโค้ดที่โต้ตอบกับเครือข่าย วิธีที่ดีกว่าที่จะทำได้ (หากคุณใช้ Ruby/Rails) คือการใช้เครื่องมืออย่าง VCR ที่ให้คุณบันทึกคำขอของเครือข่ายแล้วเล่นซ้ำในภายหลังโดยไม่ได้ใช้งานจริง การใช้อินเทอร์เน็ต

กรณีที่การพึ่งพาภายนอกไม่เป็นไร

อาจเป็นที่ถกเถียงกันอยู่ว่าหากแอปพลิเคชันขึ้นอยู่กับ Twilio API และ Twilio API หยุดทำงาน แสดงว่าแอปพลิเคชันหยุดทำงานจริงๆ ดังนั้นการทดสอบจึงควรล้มเหลวจริงๆ เราจะประนีประนอมความคิดนี้กับแนวคิดที่ว่าการทดสอบไม่ควรขึ้นอยู่กับสภาวะภายนอกได้อย่างไร

วิธีที่จะกระทบยอดสองสิ่งนี้คือการสร้างความแตกต่างระหว่างการทดสอบการผสานรวม ซึ่งทดสอบหลายชั้นหรือหลายระบบพร้อมกัน และ การทดสอบหน่วย ซึ่งทดสอบการทำงานชิ้นเดียวแบบแยกส่วน

หากทีมต้องตัดสินใจอย่างมีสติว่าชุดการทดสอบบางชุดจะเข้าถึงบริการภายนอกในเครือข่ายเพื่อให้สามารถทดสอบระบบหลายระบบร่วมกันได้ ก็ไม่มีอะไร "ผิด" เกี่ยวกับเรื่องนี้ (ทางเลือกอื่นคือตัดสินใจว่าจะไม่พยายามทดสอบระบบเหล่านั้นพร้อมกันเลย) ในสถานการณ์สมมตินี้ ทีมงานจะต้องตระหนักว่าชุดทดสอบการรวมระบบขึ้นอยู่กับเครือข่ายไม่รับประกันว่าจะถูกกำหนดและอาจจะหลุดออกไปในบางครั้ง . ชุดทดสอบแบบนี้ควรแยกจากชุดการทดสอบที่นักพัฒนาเรียกใช้บนเครื่องทุกวันเพื่อตรวจสอบการถดถอย

แม้ว่าจะมีข้อยกเว้นสำหรับกฎที่การทดสอบไม่ควรขึ้นอยู่กับสภาวะภายนอก แต่โดยส่วนใหญ่แล้วควรปฏิบัติตามกฎ ซึ่งจะทำให้ชุดการทดสอบของคุณได้รับประโยชน์จากการเป็นตัวกำหนดและเชื่อถือได้