Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ระบบ >> Android

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ

โดย สยามัค มาห์มูดี

TDD หรือ Test-Driven Development เป็นแนวทางการพัฒนาซอฟต์แวร์ที่เขียนการทดสอบก่อนที่จะนำโค้ดจริงไปใช้

จำเป็นต้องมีความเข้าใจที่ชัดเจนเกี่ยวกับ "อะไร" และ "อย่างไร" ในข้อกำหนดของโปรเจ็กต์/ฟีเจอร์

TDD ช่วยให้เขียนโค้ดน้อยลงแต่เพียงพอ ช่วยป้องกันข้อผิดพลาดทั่วไปในการพัฒนาซอฟต์แวร์ เช่น วิศวกรรมมากเกินไป ความครอบคลุมของการทดสอบมากเกินไป ข้อกำหนดหลักที่ขาดหายไป ฟังก์ชันและคลาสที่ใหญ่เกินไป และคำสั่งโค้ดที่ซับซ้อนมากเกินไป

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

ในบทความนี้เราจะพูดถึงการทำงานของ TDD

บริบทคือสภาพแวดล้อมการพัฒนา Android ดังนั้นเราจะใช้ Kotlin และ JUnit5 กับโปรเจ็กต์ตัวอย่างเพื่อสาธิตขั้นตอนต่างๆ

อย่างไรก็ตาม คำแนะนำและเทคนิคที่นี่สามารถฝึกฝนได้ในภาษาการเขียนโปรแกรมอื่นเช่นกัน

ข้อกำหนดเบื้องต้น

  • ความรู้พื้นฐานของ Kotlin
  • ความรู้พื้นฐานในการเขียนการทดสอบหน่วย
  • ความรู้เกี่ยวกับการเยาะเย้ยและการยืนยัน

เราจะใช้ Kotlin เป็นภาษาการเขียนโปรแกรมและ JUnit5 เพื่อเขียนการทดสอบหน่วย

Mockito จะถูกใช้เพื่อทำงานกับการเยาะเย้ยและสายลับ

กลุ่มเป้าหมายคือนักพัฒนาซอฟต์แวร์จากแพลตฟอร์มใดๆ ที่กำลังมองหาบทใหม่ในอาชีพของตน

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

หากข้างต้นโอเคสำหรับคุณ มาเริ่มกันเลย

การพัฒนาที่ขับเคลื่อนด้วยการทดสอบทำงานอย่างไร

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ วงจร TDD

กระบวนการพัฒนาเป็นไปตามวงจรของ:

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

การเขียนการทดสอบที่ล้มเหลว (สี่เหลี่ยมสีชมพู)

ในขั้นตอนนี้ คุณจะเริ่มต้นด้วยการอธิบายว่าคุณต้องการให้โค้ดทำอะไร

ลองจินตนาการว่าคุณกำลังทดสอบโค้ดของคุณเพื่อดูว่าโค้ดทำงานถูกต้องหรือไม่ การทดสอบนี้เหมือนกับคำถามที่คุณถามโค้ด เช่น "คุณทำงานนี้ได้ไหม"

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

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

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

เปลี่ยนความสนใจของคุณจากความซับซ้อนทางเทคนิคไปสู่พฤติกรรมของซอฟต์แวร์

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

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

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

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

เคล็ดลับ

  • เจาะจง: เขียนกรณีทดสอบที่ชัดเจนและเฉพาะเจาะจงโดยเน้นไปที่ลักษณะหนึ่งของพฤติกรรมโค้ดของคุณ
  • เริ่มต้นอย่างง่าย:เริ่มต้นด้วยกรณีทดสอบที่ง่ายที่สุดซึ่งครอบคลุมฟังก์ชันพื้นฐานที่คุณต้องการ
@Test fun `a sum is calculated from two input numbers`() {}
  • ใช้ชื่อที่สื่อความหมาย:ตั้งชื่อการทดสอบของคุณอย่างอธิบายเพื่อให้ใครก็ตามที่อ่านการทดสอบรู้ว่าการทดสอบกำลังตรวจสอบอะไร
@Test fun `Font Ratio is fetched from data source INITIALLY`() {}

