Part5 : Testing
Introducing automated testing
What are automated tests?
การทดสอบเป็นกิจวัตรที่ตรวจสอบการทำงานของโค้ด
การทดสอบอัตโนมัติคือระบบจะทำการทดสอบให้คุณ โดยคุณสร้างชุดการทดสอบเพียงครั้งเดียว จากนั้นเมื่อคุณทำการเปลี่ยนแปลงในแอป คุณสามารถตรวจสอบว่าโค้ดของคุณยังคงใช้งานได้ตามที่คุณตั้งใจไว้ตั้งแต่แรก โดยไม่ต้องทำการทดสอบด้วยตนเองให้เสียเวลา
Why you need to create tests
- การทดสอบจะช่วยคุณประหยัดเวลา
- การทดสอบไม่เพียงแค่ระบุปัญหาเท่านั้น แต่ยังป้องกันไม่ให้เกิดปัญหาด้วย
- การทดสอบทำให้โค้ดของคุณน่าสนใจยิ่งขึ้น
- การทดสอบช่วยให้ทีมทำงานร่วมกัน
Writing our first test
We identify a bug
Question.was_published_recently( ) เมธอดจะคืนค่า True หาก Question มีการเผยแพร่ภายในวันสุดท้าย (ซึ่งถูกต้อง) แต่ถ้าฟิลด์ Question ของ pub_date เป็นในอนาคต (ซึ่งไม่แน่นอน)
คอนเฟิร์มbug โดยใช้ shell วิธีการตรวจสอบสำหรับคำถามที่มีวันที่อยู่ในอนาคต:
Create a test to expose the bugเปลี่ยนสิ่งที่เพิ่งทำใน shell ให้เป็น automated test
เราได้สร้าง django.test.TestCase คลาสย่อยด้วยเมธอดที่สร้าง Questionอินสแตนซ์ด้วย a pub_date ในอนาคต จากนั้นเราตรวจสอบผลลัพธ์ของ was_published_recently( ) -ซึ่งควรเป็นเท็จ
Running tests
เกิด AssertionError เนื่องจากการใช้ assertIs( ) method พบว่า was_published_recently( ) returns True แต่เราต้องการให้ return False
Fixing the bug
Question.was_published_recently( ) ควร return False หาก pub_date เป็นปัญหาในอนาคต แก้ไขเมธอดใน models.py เพื่อให้ return True หากวันที่เป็นวันที่ในอดีตด้วย:
และทำการทดสอบอีกครั้ง -ซึ่ง run test ผ่าน:
More comprehensive testsเพิ่มวิธีการทดสอบอีกสองวิธีในคลาสเดียวกัน เพื่อทดสอบพฤติกรรมของวิธีการอย่างครอบคลุมมากขึ้น:
และตอนนี้เรามีการทดสอบ 3 รายการที่ยืนยันว่า Question.was_published_recently( ) จะส่งกลับค่าที่เหมาะสมสำหรับคำถามในอดีต ปัจจุบัน และในอนาคต
Test a viewA test for a view
สำหรับการทดสอบนี้ เราต้องการตรวจสอบพฤติกรรมของมันเหมือนกับที่ผู้ใช้จะสัมผัสผ่านเว็บเบราว์เซอร์ แต่ก่อนที่จะแก้ไขอะไร มาดูเครื่องมือที่เราจัดการกันก่อน
The Django test client
Django จัดทำการทดสอบ Client เพื่อจำลองผู้ใช้โต้ตอบกับโค้ดในระดับมุมมอง เราสามารถใช้มันใน tests.py หรือแม้กระทั่งใน shell
เราได้ทำการตั้งค่าสภาพแวดล้อมการทดสอบใน shell แล้ว setup_test_environment( ) ติดตั้งตัวแสดงเทมเพลตซึ่งจะช่วยให้เราตรวจสอบแอตทริบิวต์เพิ่มเติมบางอย่างในการตอบสนอง จากนั้น import the test client class เมื่อพร้อมแล้ว เราสามารถขอให้ลูกค้าทำงานให้เราได้
Improving our view
เราจำเป็นต้องแก้ไข get_queryset( ) method และเปลี่ยนเพื่อให้ตรวจสอบวันที่โดยเปรียบเทียบกับ timezone.now( )
Question.objects.filter(pub_date__lte=timezone.now( )) จะ return ชุดข้อความค้นหาที่มี Questions ซึ่ง pub_date น้อยกว่าหรือเท่ากับ - นั่นคือ ก่อนหน้าหรือเท่ากับ timezone.now
Testing our new view
เราจะสร้าง shortcut function เพื่อสร้างคำถามและคลาสทดสอบใหม่:
- อย่างแรกคือฟังก์ชันทางลัดคำถาม create_question เพื่อนำการทำซ้ำออกจากกระบวนการสร้างคำถาม
- test_no_questions ไม่สร้างคำถามใดๆ แต่ตรวจสอบข้อความ: “ไม่มีการสำรวจความคิดเห็น” และตรวจสอบว่า latest_question_list ว่างเปล่า
- ใน test_past_question เราสร้างคำถามและตรวจสอบว่าคำถามนั้นปรากฏในรายการ
- ใน test_future_question เราสร้างคำถามด้วย a pub_date ในอนาคต ฐานข้อมูลจะถูกรีเซ็ตสำหรับวิธีการทดสอบแต่ละวิธี ดังนั้นคำถามแรกจะไม่มีอีกต่อไป และ index ก็ไม่ควรมีคำถามใดๆ ในนั้นอีก
- ฟังก์ชันอื่นๆ เป็นการบอกเล่าเรื่องราวของผู้ดูแลระบบและระบบประสบการณ์ของผู้ใช้บนไซต์ และตรวจสอบว่าในทุกสถานะและทุกการเปลี่ยนแปลงใหม่ในสถานะของระบบ ผลลัพธ์ที่คาดหวังจะได้รับการเผยแพร่
Testing the DetailViewแม้ว่าคำถามในอนาคตจะไม่ปรากฏในดัชนี ผู้ใช้ยังคงสามารถเข้าถึงได้หากทราบหรือคาดเดา URL ที่ถูกต้อง ดังนั้นเราจึงจำเป็นต้องเพิ่มข้อจำกัดที่คล้ายกันใน DetailView:
จากนั้นเพิ่มการทดสอบเพื่อตรวจสอบว่าสามารถแสดงคำถามที่มี pub_date ในอดีตได้ และแสดงคำถามคำถามที่มี pub_date ในอนาคตไม่ได้: