Test Driven Development: วิธีที่ดี / เป็นที่ยอมรับในการทดสอบการทำงานของระบบไฟล์?


14

ฉันกำลังทำงานในโครงการในขณะนี้ที่สร้างตาราง (เหนือสิ่งอื่นใด) ตามเนื้อหาของระบบไฟล์และในทางกลับกันก็จะทำการแก้ไข meta-data บางอย่างในสิ่งที่พบ คำถามคือจะเขียนการทดสอบรอบนี้หรือตั้งค่าอย่างไร มีวิธีง่าย ๆ ในการเยาะเย้ยเรื่องนี้หรือไม่? หรือฉันควรตั้ง "กล่องแซนด์บ็อกซ์"?

คำตอบ:


13

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


TDD ไม่แนะนำให้จำลองการใช้งานอุปกรณ์ภายใต้การทดสอบ ดู (e, g) solnic.eu/2014/05/22/mocking-and-ruby.html
soru

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

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

@soru ถูกต้องดังนั้นคุณจึงสร้างเลเยอร์เลเยอร์รอบ ๆ ไฟล์และโฟลเดอร์ที่มีอินเทอร์เฟซที่กำหนดไว้เพื่อให้การดำเนินการเฉพาะโดเมนทั้งหมดอยู่บนฝั่งไคลเอ็นต์และด้านการใช้งานนั้นมีความสำคัญมากพอที่จะมั่นใจได้ ยังคงต้องมี) คล้ายกับแนวคิดของ Humble Dialog ในรหัส ui หรือใช้ mock Repository ในรหัสที่ทำงานกับวัตถุถาวร
จูลส์

2
ดังนั้นเราจึงลาออกจากการทดสอบคลาสจริงที่โต้ตอบกับระบบไฟล์ฐานข้อมูลและอื่น ๆ แทนเราสร้างการใช้งานที่แตกต่างด้วยอินเทอร์เฟซเดียวกับ mock / stub แต่คลาสจริงที่เราออกไปโดยไม่มีการทดสอบหน่วยใด ๆ เพราะเราเชื่อว่าเราไม่สามารถทดสอบหน่วยได้และควรทำการทดสอบการรวมเพื่อทดสอบแทน ถูกต้องหรือไม่
Andrew Savinykh

11

เกิดอะไรขึ้นกับการมีระบบไฟล์ "ทดสอบ"

สร้างโครงสร้างโฟลเดอร์ / ไดเรกทอรีแม่แบบที่มีเนื้อหาเพียงพอที่จะทดสอบการทำงานของคุณ

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

ปัญหาเกี่ยวกับการเยาะเย้ยคือระบบไฟล์, ระบบปฏิบัติการและฐานข้อมูลที่เป็นของโครงการของคุณไม่ได้มีคุณสมบัติเป็นทรัพยากรภายนอกและการเยาะเย้ยการเรียกระบบระดับต่ำอย่างที่สองคือการเสียเวลาและเกิดข้อผิดพลาดได้ง่าย


5
การเยาะเย้ยการทำงานของระบบไฟล์จะสร้างการทดสอบที่รันเร็วกว่าการใช้ระบบไฟล์จริงมาก (!) และหากนี่เป็นปัญหาที่ "ถกเถียงได้ง่ายกว่า" ผมขอบอกว่ามันขึ้นอยู่กับการใช้งาน อย่างไรก็ตามฉันคิดว่าข้อเสนอแนะของคุณนั้นดีสำหรับการสร้างการทดสอบการรวมอัตโนมัติ แต่ OP ต้องการการทดสอบแบบพิเศษสำหรับ TDD และการทดสอบหน่วย TDD ต้องรวดเร็ว
Doc Brown

1
ฉันคิดว่าระบบไฟล์ถ้าถูกล้อเลียนควรมี API ทั้งหมดที่เขียนและดูแลโดยกลุ่มบางกลุ่มเพราะคุณกำลังสร้างวงล้อใหม่หากคุณทำสิ่งสำคัญกับระบบไฟล์
Frank Hileman

2
@Doc Brown - ฉันเป็นประเภทของสมมติว่าเขาต้องการทำ dir ลบและเปลี่ยนชื่อการดำเนินการประเภททั้งหมดที่มีกรณีขอบซึ่งจะเจ็บปวดเพื่อเยาะเย้ย นอกจากนี้ในฮาร์ดแวร์ที่ทันสมัยการขยายไฟล์ขนาดเล็กลงในไดเรกทอรีนั้นช้ากว่าการโหลดคลาส Java เพียงเล็กน้อยเท่านั้น
James Anderson