ข้อผิดพลาดทั่วไปที่ควรหลีกเลี่ยง

  • การทดสอบมากเกินไปในครั้งเดียว: หลีกเลี่ยงการทดสอบหลายอย่างในการทดสอบครั้งเดียว ซึ่งอาจทำให้ระบุได้ยากว่าสิ่งใดล้มเหลว
// Don't do this
@Test fun `pixelSize fits the standart sizes while fontSize is bigger than minumum supported font size but matches the list of special levels of size`() {}
  • ขึ้นอยู่กับรายละเอียดการใช้งาน: อย่าเขียนการทดสอบที่เชื่อมโยงกับการทำงานภายในของโค้ดอย่างแน่นหนา การทดสอบควรเน้นที่พฤติกรรม ไม่ใช่การนำไปปฏิบัติ
// Don't do this
@Test fun `pixelSize is Long and Non-Null and fits the standart sizes then calculated font size is non-null and of type Dimention`() {}

การใช้รหัสเพื่อผ่านการทดสอบ (จัตุรัสสีเขียว)

เมื่อคุณทำแบบทดสอบเรียบร้อยแล้ว ก็ถึงเวลาสอนโค้ดของคุณถึงวิธีทำงานอย่างถูกต้อง

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

เมื่อโค้ดของคุณผ่านการทดสอบ มันก็เหมือนกับไฟเขียวที่บอกว่า "ได้ ฉันสามารถทำงานได้แล้ว!"

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

เคล็ดลับ

  • เขียนโค้ดขั้นต่ำ:เขียนโค้ดที่ง่ายที่สุดที่ทำให้การทดสอบล้มเหลวผ่าน คุณสามารถอ่านเพิ่มเติมเกี่ยวกับวิธีหลีกเลี่ยงวิศวกรรมมากเกินไปได้ที่นี่
// Test Case 
@Test fun `Storage stores font ratio in key-value`() { 
 // Given
 val fontRatio = 2.0f
 val mockEditor = mockk<SharedPreferences.Editor>(relaxed = true)
 every { mockSharedPreference.edit() } returns mockEditor 
 every { mockEditor.putFloat(any(), any()) } returns mockEditor 
 every { mockEditor.apply() } just Runs 
 // When 
 storage.saveFontRatio(fontRatio) 
 // Then
 verify(exactly = 1) { 
 mockEditor.apply() 
 }
}
// Correct Implementation - Avoid extra implementation
class SharedPreferenceHelper( 
 private val sharedPreferences: SharedPreferences 
) { 
 fun saveFontRatio(fontRatio: Float) {
 sharedPreferences.edit().putFloat("font-ratio", fontRatio).apply() 
 } 
}
// Wrong Implementation 
class SharedPreferenceHelper(
 private val sharedPreferences: SharedPreferences
) { 
 fun saveFontRatio(fontRatio: Float) { 
 if (fontRatio <= 0.0f) 
 throw IllegalArgumentException("Font ratio must be greater than 0.0f") 
 storeValue(key = FONT_RATIO_KEY, value = fontRatio) 
} 
 private fun storeValue(key: String, value: Float){
 val editor = sharedPreferences.edit() editor.putFloat(key, value)
 editor.apply() 
 }
 fun getFontRatio(): Float { 
 return sharedPreferences.getFloat("font_ratio", 1.0f) } 
}
  • หลีกเลี่ยงการทำซ้ำ: อย่าทำซ้ำรหัส หากคุณพบว่าตัวเองเขียนตรรกะที่คล้ายกันในหลายๆ ที่ ให้พิจารณาปรับโครงสร้างใหม่ การปรับปรุงโค้ดหลักนี้สามารถทำได้ในระยะนี้ แต่หากการแก้ไขอาจมีผลข้างเคียงก็ไม่ต้องสนใจ
class ... {
 override fun getDefaultFontSize(): Float {
 val zoomRatio = DEFAULT_SSPEED * DEFAULT_FONT_RATIO / deviceDensity 
 val fontSize = zoomRatio * standardFontSize 
 return fontSize 
 }
 override fun getFontSizeBySSpeed(speed: Int): Float {
 val zoomRatio = speed * DEFAULT_FONT_RATIO / deviceDensity 
 val fontSize = zoomRatio * standardFontSize 
 return fontSize 
 }
}
class ... { 
 override fun getDefaultFontSize(): Float = calculate(DEFAULT_AGE)
 override fun getFontSizeByAge(age: Int): Float = calculate(age) 
 private fun calculate(age: Int): Float {
 val zoomRatio = age * DEFAULT_FONT_RATIO / deviceDensity 
 val fontSize = zoomRatio * standardFontSize 
 return fontSize 
 }
}

