วิธีการทดสอบเมื่อการจัดเรียงข้อมูลยุ่งยากเกินไป?


19

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

x = 2 + 3 * a

เป็น:

tmp1 = 3 * a
x = 2 + tmp1

ตอนนี้ฉันกำลังคิดเกี่ยวกับวิธีการทดสอบคลาสนี้โดยเฉพาะวิธีการจัดเรียงการทดสอบ ฉันสามารถสร้างแผนภูมิไวยากรณ์อินพุตด้วยตนเองได้:

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

หรือฉันสามารถเขียนเป็นสตริงและแยกมัน

var input = new Parser().ParseStatement("x = 2 + 3 * a");

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

คำถามของฉันคือ: มันไม่เป็นไรที่จะพึ่งพาส่วนใหญ่ (หรือทั้งหมด) ในการทดสอบการรวมกลุ่มนี้เพื่อทดสอบExpanderคลาสนี้?


3
ว่าข้อผิดพลาดในParserอาจล้มเหลวบางทดสอบอื่น ๆ Parserไม่ได้เป็นปัญหาถ้าคุณเป็นปกติวิสัยกระทำเฉพาะที่ศูนย์ความล้มเหลวในทางตรงกันข้ามก็หมายความว่าคุณมีความคุ้มครองมากขึ้นของ สิ่งที่ผมค่อนข้างจะกังวลเกี่ยวกับการเป็นที่ข้อผิดพลาดในการParserที่จะทำให้ประสบความสำเร็จในการทดสอบนี้เมื่อมันควรจะมีการล้มเหลว การทดสอบหน่วยจะไปหาข้อบกพร่องหลังจากทั้งหมด - การทดสอบจะขาดเมื่อมันไม่ได้ แต่ควรมี
Jonas Kölker

คำตอบ:


27

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

var input = new Parser().ParseStatement("x = 2 + 3 * a");

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

นักพัฒนาบางครั้งมุ่งเน้นไปที่ความบริสุทธิ์ของการทดสอบหน่วยของพวกเขาหรือการพัฒนาการทดสอบหน่วยและการทดสอบหน่วยเท่านั้นโดยไม่ต้องมีโมดูลบูรณาการความเครียดหรือการทดสอบประเภทอื่น ๆ แบบฟอร์มเหล่านั้นถูกต้องและเป็นประโยชน์และเป็นความรับผิดชอบที่เหมาะสมของนักพัฒนาไม่ใช่แค่ Q / A หรือบุคลากรฝ่ายปฏิบัติการเพิ่มเติม

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

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

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


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

6
ความกังวลเรื่องความบริสุทธิ์หลัก (ฉันคิดว่า) คือการหลีกเลี่ยงการเขียนการอ้างอิงแบบวงกลมในการทดสอบหน่วยของคุณ หากทั้งสองตัวแยกวิเคราะห์หรือการทดสอบตัวแยกวิเคราะห์ที่ใช้แผ่และทดสอบแผ่นี้ต้องอาศัยการทำงาน parser แล้วคุณมีความยากต่อการบริหารความเสี่ยงที่สิ่งที่คุณกำลังทดสอบว่าตัวแยกวิเคราะห์และแผ่เป็นที่สอดคล้องกันในขณะที่สิ่งที่ คุณต้องการที่จะทำคือการทดสอบว่าแผ่ขยายทำในสิ่งที่มันควรจะเป็นจริง แต่ตราบใดที่ไม่มีการพึ่งพาวิธีอื่นการใช้ parser ในการทดสอบหน่วยนี้ไม่แตกต่างจากการใช้ไลบรารีมาตรฐานในการทดสอบหน่วย
Steve Jessop

@SteveJessop จุดดี สิ่งสำคัญคือต้องใช้ส่วนประกอบที่เป็นอิสระ
Jonathan Eunice

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

+1 สำหรับแนวทางของ @ DanNeely เราใช้สิ่งที่คล้ายกันในการจัดเก็บแบบจำลองข้อมูลของเราหลายรุ่นซึ่งต่อเนื่องกันเพื่อเป็นข้อมูลทดสอบ
Chris Hayes

6

แน่นอนมันก็โอเค!

คุณจำเป็นต้องมีการทดสอบการทำงาน / การรวมที่ใช้เส้นทางรหัสที่สมบูรณ์ และเส้นทางรหัสที่สมบูรณ์ในกรณีนี้หมายถึงรวมถึงการประเมินผลของรหัสที่สร้างขึ้น นั่นคือคุณทดสอบแยกที่x = 2 + 3 * aผลิตรหัสว่าถ้าวิ่งด้วยa = 5จะตั้งxไป17และถ้าวิ่งด้วยa = -2จะตั้งไปx-4

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


4

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

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

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


0

ทำการทดสอบจำนวนมากบน parser และเมื่อ parser ผ่านการทดสอบให้บันทึกผลลัพธ์เหล่านั้นไปยังไฟล์เพื่อจำลอง parser และทดสอบส่วนประกอบอื่น ๆ

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