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


10

ฉันกำลังทดสอบ api REST สมมติว่ามันส่งคืนโครงสร้าง JSON วิธีทดสอบเซิร์ฟเวอร์ที่ดีที่สุดคืออะไร? แต่ละขั้นตอนการทดสอบจะประสบความสำเร็จก็ต่อเมื่อก่อนหน้านี้ทั้งหมดประสบความสำเร็จ

โครงสร้าง A: ทดสอบทุกอย่างในครั้งเดียว

- Test method 1:
    - make server request
    - assert http response code was 200
    - assert returned file is not empty
    - assert returned file has valid JSON syntax
    - assert returned JSON contains key X

นี่น่าจะเป็นทางออกที่ดีที่สุด

ข้อดี:

  • คำขอเซิร์ฟเวอร์เดียวเท่านั้น
  • ฉันกำลังทดสอบพฤติกรรมโดยรวม "เซิร์ฟเวอร์ส่งคืน JSON ด้วยคีย์ X หรือไม่"

โครงสร้าง B: ค่อยๆเพิ่มการยืนยันลงในการทดสอบแต่ละครั้ง

 - Test method 1:
     - make server request
     - assert http response code was 200
 - Test method 2:
     - make server request
     - assert returned file is not empty
 - Test method 3:
     - make server request
     - assert returned file has valid JSON syntax
 - Test method 4:
     - make server request
     - assert returned JSON contains key X

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

โครงสร้าง C: ทำการร้องขอหนึ่งครั้งและเรียกใช้วิธีการทดสอบแยกกันในการตอบสนองที่แคชไว้

- make server request and cache it (allow read-only access)

 - Test method 1:
     - assert http response code was 200 on cached server request
 - Test method 2:
     - assert returned file is not empty on cached server request
 - Test method 3:
     - assert returned file has valid JSON syntax on cached server request
 - Test method 4:
     - assert returned JSON contains key X on cached server request

ข้อดี:

  • ไม่มีการร้องขอเซิร์ฟเวอร์ซ้ำ ๆ (แพง)
  • ยังคงมีวิธีการทดสอบแบบยืนยันเดียว

โครงสร้างการทดสอบที่เหมาะสมที่สุดที่จะใช้คืออะไร


โปรดหยุดการเปลี่ยนแปลงคำถามของคุณหลังจากนั้นในลักษณะที่ทำให้คำตอบที่มีอยู่นั้นไม่ถูกต้อง! ขอบคุณ
Doc Brown

ขออภัยที่ทำให้คุณไม่สะดวก แต่คุณจะเสนอให้ทำอย่างอื่นหรือไม่?
mrplow

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

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

คำตอบ:


3

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

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

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

ดังนั้นคุณต้องถามตัวเองว่า - "ฉันต้องการรับประกันนี้หรือไม่"

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

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

มีอีกหลายสิ่งที่ควรพิจารณา:

ยืนยันการอ้างอิง

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

หากคุณมีเซอร์วิส REST (หรือโปรโตคอล HTTP อื่น ๆ ) ที่ส่งคืนการตอบสนองในรูปแบบ JSON คุณมักจะเขียนคลาสไคลเอ็นต์แบบง่ายที่ให้คุณใช้เมธอด REST เช่นวิธีปกติที่ส่งคืนอ็อบเจ็กต์ปกติ สมมติว่าไคลเอนต์มีการทดสอบแยกกันเพื่อให้แน่ใจว่าทำงานได้ฉันจะทิ้ง 3 asserts แรกและเก็บเพียง 4!

ทำไม?

  • การยืนยันครั้งแรกซ้ำซ้อน - คลาสไคลเอนต์ควรส่งข้อยกเว้นถ้ารหัสการตอบสนอง HTTP ไม่ใช่ 200
  • การยืนยันที่สองคือการทำซ้ำ - ถ้าการตอบสนองว่างเปล่าวัตถุผลลัพธ์จะเป็นโมฆะหรือการแสดงอื่น ๆ ของวัตถุว่างเปล่าและคุณจะไม่ต้องใส่คีย์ X
  • การยืนยันที่สามนั้นซ้ำซ้อน - ถ้า JSON ไม่ถูกต้องคุณจะได้รับข้อยกเว้นเมื่อคุณพยายามวิเคราะห์มัน

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