ข้อผิดพลาดทั่วไปที่ควรหลีกเลี่ยง:

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

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

เมื่อโค้ดของคุณผ่านการทดสอบแล้ว ก็ถึงเวลาทำความสะอาด

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

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

คุณสามารถถือว่าส่วนนี้เป็นขั้นตอนการบำรุงรักษาโค้ดแยกต่างหาก

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

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

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

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

โปรดทราบว่าโค้ด TDD ควรแสดงออกได้เองและไม่ขึ้นอยู่กับเอกสารประกอบ

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

เคล็ดลับ

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

ข้อผิดพลาดทั่วไปที่ควรหลีกเลี่ยง:

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

การเขียนการทดสอบที่ล้มเหลวใหม่ (การรีสตาร์ทโฟลว์)

ตอนนี้คุณคิดถึงสิ่งต่อไปที่คุณต้องการให้โค้ดของคุณทำ

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

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

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

เคล็ดลับ

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

ต่อไปนี้เป็นวิธีการทำงานของวงจรป้อนกลับ:

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

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

ข้อผิดพลาดทั่วไปที่ควรหลีกเลี่ยง:

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

นี่คือเหตุผลที่คุณไม่ควรข้ามขั้นตอนการทดสอบที่ล้มเหลว แม้ว่าคุณจะมั่นใจแล้วก็ตาม:

  • ความชัดเจนของเจตนา:การเขียนการทดสอบที่ล้มเหลวจะทำให้เจตนาของคุณสำหรับคุณลักษณะนี้ชัดเจนขึ้น โดยบังคับให้คุณพิจารณาพฤติกรรมและผลลัพธ์ที่แน่นอนที่คุณตั้งเป้าไว้ก่อนที่จะเริ่มนำไปใช้
  • การตรวจสอบสมมติฐาน:แม้ว่าคุณจะคิดว่าคุณเข้าใจคุณลักษณะนี้แล้ว การสร้างการทดสอบจะทำให้แน่ใจได้ว่าสมมติฐานของคุณถูกต้อง ความเข้าใจของคุณอาจจะถูกต้อง แต่การทดสอบจะพิสูจน์ได้
  • ตาข่ายนิรภัย:การเขียนการทดสอบที่ล้มเหลวจะเป็นการสร้างตาข่ายนิรภัยที่ป้องกันการถดถอยในอนาคต โดยทำหน้าที่เป็นข้อกำหนดสำหรับคุณลักษณะนี้และช่วยตรวจจับผลข้างเคียงที่ไม่ได้ตั้งใจ
  • การพัฒนาแบบค่อยเป็นค่อยไป:TDD ส่งเสริมการพัฒนาแบบค่อยเป็นค่อยไป คุณลักษณะใหม่แต่ละอย่างถูกสร้างขึ้นทีละขั้นตอน โดยมีความก้าวหน้าที่ชัดเจนตั้งแต่การทดสอบที่ล้มเหลวไปจนถึงการใช้งานจริง การข้ามขั้นตอนนี้จะขัดขวางความก้าวหน้านั้น
  • เอกสารประกอบ:การทดสอบที่ล้มเหลวจะบันทึกลักษณะการทำงานที่คาดหวังของคุณลักษณะ เอกสารนี้มีค่าสำหรับคุณและทีมของคุณ โดยเฉพาะอย่างยิ่งเมื่อกลับมาดูโค้ดอีกครั้งในอนาคต โปรดจำไว้เสมอว่ามีระบบในการสร้างรายงานโดยการแสดงรายการรหัสทดสอบทั้งหมดของคุณสำหรับผู้จัดการผลิตภัณฑ์และ QA รายงานเหล่านั้นเปิดเผยรายละเอียดที่คุณเห็นในผลิตภัณฑ์ ดังนั้น พยายามโน้มน้าวพวกเขาว่าคุณเข้าใจประเด็นนั้นอย่างถี่ถ้วน

