คุณทำการทดสอบหน่วยในโครงการเดียวกันหรือโครงการอื่นหรือไม่


137

คุณใส่การทดสอบหน่วยในโครงการเดียวกันเพื่อความสะดวกหรือคุณวางการทดสอบแยกต่างหากหรือไม่?

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

คำตอบ:


100

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

  1. การทดสอบหน่วยได้รับการจัดส่งพร้อมรหัสการผลิต สิ่งเดียวที่มาพร้อมกับรหัสผลิตภัณฑ์คือรหัสการผลิต
  2. แอสเซมบลีจะถูก bloated โดยไม่จำเป็นโดยการทดสอบหน่วย
  3. การทดสอบหน่วยสามารถส่งผลกระทบต่อกระบวนการสร้างเช่นการสร้างอัตโนมัติหรือการสร้างอย่างต่อเนื่อง

ฉันไม่รู้ถึงข้อดีจริงๆ การมีโครงการพิเศษ (หรือ 10) ไม่ใช่การแย้ง

แก้ไข: ข้อมูลเพิ่มเติมเกี่ยวกับการสร้างและการจัดส่ง

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

เพื่อสรุปนี่เป็นแนวคิดทั่วไปสำหรับการสร้างและทดสอบรายวันและการจัดส่งบิตและไฟล์อื่น ๆ :

  1. บิลด์การผลิตดำเนินการโดยวางไฟล์การผลิตไว้ในไดเรกทอรี "การผลิต" ที่เฉพาะเจาะจง
    1. สร้างโครงการผลิตเท่านั้น
    2. คัดลอกบิตรวบรวมและไฟล์อื่น ๆ ลงในไดเรกทอรี "การผลิต"
    3. คัดลอกบิตและไฟล์อื่น ๆ ไปยังไดเรคทอรี Release release หรือที่รู้จักในไดเร็กตอรี่รีลีสคริสต์มาสจะเป็น "Release20081225"
  2. หากบิลด์การผลิตสำเร็จการทดสอบหน่วยจะรัน
    1. คัดลอกรหัสการผลิตไปยังไดเรกทอรี "การทดสอบ"
    2. สร้างการทดสอบหน่วยในไดเรกทอรี "การทดสอบ"
    3. เรียกใช้การทดสอบหน่วย
  3. ส่งการแจ้งเตือนการสร้างและผลการทดสอบหน่วยให้กับนักพัฒนา
  4. เมื่อยอมรับตัวเลือกการปล่อย (เช่น Release20081225) ให้ส่งบิตเหล่านี้

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

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

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

4
ในฐานะที่เป็นทางเลือกที่จะ "แยกโครงการ" วิธีการสำหรับการลบทดสอบหน่วยในรหัสการผลิต, #ifการพิจารณาการใช้สัญลักษณ์ที่กำหนดเองและสั่งคอมไพเลอร์เช่น สัญลักษณ์ที่กำหนดเองนี้สามารถสลับโดยใช้พารามิเตอร์บรรทัดคำสั่งคอมไพเลอร์ในสคริปต์ซอฟต์แวร์ CI ของคุณ ดูmsdn.microsoft.com/en-us/library/4y6tbswk.aspx
Rich C

23
.NET อยู่เบื้องหลังเส้นโค้งในการทดสอบในโครงการที่แยกจากกันอย่างสมบูรณ์และฉันจะเดิมพันว่าสิ่งนี้จะเปลี่ยนแปลงเร็ว ๆ นี้ ไม่มีเหตุผลที่กระบวนการสร้างไม่สามารถเพิกเฉยต่อโค้ดทดสอบในบิลด์ที่วางจำหน่าย ฉันใช้ตัวสร้างเว็บแอปหลายตัวที่ทำสิ่งนี้ ฉันคิดว่ามันเป็นการดียิ่งกว่าที่จะรวม codefiles ทดสอบหน่วยข้างๆ codefiles ที่พวกเขาอธิบายรวมอยู่ในลำดับชั้นไฟล์เดียวกัน Google แนะนำสิ่งนี้เรียกว่าองค์กรไฟล์ 'เศษส่วน' เหตุใดการทดสอบจึงแตกต่างจากความคิดเห็นแบบอินไลน์และเอกสารประกอบ readme คอมไพเลอร์ไม่สนใจหลัง
แบรนดอนอาร์โนลด์

