เราจะทำให้การทดสอบหน่วยทำงานอย่างรวดเร็วได้อย่างไร


40

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

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

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

แก้ไข:เพื่อเป็นการตอบสนองต่อคำตอบหลาย ๆ คำเราใช้ CI และ build server อยู่แล้วนี่คือวิธีที่ฉันรู้ว่าการทดสอบล้มเหลว ปัญหา (จริง ๆ แล้วเป็นอาการ) คือเราได้รับข้อความเกี่ยวกับงานสร้างที่ล้มเหลว ใช้การทดสอบบางส่วนเป็นสิ่งที่คนส่วนใหญ่ทำ แต่ไม่ใช่ทั้งหมด และเกี่ยวกับการทดสอบพวกเขาทำได้ค่อนข้างดีพวกเขาใช้ของปลอมสำหรับทุกสิ่งและไม่มี IO เลย


8
รับฮาร์ดแวร์ที่ดีกว่า ฮาร์ดแวร์มีราคาถูกเมื่อเทียบกับเวลาโปรแกรมเมอร์
ไบรอัน Oakley

18
คุณได้บ่งบอกถึงวิธีแก้ปัญหาในคำถามของคุณแล้ว: เรียกใช้การทดสอบที่เกี่ยวข้องกับชิ้นส่วนของรหัสที่เปลี่ยนไปเท่านั้น รันชุดทดสอบทั้งหมดเป็นระยะซึ่งเป็นส่วนหนึ่งของวงจร QA / Release ที่กล่าวว่า 2 ถึง 3 นาทีดูเหมือนจะไม่ค่อยมีเวลามากนักดังนั้นเป็นไปได้ว่าทีมนักพัฒนาของคุณกำลังตรวจสอบสิ่งต่าง ๆ บ่อยเกินไป
Robert Harvey

3
เกณฑ์มาตรฐานแรกเพื่อพิจารณาว่าต้นทุนมาจากไหน มีการทดสอบราคาแพงเล็กน้อยหรือเป็นจำนวนการทดสอบที่แท้จริงหรือไม่? การตั้งค่าบางอย่างมีราคาแพงหรือไม่
CodesInChaos

13
ประณามฉันหวังว่าการทดสอบของเราจะใช้เวลาเพียง 2-3 นาที ในการรันการทดสอบหน่วยทั้งหมดของเราใช้เวลา 25 นาทีและเรายังไม่มีการทดสอบการรวมเข้าด้วยกัน
Izkata

4
2 ถึง 3 นาที? Jeez เราสามารถเรียกใช้ชั่วโมง ...
ร็อดดีของการแช่แข็ง Peas

คำตอบ:


51

ทางออกที่เป็นไปได้ก็คือการย้ายส่วนการทดสอบจากเครื่องพัฒนาไปยังการตั้งค่าการรวมอย่างต่อเนื่อง ( เช่นเจนกินส์ ) โดยใช้ซอฟต์แวร์ควบคุมเวอร์ชันของรสชาติบางอย่าง ( git , svn , etc ... )

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

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

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

คำแนะนำที่ดีเกี่ยวกับวิธีการตั้งค่าดังกล่าวสามารถพบได้ที่นี่ (เฉพาะ git แต่ควรใช้กับระบบควบคุมเวอร์ชันอื่น ๆ ): http://nvie.com/posts/a-successful-git-branching-model/


15
นี้. หากนักพัฒนา "หยุดกวนการทำงาน (การทดสอบหน่วย) ก่อนที่จะทำการเช็คอิน" คุณต้องให้การตั้งค่า CI ของคุณทำงานหลังจากการเช็คอิน
Carson63000

+1: การปรับปรุงเพิ่มเติมคือการทำให้การทดสอบเป็นโมดูล หากโมดูล / ไฟล์ที่ระบุไม่เปลี่ยนแปลงตั้งแต่การรันครั้งล่าสุดไม่มีเหตุผลที่จะทำการทดสอบอีกครั้งที่รับผิดชอบการทดสอบ การเรียงลำดับเช่น makefile ไม่ได้คอมไพล์ใหม่ทุกอย่างเพียงเพราะมีการเปลี่ยนแปลงไฟล์หนึ่งไฟล์ สิ่งนี้อาจต้องใช้งานบางอย่าง แต่อาจจะให้การทดสอบที่สะอาดยิ่งขึ้นเช่นกัน
Leo

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