วิธีการพัฒนาโดยใช้ TDD

TDD เน้นย้ำถึงความสำคัญของการเขียนการทดสอบอัตโนมัติเพื่อขับเคลื่อนการออกแบบและพัฒนาซอฟต์แวร์ สิ่งนี้นำไปสู่โค้ดที่เชื่อถือได้ บำรุงรักษาได้ และเปลี่ยนแปลงได้ง่ายขึ้นเมื่อเวลาผ่านไป

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

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

เราจะใช้คุณสมบัติการตั้งค่าขนาดตัวอักษรอัตโนมัติ

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

เราต้องการใช้คุณลักษณะที่ปรับขนาดแบบอักษรของหน้าจอจากความเร็วการเลื่อนที่ตั้งไว้ในหน้าโปรไฟล์ผู้ใช้

หากผู้ใช้ตั้งค่าความเร็วในการเลื่อนจาก 0 เป็น 1 ขนาดตัวอักษรควรเพิ่มขึ้น 1.3

การเพิ่มความเร็วการเลื่อนใดๆ มากกว่า 1 จะส่งผลให้ขนาดตัวอักษรเพิ่มขึ้น 1.2

คุณลักษณะนี้ช่วยให้ผู้ใช้ได้รับประสบการณ์ที่ดีขึ้นในขณะที่อ่านข่าว

ฉันยังได้แชร์โค้ดที่เราสำรวจในพื้นที่เก็บข้อมูล GitHub นี้ด้วย

อย่าลังเลที่จะโคลนและเล่นกับมัน

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

ดังนั้น ให้เปิด Android Studio และสร้างโปรเจ็กต์ใหม่

แผนภูมิการไหลของข้อมูลคุณสมบัติการตั้งค่าขนาดตัวอักษรอัตโนมัติ

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ DFD ของคุณลักษณะตัวอย่างในแอป Android

ด้านบนนี้เป็นแผนผังลำดับงานว่ากระแสข้อมูลควรมีลักษณะอย่างไรในท้ายที่สุด

ต่อไปนี้เป็นโครงร่างขององค์ประกอบที่น่าสนใจแต่ละส่วน:

09 คลาสจะจัดการตรรกะสำหรับการคำนวณและจัดเก็บ 13 ขึ้นอยู่กับความเร็วการเลื่อนที่เลือก

กรณีการใช้งานนี้จะขึ้นอยู่กับ 25 เก็บ 38 ค่า

ใน 45 มีวิธีจัดเก็บและเรียกข้อมูล 58 ค่าโดยใช้ 65 กลไก เมื่อใดก็ตามที่มี 76 ใหม่ ถูกส่งไปยังที่เก็บข้อมูล สิ่งที่สังเกตได้ใดๆ จะได้รับการปล่อยก๊าซเรือนกระจกด้วยค่าล่าสุด

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

เราจะมีส่วนประกอบ UI ที่จำเป็นในส่วนการตั้งค่าผู้ใช้เพื่อให้ผู้ใช้สามารถป้อนความเร็วการเลื่อนที่ต้องการได้ ซึ่งสามารถทำได้โดยใช้องค์ประกอบ UI มาตรฐานของ Android เช่น 117 หรือส่วนประกอบ UI ที่กำหนดเอง (เราจะไม่พูดถึงส่วนเหล่านี้)

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

วิธีการเขียนแบบทดสอบ

ขั้นตอนแรกคือสร้างคลาสทดสอบเองเสมอ ในกรณีนี้ เราจะมีคลาสการทดสอบอย่างน้อยดังต่อไปนี้:

  • 121
  • 130
  • 144

ฉันชอบเริ่มต้นด้วยส่วน ViewModel

ViewModel เป็นส่วนประกอบทางสถาปัตยกรรม Android ที่จะหลีกเลี่ยงการเปลี่ยนแปลงวงจรชีวิต (เช่น เบื้องหน้า พื้นหลัง ที่โฟกัส) ดังนั้นจึงเป็นสถานที่ที่ดีในการจัดเก็บรัฐของเรา

มาสร้างไฟล์ทดสอบภายใน 159 ไดเร็กทอรีของซอร์สโค้ดตามพาธแพ็กเกจเดียวกันกับโค้ดฟีเจอร์จริง