ยิ่งฉันคิดถึงระบบไฟล์ทดสอบมากเท่าไหร่ฉันก็ยิ่งชอบมากเท่านั้น
Frank Hileman

3

นี่คือประเภทของสิ่งที่คุณต้องทดสอบการรวมเนื่องจากระบบไฟล์ในโลกแห่งความจริงมีพฤติกรรมแปลก ๆ (เช่นวิธีที่ Windows ไม่อนุญาตให้ลบไฟล์หากกระบวนการใด ๆ รวมถึง deleter เปิดอยู่)

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

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

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


คำตอบนี้นำไปสู่มุมมองสำหรับฉัน - 'unit test' and 'integration test'; they are just tests.ฉันคิดว่าเป็นจริงนี่จะเป็นทางออกที่ดีที่สุดสำหรับกรณีของฉัน - ฉันต้องทดสอบไลบรารีระบบไฟล์ที่ฉันใช้สำหรับเคสแบบขอบและวิธีการที่แอปพลิเคชันควรตอบสนอง เหล่านั้น ถ้าฉันเปลี่ยนไปใช้ไลบรารีระบบไฟล์ที่แตกต่างกันฉันไม่ต้องการเขียน mocks / รหัสทดสอบใหม่เพื่อทำงานกับไลบรารีใหม่ แต่การมีโครงสร้างโฟลเดอร์ทดสอบและการทดสอบการรวมจะทำให้ง่ายขึ้นมาก
tehDorf

2

ฉันเข้าใจคำถามของคุณว่า "วิธีที่ดี / เป็นที่ยอมรับในการทดสอบคลาสที่ขึ้นอยู่กับการทำงานของระบบไฟล์" ฉันไม่คิดว่าคุณต้องการทดสอบระบบไฟล์ของระบบปฏิบัติการของคุณ

เพื่อที่จะให้ความพยายามที่ 'การเชื่อมต่อกับการดำเนินงานระบบแฟ้มของคุณและ "เยาะเย้ยพวกเขาออกไป' เป็นคำตอบ @Doc สีน้ำตาลปัญหาขนาดเล็กที่สุดเท่าที่เป็นไปได้มันเป็นความคิดที่ดีที่จะใช้ java ในลำธารไบนารีหรืออ่านข้อความ (หรือบิดาเทียบเท่าใน C # หรือ ภาษาการเขียนโปรแกรมที่คุณใช้) แทนที่จะใช้ไฟล์ที่มีชื่อไฟล์โดยตรงในคลาสที่คุณพัฒนา tdd

ตัวอย่าง:

การใช้ java ฉันใช้คลาส CsvReader

public class CsvReader {
    private Reader reader;

    public CsvReader(Reader reader) {
        this.reader = reader;
    }
}

สำหรับการทดสอบฉันใช้ในข้อมูลหน่วยความจำเช่นนี้

String contentOfCsv = "TestColumn1;TestColumn2\n"+
    "value1;value2\n";

CsvReader sut = new CsvReader(java.io.StringReader(contentOfCsv));

หรือฝังข้อมูลทดสอบลงในทรัพยากร

CsvReader sut = new CsvReader(getClass().getResourceAsStream("/data.csv"));

ในการผลิตฉันใช้ระบบไฟล์

CsvReader sut = new CsvReader(new BufferedReader( new FileReader( "/import/Prices.csv" ) ));

วิธีนี้ CsvReader ของฉันไม่ได้ขึ้นอยู่กับระบบไฟล์ แต่เป็นนามธรรม "Reader" ซึ่งมีการนำไปใช้งานสำหรับระบบไฟล์


2
ปัญหาเดียวที่นี่คือ OP ไม่ได้พูดถึงการทำงานของไฟล์ แต่การทำงานของระบบไฟล์และการทำงานของ meta data - ฉันคิดว่าเขาหมายถึงบางอย่างเช่นการแสดงรายการไฟล์ทั้งหมดในไดเรกทอรีอัปเดตข้อมูล EXIF ​​ในไฟล์รูปภาพ ฯลฯ
Doc Brown

สิ่งนี้ถูกต้อง
Kirbinator

1
คุณสามารถสร้าง IDirectoryLister ซึ่งมีเมธอด String [] List (ไดเร็กทอรี String); จากนั้น FakeDirectoryLister สามารถใช้วิธีดังกล่าวได้โดยส่งคืน String ใหม่ [] {".", ".. ", "foo.bat", "bar.exe"};
Anders Lindén

0

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

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