ฉันไม่มีประสบการณ์ส่วนตัวในการทำงานกับ TFS อย่างไรก็ตามฉันสามารถเจอคู่มือนี้จาก Microsoft ซึ่งดูเหมือนว่าจะแสดงกลยุทธ์การแยกสาขาที่คล้ายคลึงกับรายการในโพสต์: msdn.microsoft.com/en-us/magazine/gg598921.aspx
Mike

33

การทดสอบหน่วยส่วนใหญ่ควรใช้เวลาไม่เกิน 10 มิลลิวินาทีในแต่ละครั้ง มีเกือบพันทดสอบ 'คืออะไรและควรใช้เวลาอาจจะไม่กี่วินาทีในการวิ่ง

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


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

2
คุณถูกต้องว่าสิ่งเหล่านี้ดูเหมือนจะเป็นการทดสอบการรวมเข้าด้วยกัน
Tom Squires

9
คำตอบนี้ไม่ได้ผล ประการแรกเป็นการตั้งค่าความคาดหวังที่ไม่สมเหตุสมผล มีค่าโสหุ้ยในกรอบการทดสอบหน่วย การทดสอบแต่ละครั้งใช้เวลาน้อยกว่าหนึ่งมิลลิวินาทีไม่ได้หมายความว่าการทดสอบหนึ่งพันครั้งต้องใช้เวลาน้อยกว่าสองสามวินาที การที่ชุดทดสอบทั้งหมดของ OP เสร็จสิ้นใน 2-3 นาทีเป็นสัญญาณที่ดีมากโดยมาตรการส่วนใหญ่

6
@rwong - ขอโทษฉันโทรพล่าม ตัวชี้วัดที่ฉันได้รับมาจากการใช้งานโปรเจ็กต์มืออาชีพที่แตกต่างกันสองแบบ: แบบทดสอบ 300 ข้อต่อแบบทดสอบ 30000 ครั้งและดูแบบทดสอบรอบเวลา ชุดทดสอบที่ใช้เวลา 2-3 นาทีสำหรับการทดสอบ <1,000 ครั้งนั้นโหดร้ายและเป็นสัญญาณว่าการทดสอบนั้นไม่ได้แยกอย่างเพียงพอ
Telastyn

2
@rwong ในหลอดเลือดดำเดียวกับ Telastyn นี่คือจุดข้อมูลจากฉัน: ถึงแม้จะมีการทดสอบที่มีขนาดใหญ่กว่าอุดมคติไม่กี่กรอบการทดสอบ ( py.test) ทำเวทมนตร์ในพื้นหลังและทุกอย่างล้วนเป็นรหัส Python บริสุทธิ์ ("100x ช้ากว่า C ") การทดสอบประมาณ 500 ครั้งในโครงการของฉันใช้เวลาน้อยกว่า 6 วินาทีในเน็ตบุ๊กที่ช้ากว่าหลายปี ตัวเลขนี้เป็นเส้นตรง ๆ ในจำนวนการทดสอบ ในขณะที่มีค่าใช้จ่ายเริ่มต้นบางส่วนจะถูกตัดจำหน่ายสำหรับการทดสอบทั้งหมดและค่าใช้จ่ายในการทดสอบต่อหนึ่งคือ O (1)

16