TDD ในทางปฏิบัติไม่เหมือนกับการพัฒนางานแบบเดิม

ด้วย TDD เราใช้ IDE เพื่อเพิ่มกระบวนการสร้างไฟล์และคุณสมบัติ (ฟิลด์) แต่เราสร้างไฟล์ทดสอบด้วยตนเอง! หลังจากลองไม่กี่ครั้ง IDE ด้านนี้จะมีประโยชน์

สร้างโครงสร้างโค้ด (แพ็คเกจ) จากนั้นสร้างคลาสทดสอบของคุณโดยคลิกขวาที่แพ็คเกจแล้วเลือก 163 ประเภท

เลือกชื่อที่สื่อความหมาย (บางทีคุณควรปฏิบัติตามแบบแผนหากคุณยังไม่ได้ทำ)

ตัวอย่างเช่น:174 โดยที่ 184 คือชื่อของส่วนประกอบที่ทดสอบ

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ ใช้ IDE เพื่อสร้างไฟล์

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ

ตอนนี้เรามาสร้างการทดสอบเปล่ากันดีกว่า พยายามให้กว้างที่สุด

ตามแผนภาพ เราจะไม่มีตรรกะมากนักสำหรับฟีเจอร์นี้

มีสองกลยุทธ์หลักในการเขียนฟังก์ชันการทดสอบหน่วย:

  • เอเอ
  • ให้/เมื่อ/แล้ว
@Test fun `strategy A`(){ 
 // Arrange
 // Act 
 // Assert 
}
@Test fun `strategy B`(){ 
 // Given 
 // When 
 // Then 
}

มาเลือกหนึ่งรายการและติดตามการทดสอบทั้งหมดของคุณ

แนวคิดก็เหมือนกัน:จัดกลุ่มโค้ดทดสอบของคุณเพื่อให้อ่านและบำรุงรักษาได้ง่าย

นี่คือสิ่งที่ฉันมีตอนนี้:

class UserProfileViewModel is tested for` {
 // Unimplemented Class 
 val viewModel = UserProfileViewModel()
 @Test
 fun Font Ratio is fetched from data source`(){}
 @Test
 fun `Scroll Speed update is called so fontSize calculations are triggered`() {}
 @Test
 fun `Font Ratio is updated with new emissions from data source`() {}
}

มาทำการทดสอบกันดีกว่า!

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ การทดสอบล้มเหลวเนื่องจากเป้าหมายการทดสอบหายไป

มันล้มเหลว. ที่จริงแล้ว บิลด์ล้มเหลว- ไม่ใช่การทดสอบ

ขอแสดงความยินดี! เราเพิ่งมาถึงขั้นตอนแรกในวงจร TDD:

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ ขั้นตอนแรกในรอบ TDD

เนื่องจากยังไม่มี ViewModel เราจึงมีสีแดง

ตอนนี้ เรามาสร้างอินสแตนซ์ของ ViewModel กันดีกว่า

ดังนั้นเราจึงใช้ IDE เพื่อสร้างคลาสที่ขาดหายไปหรือโค้ดที่ยังไม่ได้ใช้งาน

หากต้องการให้ป๊อปอัปโต้ตอบนี้ ฉันเลื่อนตัวชี้ไปที่ส่วนที่ยังไม่ได้ใช้งานแล้วกด Option + Return (บน macOS)

จากนั้น ปฏิบัติตามตัวเลือกที่ให้มา:

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ การดำเนินการ TDD:สร้างไฟล์เป้าหมายผ่านไฟล์ UnitTest

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ เลือกปลายทางที่ถูกต้องสำหรับไฟล์ใหม่

และตอนนี้เรามาทำการทดสอบอีกครั้ง (ขั้นตอนสุดท้าย):

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ แสดงการทดสอบที่ผ่านการทดสอบ

ใช่! มันผ่านไป

โปรดทราบว่าการทดสอบเหล่านี้มีเนื้อความว่างและไม่ได้ทดสอบอะไรเลย! ถูกต้องและไม่เป็นไร

เราควรสร้างคลาสการทดสอบทั้งหมดต่อไป (ยังคงมีเนื้อหาทดสอบว่างเปล่า) สำหรับทุกส่วนประกอบในแผนภาพ DFD - ฉันได้แชร์สิ่งเหล่านี้ไว้ที่ตอนต้นของบทความ

