ฉันควรเขียนการทดสอบการรวมระบบเมื่อใด


30

ตามกฎของการทดสอบหน่วย TDD ถูกเขียนขึ้นก่อนรหัสผลิต แต่สิ่งที่เกี่ยวกับการทดสอบการรวมที่ออกกำลังกายปฏิสัมพันธ์ระหว่างวัตถุแบบมีสาย (ไม่ใช่ mocks)?

พวกเขาควรจะเขียนก่อนทดสอบหน่วยหรือหลังรหัสการผลิตเพียงเพื่อทดสอบ "เดินสาย"?

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

คำตอบ:


49

Rspec Bookเป็นหนึ่งในทรัพยากร BDD อื่น ๆ ซึ่งแสดงให้เห็นวงจรเช่นนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ในสาระสำคัญกระบวนการคือ:

While behaviour required
    Write an integration test for a specific behaviour
    While integration test failing
        Write a unit test to fulfil partial behavior
        While unit test failing
            Write code to make unit test pass
        Commit
        While refactoring can be done
            Refactor
            While unit test failing
                Write code to make unit test pass
            Commit
    Push

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

ที่กล่าวว่าการมีกระบวนการในอุดมคติเป็นสิ่งที่ดี มันทำให้คุณมีจุดที่จะประนีประนอม


2
ขอบคุณ @pdr แต่ฉันระบุว่าฉันไม่ได้พูดถึงการทดสอบการยอมรับที่เขียนไว้ก่อน / ที่จุดเริ่มต้นของการทำซ้ำฉันสนใจในการทดสอบบูรณาการระดับล่าง
Chedy2149

@ chedy2149: Akkh พลาดความคิดเห็นนั้น ก่อนที่ฉันจะลบคำตอบของฉันฉันคิดว่าคุณควรเจาะจงมากขึ้นเกี่ยวกับความหมายของ "ระดับล่าง" ในบริบทของการทดสอบการรวม
pdr

ระดับที่ต่ำกว่า: พฤติกรรมที่ไม่ได้ระบุไว้โดยผู้ใช้หรือลูกค้าและที่ใช้ในการทดสอบการโต้ตอบชั้นเรียน / ส่วนประกอบได้คาดหวังโดยนักพัฒนา
Chedy2149

4
ที่จริงแล้วฉันไม่คิดว่ามันจะสร้างความแตกต่างถ้าคุณใส่ "การทดสอบการยอมรับ" หรือ "การทดสอบการรวม" ในภาพนั้น - มันเป็นมุมมองที่เหมาะสำหรับการทดสอบทุกประเภทในระดับนามธรรมที่แตกต่างกัน แต่ปัญหาที่แท้จริงของ IMHO ไม่ใช่ว่าอาจจะ "เสียเวลา" - ปัญหาที่แท้จริงคือการเขียนการทดสอบการรวม "ไว้ล่วงหน้า" กับส่วนต่อประสานสาธารณะซึ่งยังคงใช้การออกแบบด้วยความช่วยเหลือของ TDD ก็เหมือนกับการถ่ายภาพที่ "เป้าหมายเคลื่อนที่ "
Doc Brown

@DocBrown คำตอบของคุณคือรหัสการผลิตและก่อนที่จะปล่อย?
Chedy2149

10

โครงการจริงแสดงให้ฉันเห็นว่ามันเป็นไปไม่ได้ที่จะเขียนการทดสอบหน่วยและจากนั้นการบูรณาการและแม้แต่ทิศทางที่ตรงข้ามเป็นสิ่งที่ผิด :-) ดังนั้นฉันมักจะเขียนการทดสอบหน่วยพร้อมกับการรวมหน่วย

ทำไม? ให้ฉันเขียนว่าฉันเห็นการทดสอบทั้งสองประเภทอย่างไร:

  1. การทดสอบหน่วย - นอกเหนือจาก Wikipedia และข้อมูลทั้งหมดการทดสอบหน่วยช่วยให้คุณจำกัด การออกแบบปรับปรุงโมเดลความสัมพันธ์ของคุณ การไหลง่าย: เมื่อคุณเริ่มพิมพ์โครงการใหม่ / องค์ประกอบใหม่ส่วนใหญ่เวลาที่คุณกำลังทำชนิดของPoC เมื่อคุณทำเสร็จแล้วคุณมักจะมีวิธีการยาวเรียนยาววิธีที่ไม่สอดคล้องกันและชั้นเรียน ฯลฯ

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

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

    นี่เป็นเรื่องสำคัญอย่างยิ่งที่บางครั้งมันบอกกับคุณว่า API ของคุณไม่สมเหตุสมผล

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

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

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

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

คำแนะนำของฉันคืออะไร

ฉันได้เรียนรู้การไหลต่อไปนี้:

  1. พัฒนาโครงกระดูกพื้นฐานของรหัสของคุณ
  2. เขียนการทดสอบการรวมระบบที่บอกว่าเหมาะสมหรือไม่จากมุมมองของผู้บริโภค กรณีการใช้งานเบื้องต้นก็เพียงพอแล้วสำหรับตอนนี้ เห็นได้ชัดว่าการทดสอบใช้งานไม่ได้
  3. เขียนโค้ดพร้อมกับการทดสอบหน่วยสำหรับแต่ละชั้นเรียน
  4. เขียนส่วนที่เหลือ / ขาดการทดสอบการรวม จะเป็นการดีกว่าที่จะใช้การทดสอบเหล่านี้ภายใน # 3 วิธีที่คุณปรับปรุงรหัสของคุณ

โปรดทราบว่าฉันได้ทำการนำเสนอเล็กน้อยเกี่ยวกับการทดสอบหน่วย / การรวมเข้าด้วยกันให้ดูที่สไลด์ # 21 ซึ่งมีการอธิบายโครงกระดูก


