วิธีเขียนการทดสอบหน่วยบำรุงรักษาไม่เปราะการบำรุงรักษาสำหรับ GUI?


16

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

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


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


1
@MichaelDurrant: คุณแก้ไขคำถามเกี่ยวกับการทดสอบ UI โดยทั่วไปในขณะที่ฉันถามเกี่ยวกับการทดสอบหน่วย ฉันพบว่าการทดสอบการรวมเข้าด้วยกันนั้นยากที่จะรักษาและฉันก็ชอบการทดสอบแบบหน่วยมากกว่าถ้าเป็นไปได้
mik01aj

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

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

2
เกี่ยวข้อง แต่ไม่ซ้ำกันเนื่องจากเป็นเรื่องเกี่ยวกับการทดสอบ gui: programmers.stackexchange.com/questions/109703/…
k3b

คำตอบ:


3

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

ลองพิจารณาตัวอย่างการทดสอบที่ใช้คำว่า:

เมื่อผู้ใช้ป้อน '999' ลงในฟิลด์หมายเลขโทรศัพท์และคลิกปุ่มบันทึกป๊อปอัพข้อความแสดงข้อผิดพลาดควรระบุว่า 'หมายเลขโทรศัพท์ไม่ถูกต้อง'

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

ตอนนี้ให้นำสิ่งนี้ไปใช้ถ้อยคำอื่น:

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

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


4