ซึ่งจะช่วยให้มีความเข้าใจคุณลักษณะนี้ชัดเจนยิ่งขึ้นก่อนที่เราจะนำไปใช้

ในที่สุด เราจะมีคลาสการทดสอบประมาณ 3-4 คลาสที่มีสถานการณ์ทั่วไปและการทดสอบหน่วยให้ครอบคลุม

มันจะมีลักษณะดังนี้:

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ กรณีทดสอบที่ว่างเปล่าน้อยที่สุด

ลองใช้หนึ่งในนั้นเป็นตัวอย่าง

แต่ก่อนหน้านั้น เราจะต้องทำงานกับโมเดลข้อมูล UI และโดเมนของฟีเจอร์นี้

ดังนั้น เพื่อให้สามารถย้ายข้อมูลไปมาได้ เรามาสร้างคลาสข้อมูลที่คุณต้องการล่วงหน้ากันดีกว่า

กลับไปที่ 196 ของเรา คลาสทดสอบ เรามีฟังก์ชันทดสอบหน่วยว่าง ลองใช้อันนั้นกัน

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

อนุญาตให้ดำเนินการตามข้อกำหนดเท่านั้น

ในกรณีนี้ เราต้องการกระแสข้อมูลที่เชื่อมต่อกับแหล่งข้อมูลที่สร้างขึ้นก่อนหน้านี้(207 ).

อย่าลืม:เราจำเป็นต้องมีการทดสอบที่ล้มเหลวก่อน

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ ใช้งานร่างกายภายใน

สังเกตส่วนที่ยังไม่ได้ใช้งานภายในตัวฟังก์ชันทดสอบ (ทำเครื่องหมายด้วยตัวอักษรสีแดง)

ตอนนี้ เรามาติดตั้งโค้ด จากนั้นปรับโครงสร้างใหม่เพื่อให้ผ่านไป

ฉันใช้ไลบรารี MockK สำหรับการเยาะเย้ยคลาสและวัตถุ และใช้ Turbine เพื่อทดสอบสตรีม Flow ที่นี่

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

มาสร้างการพึ่งพากันก่อนและเพิ่มลงใน ViewModel โดยใช้ Named Arguments อาร์กิวเมนต์ที่มีชื่อช่วยเราในการสร้างพารามิเตอร์ผ่าน IDE เพื่อแนะนำชื่อที่ถูกต้องผ่านโค้ดทดสอบ

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ สร้างพารามิเตอร์ที่ขาดหายไปโดยใช้ไดอะล็อก IDE

ทำเช่นเดียวกันกับ 219 ตัวแปรภายใน Repository

ในที่สุด รหัสทดสอบสุดท้ายอาจเป็นรหัสด้านล่าง:

class `UserProfileViewModel is tested for` {
 init {
 Dispatchers.setMain(Dispatchers.Unconfined)
 }
 val mockUserRepository = mockk<UserRepository>()
 @Test
 fun `Font Ratio is fetched from data source`() = runTest {
 // Given
 val expectedRatio = 2.0f
 every { mockUserRepository.fontRatio } returns flowOf(FontRatioUiModel(expectedRatio))
 val viewModel = UserProfileViewModel(userRepository = mockUserRepository)
 // When
 viewModel.fontRatio.test {
 val fromDataSource = expectItem()
 // Then
 assertEquals(/* expected = */ expectedRatio, /* actual = */ fromDataSource.fontRatio)
 }
 }
...
}

โปรดทราบว่าเราไม่ได้ใช้ส่วนภายในของ ViewModel หรือ Repository ที่นี่

เราเพียงสร้างส่วนที่ขาดหายไปเพื่อลบข้อผิดพลาดออกจากตัวทดสอบ

เราจะนำรายละเอียดเหล่านั้นไปใช้ในการวนซ้ำครั้งถัดไป

ดำเนินการทดสอบทันที

แน่นอนว่ามันจะล้มเหลว เพราะเราไม่ได้ใช้ 224 ภายใน 234 .

ตอนนี้ ปรับโครงสร้าง ViewModel ใหม่เพื่อให้ผ่านการทดสอบ (การใช้งานขั้นต่ำ)

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

