การทดสอบหน่วยควรครอบคลุมซอฟต์แวร์ 'ที่ใช้งานได้' เท่านั้น


9

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

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

ตัวอย่างของสิ่งนี้คือ;

var repositories = container.GetAllInstances<IEnvironmentRepository>();
Assert.AreEqual(1, repositories .Count());
foundInstances = foundInstances + repositories .Count();

นอกจากนี้เรายังมี 'การทดสอบหน่วย' สำหรับคลาสต่อไปนี้

public MyClass(IEnvironmentRepository environmentRepository)
        {

        }

ในการทดสอบเหล่านี้เราเยาะเย้ย IEnvironmentRepository ดังนั้นจะไม่ถูกฉีดจากภาชนะที่จะเกิดขึ้นในระบบสด

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

ดังนั้นคำถามมากมาย

  • เป็นการทดสอบหน่วยที่ถูกต้อง - เรากำลังทดสอบการกำหนดค่าของคอนเทนเนอร์ของเราไม่ใช่ structuremap นั้นใช้งานได้ (แต่ฉันเห็นการทับซ้อนกัน)
  • หากไม่เป็นเช่นนั้นคุณจะตรวจสอบความถูกต้องของการกำหนดค่าโดยไม่ทำการทดสอบได้อย่างไร คุณจะหยุดบางคนตั้งใจลบบรรทัดของรหัสที่ต้องการและตรวจสอบได้อย่างไร
  • การMyClassทดสอบหน่วยควรแก้ไขอินสแตนซ์ของIEnvironmentRepositoryจากคอนเทนเนอร์และส่งผ่านสิ่งนี้หรือไม่

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

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

4
เพื่อนร่วมงานของคุณมีจุดเมื่อเขาบอกว่าจะไม่ทดสอบการกำหนดค่าดังนั้นเนื่องจากการกำหนดค่าของแท้ที่สามารถเปลี่ยนแปลงได้จริงต่อการปรับใช้ไม่สามารถ / ไม่ควรทดสอบใครจะพูดว่า "สีแดง" ผิดและ "สีน้ำเงิน" ไม่ใช่? การทดสอบจะถูกผนวกเข้ากับการตั้งค่าเดียวอย่างแน่นหนา แต่การกำหนดค่าที่เชื่อมโยงกับส่วนของโค้ดนั้นเป็นข้อยกเว้นเล็กน้อยเนื่องจากมันไม่ได้แตกต่างกันและมีวิธีที่ชัดเจนในการทำให้มันผิด เป็นการดีที่คุณจะมีการกำหนดค่าดังกล่าวที่สร้างเมื่อสร้างจากข้อมูลเมตา DRY แต่สิ่งนี้ไม่เป็นไปได้ที่การทดสอบเช่นนี้จะเพิ่มมูลค่า ดีกว่าข้อผิดพลาดในการปรับใช้ที่หลีกเลี่ยงได้
Jeroen Mostert

2
สิ่งที่คุณกำลังอธิบายไม่ได้ทดสอบหน่วยมันจะทดสอบการกำหนดค่าของซอฟต์แวร์ของบุคคลที่สาม มันมีประโยชน์อย่างมากที่จะมีการทดสอบที่ทดสอบสิ่งเหล่านี้ แต่เป็นการทดสอบการรวมระบบไม่ใช่การทดสอบหน่วยและการตัดการเชื่อมต่ออาจมีรากเหง้าของความไม่ลงรอยกัน
Phoshi

3
@ChrisBint ความดีงามดีไม่ฉันได้เขียนกลุ่มของคอนเทนเนอร์ทดสอบตัวเอง พวกเขามีค่ามากพวกเขาไม่ได้ทดสอบหน่วย ที่ดีของการทดสอบการรวมมีคุณค่ามากสำหรับการจับการทดสอบสิ่งที่หน่วยไม่สามารถ
Phoshi

คำตอบ:


13

นี่คือการทดสอบอัตโนมัติที่ถูกต้องสมบูรณ์แบบที่จะมี ฉันเรียกพวกเขาว่า "การทดสอบสถาปัตยกรรม" เนื่องจากยืนยันความสมบูรณ์ขององค์ประกอบโครงกระดูกของรหัสฐานของคุณ

คอนเทนเนอร์ IoC สามารถแก้ไขและเขียนแผนผังวัตถุทั้งหมดในแอปพลิเคชันได้หรือไม่ Mapper อัตโนมัติสามารถแมประหว่างวัตถุที่ลงทะเบียนทั้งหมดโดยไม่ล้มเหลวได้หรือไม่? เลเยอร์กลางในสถาปัตยกรรมหัวหอมไม่อ้างอิงสิ่งภายนอกหรือไม่?

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

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


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