ปัญหานี้เป็นปัญหาทั่วไป ฉันจะใส่ใจกับ:

  • คุณตั้งชื่อองค์ประกอบอย่างไร

    ใช้ css id หรือ class เพื่อระบุองค์ประกอบ ชอบใช้ CSS ID เมื่อวัตถุไม่ซ้ำกัน พิจารณาเฟรมเวิร์กที่คุณใช้ตัวอย่างเช่น Ruby on Rails nameแอ็ตทริบิวต์ถูกกำหนดโดยอัตโนมัติและสามารถ (ไม่ใช่แบบสังหรณ์ใจ) จะดีกว่าการใช้ css id หรือคลาส

  • คุณระบุองค์ประกอบอย่างไร

    หลีกเลี่ยงตัวระบุตำแหน่งเหมือนtable/tr/td/tdในความโปรดปรานของรูปแบบเช่นหรือtd[id="main_vehicle" td[class='alternates']พิจารณาใช้คุณลักษณะข้อมูลตามความเหมาะสม ยิ่งพยายามหลีกเลี่ยงแท็กเลย์เอาต์เช่น<td>ทั้งหมดดังนั้นสำหรับข้างต้นคุณสามารถเพิ่มการขยายและใช้สิ่งนั้นเช่น<span id="main_vehicle">หรือตัวเลือกสัญลักษณ์แทนเช่น*[id="main_vehicle"]ที่*ตอนนี้อาจเป็น div, span, td เป็นต้น

  • การใช้การทดสอบคุณสมบัติข้อมูลเฉพาะที่ใช้สำหรับ qa และการทดสอบเท่านั้น

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

    body.main div#vehicles > form#vehicle input#primary_vehicle_name

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

    input#primary_vehicle_name

    ก็เพียงพอที่จะระบุองค์ประกอบ

  • หลีกเลี่ยงการทดสอบที่อ้างถึงข้อความที่มองเห็นได้ ข้อความบนหน้าเว็บที่แสดงต่อผู้ใช้มักจะเปลี่ยนแปลงเมื่อเวลาผ่านไปเนื่องจากมีการดูแลและปรับปรุงเว็บไซต์ดังนั้นให้ใช้ตัวระบุเช่น css id และ css class หรือ data attribute องค์ประกอบต่างๆเช่นform, inputและselectนำมาใช้ในรูปแบบนอกจากนี้ยังมีส่วนที่ดีขององค์ประกอบการระบุมักจะอยู่ในการรวมกันที่มี ID หรือระดับเช่นli.vehicleหรือคุณยังสามารถเพิ่มตัวบ่งชี้ของคุณเองเช่นinput#first-vehicle <div data-vehicle='dodge'>วิธีนี้คุณสามารถหลีกเลี่ยงการใช้ ID องค์ประกอบหรือคลาสซึ่งน่าจะมีการเปลี่ยนแปลงโดยนักพัฒนาและนักออกแบบ ฉันได้พบจริงเมื่อเวลาผ่านไปว่ามันจะดีกว่าที่จะทำงานร่วมกับนักพัฒนาและนักออกแบบและมาตกลงกับชื่อและขอบเขต มันยาก.

  • วิธีแก้ไขข้อมูลที่ถูกเก็บรักษาไว้

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

    storedVars["eqv_auto_year"] = "2015";
    storedVars["eqv_auto_make_1"] = "ALFA ROMEO";
    storedVars["eqv_auto_make_2"] = "HONDA";`  
    

    ข้อมูลเพิ่มเติมเกี่ยวกับวัตถุหน้าที่selenium wikiและselenium docs

  • การสื่อสารกับนักพัฒนา

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

    def css_email_opt_in_true
      'auto_policy[email_opt_in][value=1]'
    end 
    
    def css_phone_opt_in
      '*[name="auto_policy[phone_opt_in]"]'
    end 
    
    def css_phone_opt_in_true
      'input[name=phone_opt_in][value=true]'
    end 
    
    def css_credit_rating
      'auto_policy[credit_rating]'
    end
    

    นี่คือหน้าวัตถุเดียวกันกับตัวแปรจาวาสคริปต์:

    storedVars["css_email_opt_in"] = "css=*[name='auto_policy[email_opt_in]']";
    storedVars["css_phone_opt_in"]="css=*[name='auto_policy[phone_opt_in]']";
    storedVars["css_phone_opt_in_true"]="css=input[name='phone_opt_in'][value=true]";
    storedVars["css_credit_rating"]="css=select[name='auto_policy[credit_rating]']";
    

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

1
อ่าเป็นเรื่องดีที่รู้ ใช่สำหรับสิ่งนั้นฉันจะมุ่งเน้นไปที่ขั้นตอนการทำงานและการมีปฏิสัมพันธ์กับนักพัฒนาองค์กร
Michael Durrant

1
ฉันยังโพสต์ข้อมูลสำหรับคนอื่น ๆ ที่พบคำถามของคุณและอาจไม่มีทุกอย่างที่คุณมีหรืออาจไม่รู้ด้วยซ้ำ
Michael Durrant

1
ฉันขยายจุดตัวสุดท้ายของฉันตามความคิดเห็นของคุณ
Michael Durrant

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

3

เหตุผลที่ผู้คนพัฒนาสิ่งต่าง ๆ เช่น MVC, MVP และผู้นำเสนอก่อนและรูปแบบการออกแบบที่คล้ายกันคือการแยกตรรกะทางธุรกิจออกจากส่วนติดต่อผู้ใช้

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

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


GUIs เปลี่ยนไปมาก

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


2
ฉันคิดว่ามันเป็นจุดที่ดี บางทีฉันอาจทำผิด MVC :) Btw ฉันเชื่อว่าข้อกำหนดการเปลี่ยนแปลงจะหลีกเลี่ยงไม่ได้เมื่อคุณพัฒนาแพลตฟอร์มเว็บสำหรับผู้ใช้จำนวนมาก คุณไม่รู้ว่าผู้ใช้ของคุณจะทำงานอย่างไรจนกว่าพวกเขาจะเริ่มใช้ GUI
mik01aj

2

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

เป็นการเปรียบเทียบ:

การทดสอบหน่วย

ต้นฉบับ : validateEmail()ควรมีInvalidDataข้อยกเว้น ซึ่งครอบคลุมในการทดสอบหน่วยของคุณอย่างถูกต้อง

เปลี่ยนแปลง : validateEmail()ควรมีInvalidEmailข้อยกเว้น ตอนนี้การทดสอบของคุณไม่ถูกต้องคุณอัปเดตและทุกอย่างเป็นสีเขียวอีกครั้ง

ทดสอบ GUI

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

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


จำไว้ว่าคุณกำลังทดสอบอินพุตและเอาต์พุต - พฤติกรรมที่กำหนดไว้อย่างดี ไม่ว่าจะเป็นการทดสอบ GUI หรือการทดสอบหน่วยหรือการทดสอบการรวม ฯลฯ

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