การทดสอบหน่วย - เริ่มต้น


14

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

  1. ฉันคิดว่าจุดประสงค์ของการทดสอบหน่วยคือการทดสอบโค้ดที่เราเขียน อย่างไรก็ตามสำหรับฉันดูเหมือนว่าเพื่อให้สามารถเรียกใช้การทดสอบเราต้องเปลี่ยนรหัสต้นฉบับ ณ จุดที่เราไม่ได้ทดสอบรหัสที่เราเขียนจริง ๆ แต่เป็นรหัสที่เราเขียนเพื่อทำการทดสอบ

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

ขออภัยถ้าฉันเป็นใบ้ที่นี่ แต่ฉันคิดว่าบางคนสามารถสอนฉันสักหน่อย

ขอบคุณล่วงหน้า.

คำตอบ:


7

0.02 $ ของฉัน ... นี่เป็นอัตวิสัยเล็กน้อยดังนั้นให้เอาเม็ดเกลือมาด้วย แต่หวังว่ามันจะทำให้คุณคิดและ / หรือจุดประกายการโต้ตอบ:

  1. วัตถุประสงค์หลักของการทดสอบหน่วยให้ฉันคือเพื่อให้แน่ใจว่ารหัสที่คุณเขียนตอบสนองสัญญาและกรณีขอบรหัสของคุณมีวัตถุประสงค์เพื่อตอบสนอง ด้วยการทดสอบหน่วยในสถานที่คุณสามารถมั่นใจได้ว่าเมื่อคุณ (หรือคนอื่น ๆ ในอนาคต) refactors รหัสของคุณผู้บริโภคภายนอกของรหัสของคุณควรจะยังคงได้รับผลกระทบหากคุณมีความครอบคลุมของรัฐที่เหมาะสม (อย่างน้อยก็ในระดับที่คุณต้องการให้พวกเขาไม่ได้รับผลกระทบ)

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

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

    ตามหลักแล้วโค้ดของคุณควรพึ่งพาสัญญา API ของส่วนประกอบบุคคลที่สามซึ่งหมายความว่าตราบใดที่ mocks ของคุณปฏิบัติตาม API ที่ถูกต้องการทดสอบหน่วยของคุณยังคงให้คุณค่า

    ที่กล่าวว่าฉันจะยอมรับว่ามีหลายครั้งที่ฉันได้ทำการทดสอบหน่วยในความโปรดปรานของการทดสอบบูรณาการเพียงอย่างเดียว แต่นั่นเป็นเพียงกรณีที่รหัสของฉันมีการโต้ตอบอย่างมากมายกับส่วนประกอบของบุคคลที่สามที่มี API ที่ไม่ดี (เช่นข้อยกเว้นมากกว่ากฎ)


5
  1. ลองเขียนแบบทดสอบก่อน ด้วยวิธีนี้คุณจะมีฐานที่มั่นคงสำหรับพฤติกรรมของรหัสของคุณและการทดสอบของคุณจะกลายเป็นสัญญาสำหรับพฤติกรรมที่ต้องการของรหัสของคุณ ดังนั้นการเปลี่ยนรหัสที่จะผ่านการทดสอบจะกลายเป็น "การเปลี่ยนรหัสเพื่อปฏิบัติตามสัญญาที่เสนอโดยการทดสอบ" แทน "การเปลี่ยนรหัสเพื่อผ่านการทดสอบ"
  2. ดีระวังเกี่ยวกับความแตกต่างระหว่างต้นขั้วและ mocks การไม่ได้รับผลกระทบจากการเปลี่ยนแปลงใด ๆ ในโค้ดคือพฤติกรรมลักษณะของสตับ แต่ไม่ใช่ mocks ให้เริ่มต้นด้วยคำจำกัดความของจำลอง:

    วัตถุจำลองแทนที่วัตถุจริงภายใต้เงื่อนไขการทดสอบและอนุญาตให้ตรวจสอบการโทร (การโต้ตอบ) กับตัวเองเป็นส่วนหนึ่งของระบบหรือการทดสอบหน่วย

    - ศิลปะการทดสอบหน่วย

โดยทั่วไป mocks ของคุณควรตรวจสอบพฤติกรรมที่ต้องการของการโต้ตอบของคุณ ดังนั้นหากการโต้ตอบของคุณกับฐานข้อมูลล้มเหลวหลังจากทำการเปลี่ยนใหม่การทดสอบโดยใช้จำลองก็ควรจะล้มเหลวเช่นกัน หลักสูตรนี้มีข้อ จำกัด แต่ด้วยการวางแผนอย่างรอบคอบ mocks ของคุณจะทำอะไรได้มากกว่าเพียงแค่ "นั่งอยู่ตรงนั้น" และมันจะไม่ "เอาชนะวัตถุประสงค์ของการทดสอบหน่วย"