มีหลายวิธีที่ฉันใช้เพื่อแก้ไขปัญหาที่คล้ายกัน:

  1. ตรวจสอบเวลาดำเนินการและค้นหาการทดสอบที่ช้าที่สุดทั้งหมดจากนั้นวิเคราะห์สาเหตุที่ใช้เวลาดำเนินการมาก
  2. คุณมี 100 โครงการคุณอาจไม่จำเป็นต้องสร้างและทดสอบพวกเขาทุกครั้งหรือไม่ คุณสามารถเรียกใช้ unittest ทั้งหมดเฉพาะตอนกลางคืนสร้าง สร้างหลาย 'รวดเร็ว' สร้างการกำหนดค่าสำหรับการใช้งานในชีวิตประจำวัน เซิร์ฟเวอร์ CI จะดำเนินการที่ จำกัด เท่านั้นตั้งของโครงการ unittests ที่เกี่ยวข้องกับชิ้นส่วน 'ร้อน' ของกระบวนการพัฒนาในปัจจุบันของคุณ
  3. จำลองและแยกทุกสิ่งที่คุณทำได้หลีกเลี่ยงดิสก์ / เครือข่าย I / O ทุกครั้งที่ทำได้
  4. เมื่อไม่สามารถแยกการดำเนินการดังกล่าวคุณอาจจะมีการทดสอบการรวม? เป็นไปได้ไหมที่คุณจะกำหนดตารางการทดสอบการรวมเพื่อสร้างตอนกลางคืนเท่านั้น ?
  5. ตรวจสอบ singletons เป็นครั้งคราวทั้งหมดซึ่งเก็บการอ้างอิงกับอินสแตนซ์ / ทรัพยากรและใช้หน่วยความจำซึ่งอาจนำไปสู่การลดประสิทธิภาพขณะเรียกใช้การทดสอบทั้งหมด

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

  1. Gated คอมมิตเซิร์ฟเวอร์ CI บางตัวสามารถกำหนดค่าให้ดำเนินการสร้างและทดสอบก่อนที่จะส่งมอบรหัสไปยังแหล่งเก็บข้อมูล หากมีคนยอมรับรหัสโดยไม่เรียกใช้การทดสอบทั้งหมดล่วงหน้าซึ่งมีการทดสอบที่ล้มเหลวก็จะถูกปฏิเสธและส่งคืนให้ผู้เขียน
  2. กำหนดค่าเซิร์ฟเวอร์ CI เพื่อดำเนินการทดสอบแบบขนาน : ใช้เครื่องหรือกระบวนการหลายอย่าง ตัวอย่างคือpnunitและคอนฟิกูเรชัน CI ที่มีหลายโหนด
  3. ปลั๊กอินการทดสอบอย่างต่อเนื่องสำหรับนักพัฒนาที่จะทำการทดสอบทั้งหมดโดยอัตโนมัติในระหว่างการเขียนโค้ด

12

0. ฟังโปรแกรมเมอร์ของคุณ

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

1. ทำให้การทดสอบของคุณเชื่อถือได้ 100%

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

2. เปลี่ยนระบบของคุณเพื่อรับประกันว่าการทดสอบทั้งหมดผ่านตลอดเวลา

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

3. เปลี่ยนวัฒนธรรมของคุณเป็นค่าการทดสอบที่ผ่าน 100%

สอนบทเรียนว่างานไม่ได้ "เสร็จสิ้น" จนกว่า 100% ของการทดสอบผ่านและได้รับการรวมเข้ากับหลัก / ทางการ / การเปิดตัว / สาขาใด ๆ

4. ทำการทดสอบอย่างรวดเร็ว

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

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

ลองนึกภาพการทดสอบที่ทำงานเร็วจนคุณไม่รังเกียจที่จะทดสอบมันโดยอัตโนมัติทุกครั้งที่คุณคอมไพล์

การทำการทดสอบอย่างรวดเร็วอาจเป็นเรื่องยาก (นั่นคือสิ่งที่ OP ขอใช่มั้ย!) Decouplingเป็นกุญแจสำคัญ Mocks / fakes นั้นใช้ได้ แต่ฉันคิดว่าคุณสามารถทำได้ดีขึ้นโดยการปรับโครงสร้างใหม่เพื่อทำให้ mocks / fakes ไม่จำเป็น ดูบล็อก Arlo Belshee ของเริ่มต้นด้วยhttp://arlobelshee.com/post/the-no-mocks-book