112

แยกโครงการออก แต่อยู่ในแนวทางเดียวกัน (ฉันเคยทำงานกับผลิตภัณฑ์ที่มีโซลูชันแยกต่างหากสำหรับการทดสอบและรหัสการผลิต - มันน่ากลัวคุณมักจะสลับระหว่างสอง)

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

หากคุณจำเป็นต้องเข้าถึงสมาชิกภายในของรหัสการผลิตให้ใช้InternalsVisibleTo


+1: ฉันเพิ่งพบการทดสอบหน่วยในโครงการเดียวกันกับรหัสหลักและเป็นการยากที่จะหาการทดสอบระหว่างรหัสจริง - แม้ว่าจะมีการติดตามการตั้งชื่อแล้วก็ตาม
เฟนตัน

32
สำหรับผู้อ่านที่มีประสบการณ์น้อยหมายความว่าคุณเพิ่มไฟล์[assembly:InternalsVisibleTo("UnitTestProjectName")]โครงการของคุณ AssemblyInfo.cs
คุส

Margus นอกจากนี้มีประโยชน์มาก ขอบคุณจอนที่กล่าวถึง InternalsVisibleTo ในบริบทนี้
Bjørn Otto Vasbotten

1
@jropella: หากคุณลงนามในแอสเซมบลี prod คุณสามารถทำให้ internals ปรากฏแก่แอสเซมบลีที่ลงนามแล้วเท่านั้น และแน่นอนถ้าคุณใช้รหัสใด ๆ ในความไว้วางใจเต็มพวกเขาสามารถเข้าถึงได้ผ่านทางสะท้อน ...
จอนสกีต

2
@ jropella: Reflection ไม่สนใจ InternalsVisibleTo ต่อไป ... แต่คุณจะไม่เห็นการชุมนุมที่ลงนามไว้วางใจในแอสเซมบลีที่ไม่ได้ลงชื่อโดยใช้ InternalsVisibleTo เพราะนั่นเป็นการป้องกันในเวลารวบรวม
Jon Skeet

70

ฉันไม่เข้าใจการคัดค้านบ่อยครั้งในการปรับใช้การทดสอบด้วยรหัสการผลิต ฉันนำทีมที่ microcap ขนาดเล็ก (เพิ่มขึ้นจาก 14 เป็น 130 คน) เรามีแอพพลิเคชั่น Java ครึ่งโหลหรือมากกว่านั้นและเราพบว่ามันมีคุณค่าอย่างยิ่งต่อการปรับใช้การทดสอบในฟิลด์เพื่อดำเนินการกับแอปเฉพาะเครื่องที่แสดงพฤติกรรมที่ผิดปกติ ปัญหาแบบสุ่มเกิดขึ้นในสนามและสามารถโยนการทดสอบสองสามพันหน่วยที่ความลึกลับด้วยค่าใช้จ่ายที่ศูนย์เป็นสิ่งที่ประเมินค่าไม่ได้และมักจะวินิจฉัยปัญหาในไม่กี่นาที ... รวมถึงปัญหาการติดตั้งปัญหา RAM ที่ไม่สม่ำเสมอปัญหาเฉพาะเครื่อง ฯลฯ เป็นต้นฉันคิดว่ามันมีค่าอย่างไม่น่าเชื่อที่จะนำการทดสอบเข้าสู่สนาม นอกจากนี้ปัญหาสุ่มปรากฏขึ้นในเวลาสุ่มและมันเป็นเรื่องดีที่จะมีการทดสอบหน่วยนั่งอยู่ที่นั่นแล้วรอที่จะดำเนินการในช่วงเวลาที่สังเกตเห็น พื้นที่ฮาร์ดไดรฟ์ราคาถูก เช่นเดียวกับที่เราพยายามเก็บข้อมูลและฟังก์ชั่นไว้ด้วยกัน (การออกแบบ OO) ฉันคิดว่ามีบางสิ่งที่มีค่าในการรักษาโค้ดและการทดสอบด้วยกัน (ฟังก์ชั่น + การทดสอบที่ตรวจสอบฟังก์ชัน)

