ฉันจะทดสอบหน่วย GUI ได้อย่างไร


154

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

ตัวอย่างเช่นมีกราฟในแอพของฉัน ฉันไม่สามารถหาวิธีการทดสอบกราฟได้โดยอัตโนมัติ ต้องใช้สายตามนุษย์ AFAIK เพื่อตรวจสอบกราฟว่าถูกต้องหรือไม่

(ฉันใช้ Java Swing)


1
มีบทความที่ยอดเยี่ยมเกี่ยวกับสถาปัตยกรรม GUI ที่แตกต่างกันโดย Martin Fowler ( martinfowler.com/eaaDev/uiArchs.html ) มันอธิบายถึงการแลกเปลี่ยนสถาปัตยกรรม GUI ในแง่ของการทดสอบหน่วย
Roman Hwang

1
ทุกวันนี้คำถามนี้จะถูกถามดีกว่าในprogrammers.stackexchange.com (และน่าจะเป็นหัวข้อนอกเรื่อง Stack Overflow เนื่องจากมีพื้นที่กว้างเกินไป) แต่คำถามเก่า ๆ ไม่สามารถย้ายได้ คำถามที่ว่ามันอยู่ที่นี่หรือไม่ปัญหายังคงเป็นปัญหาที่น่าสนใจและยาก
Mark Amery

1
มันจะเป็นการดีถ้ามีตัวอย่างกับโค้ด GUI และ JUnit
Witold Kaczurba

1
ฉันจะบอกว่าผ่อนคลายและไม่ต้องกังวล ความพยายามในการทดสอบหน่วยไม่ได้กลายเป็นผลิตผลสุทธิเสมอไป
codeulike

ยังมีคำถามอีกข้อหนึ่งที่คุณสามารถทดสอบโฟลว์ใน GUI โดยใช้ Jubula
Abi

คำตอบ:


68

การออกแบบเช่น MVP และ MVC มักจะพยายามสรุปตรรกะออกจาก GUI จริงให้มากที่สุด หนึ่งในบทความยอดนิยมเกี่ยวกับเรื่องนี้คือ"The Humble Dialog Box"โดย Michael Feathers โดยส่วนตัวแล้วฉันมีประสบการณ์ที่หลากหลายกับการพยายามย้ายตรรกะออกจาก UI - บางครั้งมันทำงานได้ดีมากและในบางครั้งมันก็มีปัญหามากกว่าที่มันคุ้มค่า มันค่อนข้างอยู่นอกขอบเขตความเชี่ยวชาญของฉัน


??? "บางครั้งมันทำงานได้ดีมากและในบางครั้งมันก็มีปัญหามากกว่าที่มันคุ้มค่า" แปลกมากเพราะภาษาใหม่ส่วนใหญ่มีแนวโน้มที่จะมุ่งเน้น MVC ... ซึ่งเป็นตรรกะออกจาก gui (Model-Visual) ...
Patrick Desjardins

14
อย่างไรก็ตามตรรกะของงานนำเสนอจะอยู่ใน GUI บางครั้งอาจอยู่ห่างไกลจากเรื่องเล็กน้อย
Andrea


การรักษาแนวคิดของ Martin Fowler (ในกรณีที่เครือข่ายของคุณเช่น Mine, filters archive.org): martinfowler.com/eaaDev/uiArchs.html#HumbleView
Christopher Berman

@ c24w ขอบคุณที่ดึงกระจกนั่นออกมาคุณเป็น MVP ตัวจริง :)
John Baker

38

แน่นอนคำตอบคือการใช้ MVC และย้ายตรรกะออกจาก GUI มากที่สุด

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


3
ฉันชอบวิธีนี้ ยุ่งยากในการตั้งค่าและบำรุงรักษา แต่มันจะให้ความสามารถในการทดสอบการถดถอยที่ฉันต้องการ
Steve McLeod

7
Danatel คุณพลาดจุด OpenGL เป็น API การแสดงผลกราฟิกที่แม่นยำของพิกเซล เฟรมเวิร์กแอปพลิเคชัน GUI อย่าง Qt จะขึ้นอยู่กับระบบโครเมี่ยมเป็นอย่างมากดังนั้นการบัฟเฟอร์เฟรมเฟรมจึงไม่ใช่วิธีที่ดี
บ๊อบซอมเมอร์

1
MD5 อันไหน แฮชการเข้ารหัสจะทำอย่างไรกับสิ่งนี้ ความปลอดภัยเกี่ยวข้องกันอย่างไร? hash, OK มันเป็นความคิดที่ดีสำหรับกราฟิกที่สมบูรณ์แบบพิกเซล แต่แฮชเข้ารหัส? คุณสามารถใช้แฮชที่เร็วกว่าที่ไม่ใช่การเข้ารหัสและความน่าจะเป็นของการชนนั้นเล็กน้อย คุณแน่ใจหรือว่าเป็นแฮชการเข้ารหัสและไม่ใช่แค่แฮช (นอกเหนือจากนั้นในวันนี้และอายุของการคำนวณแบบขนานอัลกอริทึมการแปลงแป้นพิมพ์ [ใช้สำหรับจุดประสงค์ที่ไม่ใช่การเข้ารหัส] ที่ไม่สามารถเทียบเคียงได้ควรดูด้วยความสงสัย)
ไวยากรณ์ T3rr0r

24
@ SyntaxT3rr0r: ฟังก์ชั่นแฮชแบบไหนที่คุณจะแนะนำในแอพพลิเคชั่นที่ไม่เกี่ยวข้องกับความปลอดภัยชนิดนี้และระดับใดที่จะเพิ่มประสิทธิภาพได้เมื่อเทียบกับ MD5
Lèsemajesté