5. ทำการทดสอบที่มีประโยชน์

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


2
เห็นด้วยอย่างยิ่งโดยเฉพาะอย่างยิ่งจุดที่ 3 และ 1 หากนักพัฒนาไม่ได้ทำการทดสอบการทดสอบนั้นจะใช้งานไม่ได้สภาพแวดล้อมก็ขาดหรือทั้งสองอย่าง จุดที่ 1 คือค่าต่ำสุด การล้มเหลวที่ผิดพลาดนั้นแย่กว่าการทดสอบที่ขาดหายไป เพราะคนเรียนรู้ที่จะยอมรับความล้มเหลว เมื่อยอมรับความล้มเหลวก็จะแพร่กระจายและใช้ความพยายามอันยิ่งใหญ่เพื่อกลับไปสู่การผ่าน 100% และการผ่านไป 100% เริ่มต้นการแก้ไขนี้ในวันนี้
Bill IV

และคุณจะไม่เห็นด้วยกับ # 5 ได้อย่างไร!? นอกเหนือจาก 1 & 3 หรือ heck, 2 & 4 ด้วย! อย่างไรก็ตามคำตอบที่ดีรอบตัว
fourpastmidnight

4

สองสามนาทีก็โอเคสำหรับการทดสอบหน่วย อย่างไรก็ตามโปรดทราบว่าการทดสอบมี 3 ประเภทใหญ่ ๆ :

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

รายการเหล่านี้จะเรียงตามลำดับความเร็ว การทดสอบหน่วยควรจะรวดเร็ว พวกเขาจะไม่ตรวจจับข้อผิดพลาดทุกตัว แต่พวกเขายืนยันว่าโปรแกรมนั้นมีเหตุผลอย่างเหมาะสม การทดสอบหน่วยควรทำงานใน 3 นาทีหรือน้อยกว่าหรือฮาร์ดแวร์ที่ดี คุณบอกว่าคุณมีการทดสอบเพียง 1,000 หน่วยและพวกเขาใช้เวลา 2-3 นาที? นั่นอาจจะโอเค

สิ่งที่ต้องตรวจสอบ:

  • ตรวจสอบให้แน่ใจว่าการทดสอบหน่วยและการทดสอบการรวมระบบของคุณแยกจากกัน การทดสอบการรวมจะช้ากว่าเสมอ

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

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

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


3

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

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

  1. พิมพ์รหัสโดยไม่ต้องคิด
  2. hit build / คอมไพล์
  3. แก้ไขไวยากรณ์ของคุณเพื่อรวบรวม
  4. ทำการทดสอบเพื่อดูว่าสิ่งที่คุณเขียนนั้นสมเหตุสมผลหรือไม่

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


2
ฉันเห็นด้วยอย่างมากกับรายการของคุณ แต่ไม่ใช่ด้วย "การสร้างงานเพียงวันละสองครั้งดีกว่า 50 ครั้ง"
Doc Brown

3

วิธีหนึ่งที่เป็นไปได้: แบ่งโซลูชันของคุณ หากวิธีการแก้ปัญหามี 100 โครงการก็ไม่สามารถจัดการได้ค่อนข้าง เพียงเพราะสองโครงการ (พูด A และ B) ใช้รหัสทั่วไปจากโครงการอื่น (พูด Lib) ไม่ได้หมายความว่าพวกเขาจะต้องอยู่ในวิธีการแก้ปัญหาเดียวกัน

คุณสามารถสร้างโซลูชัน A ด้วยโครงการ A และ Lib และแก้ปัญหา B กับโครงการ B และ Lib


2

ฉันอยู่ในสถานการณ์ที่คล้ายคลึงกัน ฉันมีการทดสอบหน่วยที่ทดสอบการสื่อสารกับเซิร์ฟเวอร์ พวกเขากำลังทดสอบพฤติกรรมด้วยการหมดเวลาการยกเลิกการเชื่อมต่อ ฯลฯ การทดสอบทั้งชุดใช้เวลา 7 นาที