ฉันต้องการทดสอบในโครงการเดียวกันใน C # /. NET / Visual Studio 2008 แต่ฉันยังไม่ได้ตรวจสอบเรื่องนี้มากพอที่จะทำให้สำเร็จ

ข้อดีอย่างหนึ่งของการเก็บ Foo.cs ในโครงการเดียวกันกับ FooTest.cs คือนักพัฒนาจะได้รับการเตือนตลอดเวลาเมื่อชั้นเรียนขาดการทดสอบพี่น้อง! สิ่งนี้ส่งเสริมการเขียนโปรแกรมที่ควบคุมการทดสอบได้ดีกว่า ... รูมีความชัดเจนมากขึ้น


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

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

ฉันคิดว่ามันสมเหตุสมผลดีที่จะทำการทดสอบบูรณาการในรูปแบบ TDD / BDD นั่นคือการเขียนโค้ดทดสอบที่สามารถทำงานอัตโนมัติกับนักทดสอบมาตรฐานอย่าง NUnit, xUnit ฯลฯ แน่นอนว่าคุณไม่ควรผสมผสานหน่วยกับการทดสอบการรวมกลุ่ม เพียงให้แน่ใจว่าคุณรู้ว่าชุดการทดสอบใดที่ทำงานได้อย่างรวดเร็วและบ่อยครั้งสำหรับการสร้างการตรวจสอบ (BVT) และการทดสอบแบบรวม
mkoertgen

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

19

วางการทดสอบหน่วยในโครงการเดียวกันกับรหัสเพื่อให้ได้การห่อหุ้มที่ดีขึ้น

คุณสามารถทดสอบวิธีการภายในได้อย่างง่ายดายซึ่งหมายความว่าคุณจะไม่เปิดเผยวิธีการสาธารณะที่ควรได้รับภายใน

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