5

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

นั่นคือสิ่งที่การทดสอบการรวมเข้ามา:
พวกเขาทดสอบชิ้นส่วนที่สร้างขึ้นใหม่เหล่านี้ซึ่งประกอบด้วยหน่วยที่ผ่านการทดสอบก่อนหน้านี้ในระหว่างการประกอบชิ้นส่วนเหล่านี้เข้าด้วยกัน กรณีที่ดีที่สุดคือการเขียนการทดสอบ ณ จุดนี้ในขณะที่เขียนใบสมัครเอง


ดังนั้นคำตอบของคุณคือหลังจากรหัสการผลิต?
Chedy2149

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

1
@MathewFoscarini - คำตอบที่ปรับปรุงแล้ว หวังว่ามันจะชัดเจนขึ้นในขณะนี้
Ben McDougall

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

3

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

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


มีระดับการทดสอบที่แตกต่างกัน: การทดสอบส่วนประกอบกล่องสีขาวการทดสอบการรวมส่วนประกอบกล่องสีขาว การทดสอบส่วนประกอบกล่องดำการรวมการทดสอบกล่องดำ นอกจากนี้ยังมีการทดสอบระบบการรวม
Alexander.Iljushkin

2

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

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

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

  • ขึ้นอยู่กับโมดูล / ระบบที่คุณต้องการจัดการมันอาจต้องใช้การสำรวจจำนวนมากการกำหนดค่า tinkering การเตรียมข้อมูลตัวอย่างซึ่งต้องใช้เวลาและไม่เหมาะสมกับวงตอบรับสั้น ๆ

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

คุณสามารถหาตัวอย่างของวิธีการนี้ได้ที่นี่: http://davesquared.net/2011/04/dont-mock-types-you-dont-own.html (ย่อหน้าที่ 6) http://blog.8thlight.com/eric- smith / 2011/10/27 / thats ที่ไม่ yours.html


ที่นี่คุณกำลังพูดถึงการทดสอบการรวมที่ตรวจสอบการมีปฏิสัมพันธ์ระหว่าง "ระบบของเรา" และห้องสมุดบุคคลที่สามวิธีการทดสอบการโต้ตอบกับแพลตฟอร์มในขณะที่การพัฒนาปลั๊กอินเช่น?
Chedy2149

แม้ว่าฉันจะมีประสบการณ์เล็กน้อยเกี่ยวกับการพัฒนาปลั๊กอิน แต่ฉันคิดว่ามันอาจจะแตกต่างกันเนื่องจากเป็นธรรมชาติควบคู่กับแอปพลิเคชันโฮสต์อย่างแน่นหนาดังนั้นคุณอาจต้องยอมรับการผสานรวมนั้นอย่างเต็มที่และตัดสินใจว่าคุณไม่ต้องการเลเยอร์อะแดปเตอร์ ในกรณีนี้ฉันจะต้องระมัดระวังอย่างมากเกี่ยวกับประสิทธิภาพของการทดสอบ - ขึ้นอยู่กับแอปพลิเคชันโฮสต์การเรียก API ของมันโดยตรงในการทดสอบจำนวนมากของคุณอาจช้ามาก หากคุณกลัวสิ่งนั้นคุณสามารถใช้แนวทาง "เลเยอร์ของความเป็นนามธรรมเพิ่มเติม" และใช้การทดสอบ mocks + การรวมกับอะแดปเตอร์
guillaume31

1

ดังนั้นฉันจะยอมรับคำตอบแรก แต่มันถูกลบไปแล้ว
วิธีรวมในการคำนวณ
ซ้ำ:

  1. เขียนการทดสอบหน่วย
  2. เขียนรหัสการผลิต
  3. เขียนการทดสอบการรวมเพื่อทดสอบการโต้ตอบ

ระลึกถึงการทดสอบการรวมระบบในขณะที่ 1 และ 2 เพื่อรับประกันความสามารถในการทดสอบในระดับการรวม

การทดสอบการรวมเข้าด้วยกันไม่จำเป็นต้องเขียนตั้งแต่ต้นจนจบในขั้นตอนที่ 3 แต่อาจจะเขียนบางส่วนระหว่างขั้นตอนที่ 1 และ 2


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

จุดที่ดีคำตอบดูเหมือนจะไม่สนใจธรรมชาติซ้ำ ๆ ของการออกแบบผ่านการปรับโครงสร้างใหม่
Chedy2149

0

การทดสอบหน่วยทดสอบบล็อกที่ไม่ต่อเนื่องของรหัสภายในโครงการของคุณ
การทดสอบบูรณาการทดสอบว่าอินเตอร์เฟซรหัสของคุณกับรหัสอื่น: ในคำอื่น ๆ พวกเขาทดสอบอินเทอร์เฟซของรหัสของคุณ

เขียนการทดสอบหน่วยเมื่อพัฒนาโค้ดหลังอินเตอร์เฟส
เขียนการทดสอบการรวมเมื่อพัฒนาส่วนต่อประสานหรือรหัสใด ๆ ที่ใช้ส่วนต่อประสาน

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

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


คุณตกลงที่จะบอกว่าการทดสอบหน่วยคือการทดสอบไวท์บ็อกซ์และการทดสอบการรวมเป็นการทดสอบ blackbox หรือไม่
Chedy2149

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

กล่าวโดยสรุปในบางกรณีการทดสอบการรวมเข้าด้วยกันเป็นการทดสอบกล่องดำ แต่ไม่ใช่ในทุกกรณี
Marco

FYI: Wikiกำหนดการทดสอบจำนวนเต็มว่า "ขั้นตอนในการทดสอบซอฟต์แวร์ที่แต่ละโมดูลรวมและทดสอบเป็นกลุ่ม"
Marco

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