6

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

ในกรณีของคุณเมื่อใดก็ตามที่คุณเปลี่ยนการตั้งค่าคอนเทนเนอร์บางทีคุณอาจมีการพึ่งพาใหม่ที่ต้องการฉีดคุณทำลายการทดสอบของคุณ

นอกจากนี้หากคุณเพิ่มข้อกำหนดการพึ่งพาพิเศษ แต่ลืมเพิ่มลงในคอนเทนเนอร์และเปลี่ยนการทดสอบคอนเทนเนอร์ ทุกอย่างจะผ่าน แต่โปรแกรมของคุณจะพัง

การทดสอบอัตโนมัติที่ดีกว่าคือการเริ่มต้นโปรแกรมและดูว่ามันขัดข้องหรือไม่

คุณควรตรวจจับข้อผิดพลาดประเภทนี้ที่การรวมหรือการทดสอบ UI แม้ว่าจะผ่านการทดสอบหน่วย

ต้องบอกว่าความซับซ้อนที่เพิ่มขึ้นของการตั้งค่าคอนเทนเนอร์เป็นความเจ็บปวดในตูด บางทีการทดสอบที่ 'ไม่ดี' บางอย่างก็คุ้มค่า


1

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


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

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

2
การทดสอบหน่วยใช้เวลา 10 นาทีในการเคาะ การปรับใช้อาจใช้เวลามากกว่าหนึ่งชั่วโมง
ChrisBint

1
ส่วนที่ได้รับจากการทดสอบหน่วยตรวจสอบความถูกต้องของการมีอยู่ของบรรทัดเดียวในการกำหนดค่าโดยเฉพาะไม่แน่ใจว่าจะไม่สามารถแยกได้มากขึ้น การนับทั่วไปที่ฉันเห็นด้วย
ChrisBint

1
อาจมีบางไมล์สะสมในพวกเขา - การตัดสินเรียกร้องให้คุณจริงๆ แต่พวกเขาควรจะแยกออกทางร่างกายหรือผ่านคุณลักษณะบางอย่าง
Robbie Dee

0

ความรับผิดชอบของคอนเทนเนอร์ฉีดพึ่งพาคือการติดโมดูลที่แตกต่างกันในการใช้งานหนึ่ง

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

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

คุณไม่จำเป็นต้องครอบคลุมกรณีทดสอบที่เป็นไปได้ทั้งหมดในการทดสอบการรวมเพียงหนึ่งกรณีทดสอบต่อหนึ่งฟีเจอร์ที่ครอบคลุมตั้งแต่ UI จนถึงฐานข้อมูล

หากกรณีทดสอบการรวมระบบไม่ครอบคลุมการสร้างอินสแตนซ์ของการพึ่งพาบางอย่าง - คุณเพียงแค่เพิ่มสิ่งนั้น

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


0

IMO คำตอบคือ:

  1. เป็นการทดสอบหน่วยที่ถูกต้อง - เรากำลังทดสอบการกำหนดค่าของคอนเทนเนอร์ของเราไม่ใช่ structuremap นั้นใช้งานได้ (แต่ฉันเห็นการทับซ้อนกัน)

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

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

    • ไม่นี่คือการทดสอบหน่วยที่สมบูรณ์แบบเพราะคุณเยาะเย้ยการพึ่งพาและทดสอบตรรกะ MyClass อย่างแยก

-1

UnitTestตรวจสอบพฤติกรรมที่ต้องการของหน่วยในการแยกในการคัดแยก

ที่นี้หมายถึงชนิดของใด ๆการกำหนดค่าเป็นไม่ได้อยู่ในขอบเขตของunittests unittests

อย่างไรก็ตามคุณควรได้โดยอัตโนมัติทดสอบสำหรับการกำหนดค่าของคุณ แต่เหล่านี้จะไม่unittests ...


คุณได้คำจำกัดความของหน่วยที่ไหน
ChrisBint

ฉันชอบหนึ่งในRoy OsheroveในThe Art Of Unittesting : ยูนิตคือโค้ดอันใดอันหนึ่ง (การผลิต -) ที่มีเหตุผลเดียวกันในการเปลี่ยนแปลง ฉันโลกของฉันนี้มักจะมีตั้งแต่ชั้นเดียวถึงสามหรือห้า ...
ทิโมธียอมจำนน

นี่คือรหัสการผลิตที่กำลังทดสอบ
ChrisBint

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