นี่คือรหัสสุดท้าย:

class UserProfileViewModel(
 userRepository: UserRepository
) : ViewModel() {
 val fontRatio: StateFlow<FontRatioUiModel> = userRepository.fontRatio.stateIn(
 initialValue = FontRatioUiModel(DEFAULT_FONT_RATIO),
 scope = viewModelScope,
 started = SharingStarted.Lazily
 )
 companion object {
 private const val DEFAULT_FONT_RATIO = 1.0f
 }
}

ทำการทดสอบอีกครั้ง และบูม! ผ่านไป!

Master Android TDD:คู่มือเชิงปฏิบัติสำหรับการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ ผ่านการทดสอบหลังจากใช้งานโค้ดหลักเพียงเล็กน้อย

ด้วยการทดสอบหน่วยนี้ เราได้นำส่วนหลักของ 246 ไปใช้งาน ส่วนประกอบ แต่เฉพาะส่วนที่จำเป็นเท่านั้น ทำเช่นเดียวกันกับกรณีทดสอบที่เหลือ

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

ใช้เวลาทำความเข้าใจข้อกำหนดทางเทคนิคและผลิตภัณฑ์ก่อน จากนั้นจึงเผยแพร่แผนและเริ่มดำเนินการ หลังจากลองไม่กี่ครั้ง คุณจะคิดแบบ TDD ได้ง่ายขึ้น

ซอร์สโค้ด

ซอร์สโค้ดและพื้นที่เก็บข้อมูลสำหรับโปรเจ็กต์นี้มีอยู่ในหน้า GitHub ของฉัน

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

บทสรุป

ดังนั้น หลังจากดำดิ่งลงสู่ Test-Driven Development (TDD) และสำรวจอย่างเจาะลึกแล้ว ฉันต้องบอกว่ามันเป็นตัวเปลี่ยนเกม!

ให้ฉันอธิบายให้คุณฟัง:

ประเด็นสำคัญ:

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

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

อาจดูแปลกเล็กน้อยที่มีการทดสอบที่ไม่ได้ทำอะไรเลย แต่ทั้งหมดนี้เป็นส่วนหนึ่งของแผน

ต่อไป เราได้วางแผนการที่ชัดเจนเกี่ยวกับสิ่งที่ฟีเจอร์ของเราควรทำ โดยอิงตามแผนภูมิการไหลของข้อมูล สิ่งนี้ช่วยให้เราเข้าใจข้อกำหนดก่อนที่จะเริ่มใช้งาน

เมื่อมีแผนอยู่ในมือแล้ว เราจึงเริ่มใช้ส่วนประกอบที่จำเป็น (ViewModel ในกรณีนี้) เพื่อให้แน่ใจว่าการทดสอบของเราล้มเหลวก่อน ใช่แล้ว การทดสอบที่ล้มเหลวเป็นสิ่งที่ดีใน TDD!

เราค่อยๆ เชื่อมต่อส่วนต่างๆ เข้าด้วยกัน เช่น การตั้งค่า 258 คลาสเพื่อจัดการการคำนวณขนาดตัวอักษรตามความเร็วในการเลื่อนอัตโนมัติ (ตรวจสอบ repo โปรเจ็กต์)

นอกจากนี้เรายังจัดการกับองค์ประกอบ UI ซึ่งช่วยให้ผู้ใช้สามารถป้อนความเร็วการเลื่อนที่ต้องการได้ และตรวจสอบให้แน่ใจว่าขนาดตัวอักษรได้รับการปรับขนาดตามนั้น (ตรวจสอบ repo ของโครงการ)

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

ในตอนท้าย เรามีคุณลักษณะ "การตั้งค่าขนาดแบบอักษรอัตโนมัติ" ของเราพร้อมทำงาน พร้อมด้วยการทดสอบที่ผ่านการทดสอบอย่างยอดเยี่ยม

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

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

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

ขอให้มีความสุขในการเขียนโค้ด! 🚀

เรียนรู้การเขียนโค้ดฟรี หลักสูตรโอเพ่นซอร์สของ freeCodeCamp ช่วยให้ผู้คนมากกว่า 40,000 คนได้งานในตำแหน่งนักพัฒนา เริ่มต้น