คุณต้องการรับรายงานอย่างไร

สมมติว่าคุณไม่ได้รับอีเมลจากเซิร์ฟเวอร์ทดสอบ แต่แผนก QA จะทำการทดสอบและแจ้งให้คุณทราบว่าการทดสอบล้มเหลว

แจ็คจาก QA เคาะที่ประตูของคุณ เขาบอกว่าวิธีการทดสอบแรกล้มเหลวและวิธี REST ส่งคืนรหัสตอบกลับที่ไม่ดี คุณขอบคุณเขาและเริ่มมองหาต้นเหตุ

จากนั้นเจนก็มาจาก QA และบอกว่าวิธีการทดสอบที่สามล้มเหลว - เมธอด REST ไม่ส่งคืน JSON ที่ถูกต้องในเนื้อความการตอบสนอง คุณบอกเธอว่าคุณกำลังดูวิธีการนั้นอยู่แล้วและคุณเชื่อว่าสิ่งเดียวกันที่ทำให้การส่งคืนรหัสการออกที่ไม่ถูกต้องยังทำให้มันส่งคืนสิ่งที่ไม่ใช่ JSON ที่ถูกต้องและมีลักษณะเหมือนการติดตามสแต็กข้อยกเว้น

คุณกลับมาทำงานได้ แต่แล้ว Jim จาก QA มาถึงโดยบอกว่าวิธีทดสอบที่สี่ล้มเหลวและไม่มีคีย์ X ในการตอบสนอง ...

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

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


3

หากคุณสามารถสันนิษฐานได้อย่างปลอดภัยว่าการร้องขอเซิร์ฟเวอร์ด้วยพารามิเตอร์เดียวกันจะทำงานเหมือนเดิมเสมอเมธอด B เกือบจะไม่มีจุดหมาย - ทำไมคุณควรเรียกวิธีการเดียวกันสี่ครั้งเพื่อรับข้อมูลการตอบกลับที่เหมือนกันสี่ครั้งเมื่อการโทรหนึ่งครั้งเพียงพอ

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

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

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

TLDR: เริ่มต้นด้วย A หากคุณแน่ใจว่าคุณต้องการให้ชุดทดสอบทั้งหมดทำงานในการทดสอบครั้งเดียวให้ทำการ refactor to C หากคุณสังเกตเห็นว่าคุณจำเป็นต้องควบคุมได้ง่ายขึ้นจากภายนอกเกี่ยวกับการยืนยันแต่ละชุด


0

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

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

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


0

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


เมื่อเขียนโค้ดใด ๆ (หรืออาจสร้างสิ่งอื่น) ถามตัวเองเสมอว่า: "ทำไมจึงมีการฝึกฝนเช่นนี้"
ทำไมเราพูดว่าควรมีการทดสอบที่แตกต่างกันสำหรับทุกสิ่ง?

มีสองกรณีเมื่อคุณต้องการสิ่งนี้:

  1. เมื่อคุณไม่สามารถพึ่งพา "แต่ละขั้นตอนการทดสอบจะประสบความสำเร็จก็ต่อเมื่อก่อนหน้านี้ทั้งหมดประสบความสำเร็จ"
  2. เมื่อการทดสอบของคุณไม่มีข้อความยืนยันที่สื่อความหมาย

มีสองเหตุผลที่คุณต้องเผชิญกับกรณีเหล่านี้:

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

หากคุณด้วยเหตุผลบางอย่างไม่สามารถประกาศที่หนึ่งอย่างน้อยด้วยเหตุผลเหล่านี้จะมีสถานที่เพียงสุ่มสี่สุ่มห้าใช้โครงสร้าง B


มิฉะนั้น (ฉันหวังว่าคุณจะได้รับที่นี่) คุณเลือก


คุณสามารถถามคำถามนี้ได้ที่เว็บไซต์Software Quality Assurance & Testing Stackexchange

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