และคุณสามารถลบการทดสอบหน่วยจากรหัสการผลิตโดยใช้แท็กการรวบรวม (IF #Debug)

การทดสอบการรวมอัตโนมัติ (made i NUnit) ควรอยู่ในโครงการแยกต่างหากเนื่องจากไม่ได้อยู่ในโครงการเดียว


1
แต่นั่นหมายความว่าคุณไม่สามารถรันการทดสอบในReleaseบิลด์และมี "heisenbugs" เพียงเล็กน้อยเท่านั้นที่สามารถผ่านได้
hIpPy

3
ด้วยชุดประกอบเพื่อน ( msdn.microsoft.com/en-us/library/0tke9fxk.aspx ) การใช้InternalsVisibleToช่วยให้คุณสามารถทดสอบวิธีการภายในจากโครงการทดสอบแยก
ParoX

3
@hlpPy - คุณสามารถกำหนดค่าสัญลักษณ์การคอมไพล์แบบมีเงื่อนไขและคุณสามารถมีการกำหนดค่าบิวด์มากกว่า 2 แบบ เช่น; คุณอาจมีDebug, ApprovalและRelease; และรวบรวมการอนุมัติด้วยการปรับแต่งให้เหมาะสมทั้งหมด นอกจากนี้โดยทั่วไปการทดสอบหน่วยก็ไม่ได้ยอดเยี่ยมในการตรวจจับไฮเซนบั๊กตั้งแต่แรก (จากประสบการณ์ของฉัน) คุณมีแนวโน้มที่จะต้องมีการทดสอบการถดถอยแบบบูรณาการที่เฉพาะเจาะจงสำหรับการทดสอบเหล่านั้นและคุณอาจวางแบบเคียงข้างกัน
Eamon Nerbonne

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

12

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

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

ดังนั้นเมื่อฉันเริ่มโครงการ. NET Core ใหม่เมื่อเร็ว ๆ นี้ฉันต้องการดูว่าเป็นไปได้หรือไม่ที่จะเลียนแบบโครงสร้างนี้ในโครงการ C # โดยไม่ต้องส่งการทดสอบหรือชุดประกอบการทดสอบด้วยการเปิดตัวขั้นสุดท้าย

การใส่บรรทัดต่อไปนี้ในไฟล์โครงการดูเหมือนว่าจะทำงานได้ดีจนถึงตอนนี้:

  <ItemGroup Condition="'$(Configuration)' == 'Release'">
    <Compile Remove="**\*.Tests.cs" />
  </ItemGroup>
  <ItemGroup Condition="'$(Configuration)' != 'Release'">
    <PackageReference Include="nunit" Version="3.11.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
  </ItemGroup>

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

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


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

ภาพหน้าจอของรหัส VS

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

"material-icon-theme.files.associations": {
  "*.Tests.cs": "test-jsx",
  "*.Mocks.cs": "merlin",
  "*.Interface.cs": "yaml",
}

สิ่งที่เราเพิ่งเริ่มทำ
Matthew Steeples

คุณได้สิ่งนี้ใช้งานได้กับไลบรารีคลาส. net มาตรฐานด้วยหรือไม่
Zenuka

10

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


1
แล้วคุณจะทดสอบหน่วยภายในได้อย่างไร หรือคุณแค่ทดสอบชั้นเรียนสาธารณะ
user19371

7
<assembly: InternalsVisibleTo = "TestProject" /> หากจำเป็นถึงแม้ว่าโดยทั่วไปแล้วฉันจะทดสอบเฉพาะส่วนต่อประสานสาธารณะ
tvanfosson

@tvanfosson คุณทำอะไรกับ Specs (Specflow) คุณจะมีโครงการแยกต่างหากหรือคุณจะใส่ไว้ในโครงการทดสอบหน่วย? +1
w0051977

@ w0051977 ฉันไม่เคยใช้ Specflow ดังนั้นฉันไม่รู้
tvanfosson

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

10

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

public static class Ext
{
     [TestCase(1.1, Result = 1)]
     [TestCase(0.9, Result = 1)]
     public static int ToRoundedInt(this double d)
     {
         return (int) Math.Round(d);
     }
}

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

อัปเดต : ฉันรู้ว่าการใช้งานTestCaseแอตทริบิวต์ดังกล่าวไม่ใช่ว่านักพัฒนาซอฟต์แวร์ของ NUnit ตั้งใจ แต่ทำไมถึงไม่ใช่


2
ฉันชอบความคิดนี้ มีตัวอย่างของอินพุตและเอาต์พุตที่คาดหวังพร้อมด้วยโค้ด
เพรสตัน McCormick

3

ฉันผันผวนระหว่างโครงการเดียวกันและโครงการอื่น

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

เมื่อทำการทดสอบในโครงการเดียวกันฉันพบว่าง่ายขึ้นในการสลับระหว่างการทดสอบและรหัสที่พวกเขาทดสอบและง่ายกว่าในการปรับโครงสร้าง / ย้ายพวกเขาไปรอบ ๆ


3

ฉันวางมันในโครงการแยกต่างหาก ชื่อของชุดประกอบสะท้อนว่าของเนมสเปซเป็นกฎทั่วไปสำหรับเรา ดังนั้นหากมีโครงการชื่อ Company.Product.Feature.sln จะมีเอาต์พุต (ชื่อชุดประกอบ) ของ Company.Product.Feature.dll โครงการทดสอบคือ Company.Product.Feature.Tests.sln ให้ผลผลิต Company.Product.Feature.Tests.dll

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

นอกจากนี้หากคุณใช้ Team Build (และฉันแน่ใจว่าเครื่องมือสร้าง. NET อื่น ๆ เหมือนกัน) คุณสามารถเชื่อมโยงบิลด์กับการตั้งค่าที่มีชื่อ ซึ่งหมายความว่าหากคุณไม่ได้สร้างการทดสอบหน่วยของคุณสำหรับงานสร้าง "การผลิต" ของคุณโครงการสร้างสามารถรับรู้ถึงการตั้งค่านี้ได้เช่นกันและไม่สร้างขึ้นเนื่องจากถูกทำเครื่องหมายเช่นนั้น

นอกจากนี้เรายังเคยทำ XCopy ลดลงจากเครื่องสร้าง สคริปต์จะละเว้นการคัดลอกสิ่งที่ชื่อ * .Tests.Dll จากการปรับใช้ มันง่าย แต่ทำงานได้


1

ฉันจะบอกให้แยกพวกเขา

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


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

0

ฉันได้รับแรงบันดาลใจจากกรอบการทดสอบหน่วยของห้องสมุดท่วม NNโดย Robert Lopez มันใช้โครงการที่แตกต่างกันสำหรับทุก ๆ คลาสที่ทดสอบแล้วและมีทางออกหนึ่งเดียวที่จัดการโครงการเหล่านี้ทั้งหมดรวมถึงโครงการหลักที่รวบรวมและดำเนินการทดสอบทั้งหมด

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


0

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

ทำไม?

ครั้งแรกฉันมักจะทำให้โครงสร้างโฟลเดอร์โครงการหลักเหมือนกันกับโครงการทดสอบ ดังนั้นถ้าฉันมีไฟล์ข้างล่างProviders > DataProvider > SqlDataProvider.csฉันจะสร้างโครงสร้างเดียวกันในโครงการทดสอบหน่วยของฉันเช่นProviders > DataProvider > SqlDataProvider.Tests.cs

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

ประการที่สองมันไม่ง่ายเสมอไปในการนำทางจากชั้นเรียนเพื่อทดสอบไปยังชั้นเรียนทดสอบหน่วย นี่เป็นเรื่องยากสำหรับ JavaScript และ Python

เมื่อเร็ว ๆ นี้ฉันเริ่มฝึกฝนสิ่งนั้นทุกไฟล์ที่ฉันสร้างขึ้น (ตัวอย่างเช่น SqlDataProvider.cs ) ฉันกำลังสร้างไฟล์อื่นด้วยคำต่อท้ายแบบทดสอบเช่นSqlDataProvider.Tests.cs

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

คุณสามารถเขียนกฎธุรกิจเพื่อสแกนผ่านโครงการและระบุคลาสที่ไม่มีไฟล์ทดสอบและรายงานให้เจ้าของทราบ นอกจากนี้คุณสามารถบอกได้วิ่งทดสอบของคุณได้อย่างง่ายดายเพื่อกำหนดเป้าหมาย.Testsการเรียน

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

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


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

0

ตามที่คนอื่น ๆ ได้ตอบ - ไว้ทำการทดสอบในโครงการแยกต่างหาก

สิ่งหนึ่งที่ไม่ได้กล่าวถึงคือคุณไม่สามารถทำงานnunit3-console.exeกับ.dllไฟล์ใด ๆ

หากคุณวางแผนที่จะทำการทดสอบผ่าน TeamCity สิ่งนี้จะเป็นปัญหา

สมมติว่าคุณมีโครงการแอปพลิเคชันคอนโซล เมื่อคุณคอมไพล์มันจะส่งคืนไฟล์ที่เรียกทำงานได้.exeไปยังbinโฟลเดอร์

จากที่nunit3-console.exeคุณจะไม่สามารถเรียกใช้การทดสอบใด ๆ ที่กำหนดไว้ในแอปพลิเคชันคอนโซลนั้น

กล่าวอีกนัยหนึ่งแอปพลิเคชันคอนโซลจะส่งคืนexeไฟล์และไลบรารีคลาสจะส่งคืนdllไฟล์

ฉันเพิ่งได้รับบิตโดยวันนี้และมันดูด :(


0

ฉันเพิ่งได้รับการปรับใช้ในนักเทียบท่า ฉันไม่เห็นคุณค่าของการมีโครงการแยกต่างหากเมื่อ Dockerfile สามารถคัดลอกไดเรกทอรี / src ได้อย่างง่ายดายและออกจาก / test directory แต่ฉันใหม่กับ dotnet และอาจขาดอะไรบางอย่าง


-2

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

"MyProject" - สำหรับโครงการ

และหนึ่งที่เรียกว่า

"MyProjectTests" - สำหรับการทดสอบที่เกี่ยวข้องกับ MyProject

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

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

โครงการของฉัน
| \ Trunk
| | \ รหัส
| \ ทดสอบ
| \ แท็ก
| | \ 0.1
| | | \ รหัส
| | \ ทดสอบ
| \ 0.2
| | \ รหัส
| \ ทดสอบ
\ สาขา
  \ MyFork
   | \ รหัส
    \ทดสอบ

ฉันสนใจที่จะรู้ว่าคนอื่นคิดอย่างไรกับการแก้ปัญหานี้


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