1

การถามคำถามที่ดีนั้นไม่ได้โง่ไป แต่อย่างใด

ฉันจะตอบคำถามของคุณ

  1. วัตถุประสงค์ของหน่วยการทดสอบไม่ได้ที่จะทดสอบรหัสที่คุณแล้วเขียน มันไม่มีความคิดเรื่องเวลา เฉพาะใน TDD เท่านั้นที่คุณควรทำการทดสอบก่อน แต่นั่นไม่ได้ใช้กับการทดสอบหน่วยใด ๆ อย่างเคร่งครัด ประเด็นคือเพื่อให้สามารถทดสอบโปรแกรมของคุณโดยอัตโนมัติและมีประสิทธิภาพในระดับชั้นเรียน คุณทำสิ่งที่คุณต้องทำเพื่อที่จะได้มีแม้ว่ามันจะหมายถึงการเปลี่ยนรหัส และให้ฉันบอกความลับแก่คุณ - บ่อยครั้งก็หมายความว่า
  2. เมื่อคุณเขียนการทดสอบคุณมี 2 ตัวเลือกหลักเพื่อช่วยให้การทดสอบของคุณถูกต้อง:

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

    นี่คือตัวอย่าง:

    TEST(MyTest, TwoPlusTwoIsFour) {
        ASSERT_EQ(4, 2+2);
    }
    
    TEST(MyTest, TwoPlusThreeIsntFour) {
        ASSERT_NE(4, 2+3);
    }
    

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

เมื่อคุณทำการทดสอบในระดับชั้นเรียนแล้วคุณสามารถไปทดสอบการรวมกลุ่มระหว่างชั้นเรียนของคุณ (ผู้ไกล่เกลี่ยจากสิ่งที่ฉันเข้าใจ) และห้องสมุดบุคคลที่สาม การทดสอบเหล่านี้เรียกว่าการทดสอบการรวมและไม่ใช้ mocks แต่เป็นการใช้งานที่เป็นรูปธรรมของทุกชั้นเรียน มันช้าลงเล็กน้อย แต่ก็ยังสำคัญมาก!


1

ดูเหมือนคุณจะมีแอพพลิเคชั่นขนาดใหญ่ที่ทำทุกอย่างvoid main()ตั้งแต่ฐานข้อมูลจนถึงการสร้างเอาต์พุต มีหลายขั้นตอนที่นี่ก่อนที่คุณจะเริ่มการทดสอบหน่วยที่เหมาะสม

1) ค้นหาชิ้นส่วนของรหัสที่ถูกเขียน / คัดลอกวางมากกว่าหนึ่งครั้ง string fullName = firstName + " " + lastNameถึงแม้ว่ามันจะเป็นเพียง แยกเป็นวิธีเช่น:

private static string GetFullName (firstName, lastName)
{
    return firstName + " " + lastName;
}

ตอนนี้คุณมีโค้ดส่วนหนึ่งที่ทดสอบได้ แต่อาจเล็กน้อย เขียนการทดสอบหน่วยสำหรับมัน ล้างและทำซ้ำขั้นตอนนี้ ในที่สุดคุณจะจบลงด้วยการโหลดวิธีการจัดกลุ่มตามหลักเหตุผลและคุณสามารถแยกคลาสออกได้ คลาสเหล่านี้ส่วนใหญ่จะสามารถทดสอบได้

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


0

ผู้ชายที่ฉลาดบางคนพูดว่า "ถ้ามันยากที่จะทดสอบอาจเป็นโค้ดที่ไม่ดี" นั่นเป็นเหตุผลว่าทำไมการเขียนโค้ดซ้ำจึงไม่ใช่เรื่องที่เลวร้าย รหัสที่มีการอ้างอิงภายนอกคือ VARD HARD ที่จะทำการทดสอบซึ่งจะแสดงถึงการคัดลอกรหัสและควรหลีกเลี่ยงเมื่อใดก็ตามที่เป็นไปได้ คลาสประเภทซุ้ม / เกตเวย์ สิ่งนี้จะทำให้การเปลี่ยนแปลงในองค์ประกอบภายนอกง่ายต่อการจัดการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.