1
คำตอบของคุณหมายถึง "อย่าออกแบบ GUI ให้คุณดังนั้นอย่าทดสอบ" เย็น.
Dims

10

คุณสามารถลองUISpec4Jเป็นห้องสมุดโอเพ่นซอร์สและ / หรือหน่วยทดสอบสำหรับแอปพลิเคชัน Java-based Swing ...


2
ฉันเริ่มใช้ UISpec4J เป็นเวลาหนึ่งเดือนเพื่อทำการทดสอบการตรวจสอบข้อกำหนดของ Java Swing GUI ฉันชอบมันมากแล้ว
Bassam

github.com/UISpec4J/UISpec4Jระบุว่าลิงก์ของคุณเป็นเว็บไซต์อย่างเป็นทางการ แต่ไม่ได้ดูเป็นทางการสำหรับฉัน ทั้งหมดที่ฉันเห็นคือบล็อกเกี่ยวกับ vlogging
lucidbrot

7

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


7

คุณสามารถลองใช้CucumberและSwingerสำหรับการเขียนการทดสอบการยอมรับฟังก์ชั่นในภาษาอังกฤษธรรมดาสำหรับแอปพลิเคชัน Swing GUI Swinger ใช้ห้องสมุด Jemmy ของ Netbeans ภายใต้ประทุนเพื่อขับเคลื่อนแอพ

แตงกวาช่วยให้คุณสามารถเขียนแบบทดสอบนี้:

 Scenario: Dialog manipulation
    Given the frame "SwingSet" is visible
    When I click the menu "File/About"
    Then I should see the dialog "About Swing!"
    When I click the button "OK"
    Then I should not see the dialog "About Swing!"

ดูตัวอย่างวิดีโอ Swingerนี้เพื่อดูการทำงาน


6

นี่คือเคล็ดลับบางอย่าง:

พยายามลบรหัสส่วนใหญ่ที่คุณสามารถทำได้จาก GUI (มีคอนโทรลเลอร์และวัตถุจำลอง) ด้วยวิธีนี้คุณจะสามารถทดสอบได้โดยไม่ต้องใช้ GUI

สำหรับกราฟิกคุณควรทดสอบค่าที่คุณให้กับรหัสที่สร้างกราฟิก


6

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

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


3

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


3

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

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

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



2

แนวทางของฉันในการทดสอบ GUI นั้นมีวิวัฒนาการเช่นเดียวกับฉันทามติอุตสาหกรรม แต่ฉันคิดว่าเทคนิคสำคัญบางอย่างกำลังเริ่มเกิดขึ้น

ฉันใช้เทคนิคเหล่านี้อย่างน้อยหนึ่งอย่างขึ้นอยู่กับสถานการณ์ (เช่นชนิดของ GUI ที่ต้องสร้างได้อย่างรวดเร็วว่าใครเป็นผู้ใช้ขั้นปลายเป็นต้น)

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

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

  3. สำรวจส่วนประกอบ คุณสร้างหน้าจอ 'explorer' ซึ่งมีหน้าที่เพียงอย่างเดียวคือการแสดงส่วนประกอบที่สามารถใช้งานได้อีกครั้งซึ่งประกอบเป็น GUI ของคุณ หน้าจอนี้ให้วิธีที่รวดเร็วและง่ายดายในการตรวจสอบด้วยสายตาว่าส่วนประกอบทุกอย่างมีรูปลักษณ์และความรู้สึกที่ถูกต้อง ตัวสำรวจส่วนประกอบมีประสิทธิภาพมากกว่าการผ่านแอปพลิเคชันทั้งหมดด้วยตนเองเนื่องจาก A) คุณต้องตรวจสอบแต่ละองค์ประกอบเพียงครั้งเดียวและ B) คุณไม่จำเป็นต้องไปที่ส่วนลึกของแอปพลิเคชันเพื่อดูส่วนประกอบคุณเพียงแค่ดูและ ตรวจสอบทันที

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

  5. การทดสอบ Diff / snapshot คุณเขียนการทดสอบที่เพียงแค่จับเอาท์พุทเป็นภาพหน้าจอหรือเป็นรหัส HTML และเปรียบเทียบกับผลลัพธ์ก่อนหน้า ด้วยวิธีนี้คุณจะได้รับการแจ้งเตือนเมื่อมีการเปลี่ยนแปลงผลลัพธ์ การทดสอบที่แตกต่างกันอาจมีประโยชน์หากมุมมองภาพของ GUI ของคุณซับซ้อนและ / หรืออาจมีการเปลี่ยนแปลงซึ่งในกรณีนี้คุณต้องการความเห็นย้อนกลับอย่างรวดเร็วและเห็นได้ชัดว่าผลกระทบที่การเปลี่ยนแปลงนั้นมีต่อ GUI โดยรวมเป็นอย่างไร

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

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

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

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

ทั้งหมดนี้ขึ้นอยู่กับประสบการณ์ส่วนตัวของฉันและการวิจัยตลอดจนการเขียนขึ้นที่ดีในการทดสอบ UIโดยแฮม Vocke


1

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

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


0

หากคุณใช้ Swing FEST-Swingนั้นมีประโยชน์สำหรับการขับ GUI และการทดสอบยืนยัน มันค่อนข้างตรงไปตรงมาในการทดสอบสิ่งต่าง ๆ เช่น"ถ้าฉันคลิกปุ่ม A, กล่องโต้ตอบ B ควรปรากฏขึ้น"หรือ"ถ้าฉันเลือกตัวเลือก 2 จากเมนูแบบเลื่อนลงช่องทำเครื่องหมายทั้งหมดควรจะถูกยกเลิกการเลือก"จากเมนูแบบเลื่อนลงช่องทำเครื่องหมายทั้งหมดควรจะเป็นยกเลิกการเลือก"

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

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


0

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

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