7 นาทีเป็นเวลาค่อนข้างสั้น แต่ไม่ใช่สิ่งที่คุณจะต้องทำก่อนที่จะส่งมอบ

นอกจากนี้เรายังมีชุดการทดสอบ UI อัตโนมัติเวลาทำงานของพวกเขาคือ 2 ชั่วโมง ไม่ใช่สิ่งที่คุณต้องการเรียกใช้บนคอมพิวเตอร์ของคุณทุกวัน

แล้วจะทำอย่างไรดี?

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

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


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

@MichaelKohne ฉันรู้ว่าจะมีใครเห็น ฉันรู้ว่าพวกเขาไม่ใช่การทดสอบหน่วย แต่พวกเขามีจุดประสงค์เดียวกันมันเป็นเพียงเกี่ยวกับวิธีที่คุณตั้งชื่อพวกเขา
Sulthan

1
ส่วนใหญ่เป็นเรื่องเกี่ยวกับวิธีที่คุณตั้งชื่อ แต่ก็เป็นเรื่องดีที่จะรักษาความแตกต่างในใจ (ไม่ว่าคุณจะใช้ชื่อใด) หากคุณไม่แยกความแตกต่างจากนั้น (จากประสบการณ์ของฉัน) devs มีแนวโน้มที่จะเขียนแบบทดสอบระดับสูงขึ้น เมื่อถึงจุดนี้คุณจะไม่ได้รับการทดสอบที่บังคับให้คุณมีเหตุผลในเรื่องนามธรรมและการแต่งงานกัน
Michael Kohne

1

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

เรียนรู้การเขียนการทดสอบที่ถูกต้อง

คุณบอกว่าคุณมีการทดสอบเกือบพันครั้งและคุณมี 120 โครงการ สมมติว่าครึ่งหนึ่งของโครงการเหล่านั้นเป็นโครงการทดสอบคุณมี 1,000 การทดสอบถึง 60 โครงการรหัสการผลิต นั่นให้คุณทดสอบประมาณ 16-17 ข้อ โครงการ!!!

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

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

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

เรียนรู้การจัดการโครงสร้างโครงการ

คุณแบ่งการแก้ปัญหาออกเป็น 120 โครงการ นั่นคือตามมาตรฐานของฉันจำนวนโครงการที่ส่าย

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

แต่การแยกโครงการในการสร้างส่วนประกอบหลาย ๆ แบบทำรุ่นและปรับใช้แยกต่างหากต้องอาศัยประสบการณ์ของฉันในทีมพัฒนาที่เป็นผู้ใหญ่มากทีมที่เป็นผู้ใหญ่มากกว่าที่ฉันรู้สึกว่าทีมของคุณเป็น

แต่คุณต้องทำอะไรบางอย่างเกี่ยวกับโครงสร้างโครงการ แยกโครงการเป็นส่วนประกอบแยกกันหรือเริ่มรวมโครงการ

ถามตัวเองว่าคุณต้องการ 120 โครงการหรือไม่

ps คุณอาจต้องการตรวจสอบ NCrunch เป็นปลั๊กอิน Visual Studio ที่รันการทดสอบของคุณโดยอัตโนมัติในพื้นหลัง


0

การทดสอบ JUnit นั้นปกติจะรวดเร็ว แต่บางคนก็ต้องใช้เวลาในการทดสอบ

ตัวอย่างเช่นการทดสอบฐานข้อมูลมักจะใช้เวลาสักครู่เพื่อเริ่มต้นและเสร็จสิ้น

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

สิ่งที่สามารถทำได้คือ:

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

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


0

ปัญหาที่ฉันได้เห็น:

a) การใช้ IOC เพื่อสร้างองค์ประกอบการทดสอบ 70 วินาที -> 7 วินาทีโดยลบคอนเทนเนอร์

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

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

d) โปรไฟล์ บางทีรหัสอาจไม่ดีนักและคุณสามารถเพิ่มประสิทธิภาพได้จากการตรวจสอบ

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


0

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

สิ่งที่ทำให้เสียเวลาสร้าง:

  • การดาวน์โหลดแพ็กเกจ (Nuget สำหรับ C #, Maven สำหรับ Java, Gem สำหรับ Ruby, ฯลฯ )
  • คัดลอกไฟล์จำนวนมากบนระบบไฟล์ (ตัวอย่าง: ไฟล์รองรับ GDAL)
  • การเปิดการเชื่อมต่อกับฐานข้อมูล (บางคนใช้เวลามากกว่าหนึ่งวินาทีต่อการเชื่อมต่อเพื่อเจรจา)
  • รหัสสะท้อน
  • รหัสที่สร้างอัตโนมัติ
  • ใช้ข้อยกเว้นเพื่อควบคุมการไหลของโปรแกรม

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

มีวิธีแก้ไขปัญหา:

  • ย้ายการทดสอบที่เกี่ยวข้องกับฐานข้อมูลไปยังการรวม (เช่นบนเซิร์ฟเวอร์สร้าง CI เท่านั้น)
  • หลีกเลี่ยงการสร้าง mocks ในลูปในการทดสอบของคุณ ในความเป็นจริงเพียงหลีกเลี่ยงการวนซ้ำในการทดสอบของคุณโดยสิ้นเชิง คุณอาจได้ผลลัพธ์เดียวกันโดยใช้การทดสอบแบบกำหนดพารามิเตอร์ในกรณีนั้น
  • พิจารณาแยกโซลูชันขนาดใหญ่ของคุณออกเป็นโซลูชันแยกต่างหาก

เมื่อโซลูชันของคุณมีโครงการมากกว่า 100 โครงการคุณจะต้องมีการรวมกันของรหัสห้องสมุดการทดสอบและรหัสแอปพลิเคชัน ห้องสมุดแต่ละแห่งสามารถเป็นโซลูชันของตัวเองโดยมีการทดสอบที่เกี่ยวข้อง Jet Brains Team Cityเป็นเซิร์ฟเวอร์ CI build ที่เพิ่มเป็นเซิร์ฟเวอร์ Nuget เป็นสองเท่าและฉันแน่ใจว่าไม่ใช่เซิร์ฟเวอร์เดียว ที่ให้ความยืดหยุ่นแก่คุณในการย้ายไลบรารี่เหล่านั้นซึ่งอาจไม่ได้รับการเปลี่ยนแปลงบ่อยครั้งในโซลูชัน / โครงการของตนเองและใช้ Nuget เพื่อแก้ไขการพึ่งพาสำหรับโค้ดแอปพลิเคชัน โซลูชันขนาดเล็กหมายความว่าคุณสามารถเปลี่ยนแปลงไลบรารีได้อย่างรวดเร็วและไม่ยุ่งยากและเพลิดเพลินไปกับสิทธิประโยชน์ในโซลูชันหลัก


-1

สภาพแวดล้อมการทดสอบของคุณสามารถทำงานได้ทุกที่หรือไม่? ถ้าทำได้ให้ใช้การคำนวณแบบคลาวด์เพื่อเรียกใช้การทดสอบ แยกการทดสอบระหว่างเครื่องเสมือน N หากเวลาในการรันการทดสอบในเครื่องเดียวคือ T1 วินาทีดังนั้นเวลาในการรันการทดสอบจะแบ่งออกเป็น T2 ซึ่งสามารถเข้าใกล้ T2 = T1 / N (สมมติว่าแต่ละกรณีทดสอบใช้เวลาประมาณเท่ากัน) และคุณจะต้องจ่ายค่า VM เมื่อคุณใช้งานเท่านั้น ดังนั้นคุณจึงไม่มีเครื่องทดสอบมากมายนั่งอยู่ในห้องแล็บบางแห่งตลอด 24/7 (ฉันชอบที่จะสามารถทำสิ่งนี้ได้ในที่ที่ฉันทำงาน แต่เราเชื่อมโยงกับฮาร์ดแวร์เฉพาะไม่มี VM สำหรับฉัน)

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