Wednesday, April 18, 2018

TDD : Test-Driven Development Python Part 4

      สวัสดีครับ ในบทความนี้เราจะมาเริ่มกันที่เขียน test ว่า function ของเราสามารถส่ง input เข้าไปใน web app ของเราได้รึป่าวโดยเราจะไปทำที่  functional tests กัน เปิดไฟล์ functional_tests.py แล้วเขียน code ดังนี้

 

เมื่อ run test


จะพบว่ามัน error ประมาณว่า ไม่สามารถหา element <h1> ดังนั้นเราจะต้องไปทำ html ให้กับ web app ของเรากัน
"Don’t Test Constants and Templates"
**ในส่วนของ html หรือ  Templates เราจะไม่มีการ test นะ**
 เริ่มจากสร้าง folder templates แล้วไปสร้างไฟล์ html  ชื่อ home.html


จากนั้นเขียน code ตามนี้


แล้วย้อนกลับไปที่ไฟล์ views.py แล้วเขียน code ตามนี้


เมื่อ run test


มันจะขึ้น error ประมาณว่า "หา templates ไม่เจอ" ซึ่งทำให้เรานึกขึ้นได้ว่า "เรายังไม่ได้ติดตั้ง app"

เราจะต้องไปที่ ไฟล์ settings.py ที่อยู่ใน folder superlists แล้วแก้ไฟล์ดังนี้


เมื่อ run test


เราจะพบว่ามัน error "หา templates ไม่เจอ" ตอนนี้ได้ถูกแก้ไขแล้วแต่! มันไป error ว่ามัน AssertionError แทน ตรงจุดนี้น่าจะมีอะไรผิดที่ output ดังนั้นเราจะแก้ไขแบบ ง่ายๆไปก่อนโดยให้ไปที่ file tests.py  ที่อยู่ใน folder list ของเรา แล้วเขียน code ดังนี้


เมื่อ run test


เราจะเห็นได้ว่า error ได้หายไปแล้ว

ต่อมาเราจะมา check กันว่า เรา render templates ได้ถูกต้อง โดยให้ไปที่ file tests.py  ที่อยู่ใน folder list ของเรา แล้วเขียน code ดังนี้ (ดูตรงขีดแดงๆไว้นะ)


เมื่อ run test


บางคนอาจจะสงสัยว่า "อ้าว ทำไม templates มันไม่เจอละ หรือ บางคนอาจจะรู้แล้ว" ส่วนคนที่ไม่รู้ผมจะมาเฉลยให้นะ ที่ templates  ไม่ออกเพราะว่า "ดูตรงขีดแดงๆใน file tests.py ที่ผมให้แก้ ตรงนั้นชื่อไฟล์มันผิดครับ มันต้องเป็น ชื่อ home.html ตามชื่อ file templates เราสิ ส่วนสาเหตุที่ผิดเพราะผมจงใจครับ เพราะการเขียน test ในครั้งแรกเราต้องจงใจให้มันผิดครับ จะได้แก้ไข

ดังนั้นให้เราไปแก้ render_to_string ครับ


เมื่อ run test


เราจะเห็นว่า error ได้หายไปแล้ว

จากนั้นเราจะมา Refactoring code เรากัน โดยเราจะไปที่ file tests.py ใน folder list แล้วลบ def test_root_​url_resolves แล้วเขียน def test_uses_home_template(self): ไปแทน


เมื่อ run test


แสดงว่า code ของเราไม่ error

จำได้ไหมครับว่า "functional test ของเรายังคง error อยู่" ซึ่งได้เวลาที่เราจะแก้กันแล้ว โดยไปที่ file template (home.html) ของ app list ของเราแล้วแก้ code ดังนี้


เมื่อ run test


เราจะเห็น error อะไรซักอย่างซึ่งอ่านละคลุมเครือ ดังนั้นเราจะมาแก้ให้มันแสดง error ที่ชัดเจน โดยไปที่ file functional_test.py แล้วเขียน code ดังนี้



เมื่อ run test


เราก็จะได้ error ที่ชัดเจนขึ้นกว่าเดิมนั้นคือ
AssertionError: False is not true : New to-do item did not appear in table
ซึ่งเราก็ขอจบบทความนี้ไว้เพียงเท่านี้ก่อนนะ ในบทถัดไปเราจะมาแก้ไข error ดังกล่าวกัน
วันนี้เราเดินทางกันมาไกลมาก เดี๋ยวมาต่อในบทความต่อไปนะ อย่าลืม commit ละ

Monday, April 16, 2018

MVC or Model-View-Controller

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

credit pic : https://chavp.files.wordpress.com/2011/05/asp_mvc_2.png

Model-View-Controller

      Model-View-Controller หรือ ที่เรารู้จักกันในชื่อของ MVC ( ไม่ใช่ MVP นะ ) มันคือ ความพยายามที่จะแยกส่วนของ Model และ View ออกจากกัน โดยใน MVC นั้น จะมี Controller เพิ่มขึ้นมาเป็นตัวกลาง โดยหน้าที่ของ Controller ก็คือการจัดการกับ Model โดยขึ้นอยู่กับการกระทำที่ได้จาก View และยังทำหน้าที่สรรหาข้อมูลจาก Model เพื่อนำไปแสดงผลที่ View โดย View เราก็จะเรียกมันว่า User Interface เพราะมันเป็นส่วนที่ใช้ติดต่อกับผู้ใช้ ส่วน 

ทำไม ต้องเปลี่ยนมาใช้ MVC

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

ขอบคุณข้อมูลจาก 
  1. https://arnondora.in.th/what-is-mvc/
  2. https://basketman.wordpress.com/2009/11/04/mvc-model-view-controller/
  3. https://medium.com/@leelorz6/mvc-mvp-mvvm-%E0%B8%84%E0%B8%B7%E0%B8%AD%E0%B8%AD%E0%B8%B0%E0%B9%84%E0%B8%A3-%E0%B9%81%E0%B8%A5%E0%B8%B0%E0%B8%95%E0%B9%88%E0%B8%B2%E0%B8%87%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B8%AD%E0%B8%A2%E0%B9%88%E0%B8%B2%E0%B8%87%E0%B9%84%E0%B8%A3-ca16a19631dc

TDD : Test-Driven Development Python Part 3

      สวัสดีครับ ใน part 3 เราจะมาลองเขียน unit test กันนะ โดยรายละเอียดของ unit test ผมจะแปะลิงค์ไว้ให้นะครับ

http://softwaredevii.blogspot.com/2018/04/knowledge-what-test.html

ก่อนที่เริ่ม unit test เราจะมาสร้าง app ก่อนนะ


เมื่อเราได้ app แล้ว เราก็จะได้เริ่มเขียน unit test ซะที โดยให้ไปหา file tests.py ใน app ของเรา


จากนั้นเขียน unit test แบบง่ายๆตามนี้ครับ


จากนั้นให้ run test ดู


จะพบว่ามัน Error ซึ่งเป็นที่แน่นอนอยู่แล้วเพราะการเขียน test ครั้งแรกเราจงใจให้มัน error ก่อนเพื่อดูว่า code ทำงานได้เป็นปกติ ปล. ตรงนี้เป็น smoke test นะอ่านได้ที่บทความ "What the TEST" ในหมวด Knowlage ได้เลย

เนื่องจากว่าเจ้า Django เนี่ยมันเป็น MVC เนื้อหาตรงนี้จะแปะลิงค์ให้เช่นเคยนะ

http://softwaredevii.blogspot.com/2018/04/mvc-or-model-view-controller.html

ดังนั้นต่อมาเราจะมา test homepage กัน ไปที่ไฟล์ tests.py ใน app lists เช่นเดิมแล้วเขียน code ตามนี้


จากนั้นให้ run test ดู


จะพว่ามัน error ว่าไม่สามารถ import home_page แน่นอนมันต้อง import ไม่ได้เพราะ "เรายังไม่มี home page" ดังนั้นเราจะไปทำ home page กันก่อน

โดยการทำ home page นั้นให้ไปที่ views.py ที่อยู่ใน folder lists ของเรา แล้วเขียน coed ตามนี้


ทุกคนจะเกิดคำถามว่า "เฮ้ย! เขียนแค่นี้อะนะ" ใช่ครับ เราจะเขียนไปเท่านี้ก่อนที่เหลือค่อยว่ากัน จากนั้นให้ run test


จะพบมัน error แปลกๆ ซึ่งเราควรจะอ่าน Traceback เหล่านี้เพราะมันจะอกเราได้ว่า มัน error อะไร
จากที่อ่านเราสามารถสันนิษฐานได้ว่า "เราต้อง URL mapping." ดังนั้นเราจะไปทำ URL mapping กัน
โดยไปที่ urls.py ใน folder superlists ของเรา แล้วเขียน code ตามนี้



จากนั้นให้ run test


ก็จะ error แปลกๆเช่นเคย แต่ถ้าอ่านดีๆเราจะพบว่ามัน error
TypeError: view must be a callable or a list/tuple in the case of include().
ซึ่งหมายความว่า error อันเก่าได้ถูกแก้ไขแล้วแต่ตอนนี้มัน error เพราะว่าใน views.py ของเรา 
มีปัญหา เนื่องจาก home_page มันเท่ากับ none เราจึงต้องไปแก้ไขมัน

โดยให้เรากลัไปที่ file views.py แล้วเขียน code ตามนี้


จากนั้นให้ run test


จะพบว่ามันไม่ error อะไรแล้ว นั่นความหมายว่า test ผ่านหมด

ในเมื่อ test ผ่านหมดแล้วเราก็จะมาทำ code ให้ดีขึ้นกันโดยเริ่มจากเราจะมาทำให้ app ของเรา return เป็น html จริงๆ โดยให้ไปที่ไฟล์ tests.py ใน folder lists แล้วเขียน code ดังนี้


จากนั้นให้ run test


จะพบว่ามัน error เพราะว่า home_page() ของเรานั้นไม่มีการส่ง arguments มาให้ดังนั้นเราต้องไปแก้ที่ function home_page() ในไฟล์ views.py ที่อยู่ใน lists ก่อน โดยเขียน code ดังนี้


จากนั้นให้ run test


จะพบว่า error ดังกล่าวได้หายไปแล้ว ก็ขอจบบทความนี้เพียงเท่านี้ก่อนนะ วันนี้เหนื่อยแล้วขอพักแปปป อย่าลืม commit ละ

อันนี้ run test functional นะ


TDD : Test-Driven Development Python Part 2

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

https://softwaredevii.blogspot.com/2018/04/knowledge-tdd-or-test-driven-development.html

โดยเริ่มแรกเราจะมา Test ว่า browser title มี ชื่อว่า To-Do รึป่าว ให้เปิด file functional tests แล้วเขียน code ตามนี้ครับ


จากนั้นให้ลอง run file functional test ปล.ต้อง run server ด้วยนะ


จะพบ ว่ามัน AssertionError ครับ ซึ่งถ้าเราสังเกตดีๆจะพบว่า ในส่วน Browser title ของเรานั่นไม่ได้ชื่อว่า To-Do แต่มันเป็นื่ออื่น ซึ่งถ้าไม่สังเกตดีๆจะไม่รู้เลยว่าทำไม error แบบนี้ ดังนั้นเราจะมาหาทางทำให้มันดูดีขึ้น

เปิด file functional test ขึ้นมาเหมือนเดิมแล้วเขียน code ตามนี้


จากนั้นให้ run functional test ครับ 


จะพว่ามัน AssertionError ครับ แต่ มันจะพบว่ามันจะแจ้งว่า To-Do not found in "Django: the web framwork บลาๆๆ" เราจะรู้แล้วว่า เออออ มัน Error เพราะชื่อ browser title มันไม่ได้ชื่อ To-Do นี่เอง

Implicit wait 

เนื่องจาก บางครั้งเวลาเรา run test เราจะพบว่า เราไม่รู้เลยว่ามันเปิด Browser มา test ยังไงเพราะเวลา test ตัว browser ถูกปิดลงเร็วมากเราจึงจะมาทำให้ browser ปิดช้าลงหน่อยเราจะได้ดูว่ามัน test ยังไง

เปิด file functional test ขึ้นมาเหมือนเดิมแล้วเขียน code ตามนี้


จากนั้นให้ run functional test 


เราจะพบว่า browser จะเปิดประมาณ 3 วินาทีแล้วดับไป

ในตอนนี้ก็จบ Part ที่ 2 แล้วนะครับ ซึ่งก่อนจบในบทความวันนี้เราก็จะมา commit กันก่อนนะครับ

Wednesday, April 11, 2018

TDD : Test-Driven Development Python Part 1

       สวัสดีครับ วันนี้เราจะมาทดลองทำ TDD หรือ Test-Driven Development ด้วย Python และ Django นะครับ ตามที่เคยพูดในบทความเรื่อง "What the TEST" ไปนะครับว่าเราจะใ้ช้หนังสือ "Test-Driven Development with Python"



โอเคผมจะเริ่มตามหนังสือเลยนะ เริ่มจากลองเขียน Test ง่ายๆก่อนเลย 

Start Simple

ผมสร้าง File ชื่อ "functional_test.py" แล้วเขียน Code ตามนี้เลย 

                            


เมื่อสั่ง run เราจะพบว่ามัน Error อะไรซักอย่าง แถมมันยังขึ้น web browser มาด้วย 


เมื่อเราอ่านตามหนังสือมาเรื่อยๆจะพบว่าเขาให้เราสร้าง Project django 

                                         

และหลังจากนั้นเขาให้เรา runserver

เราจะพว่า Error ที่เกิดขึ้นในตอนแรกได้หายไปแล้ว ผมจึงคิดได้ว่า 
"มันจะต้อง run server ก่อนไม่งั้นมันจะ error เพราะมันกำลัง test สิ่งที่เกี่ยวกับ web แต่ว่าตอนนี้มันยังไม่มี server นั้นจึงทำให้ไม่มี web ให้ลอง Test"



Start Git

ในส่วนนี้เขาจะให้เราได้ลองใช้คำสั่งต่างๆที่เกี่ยวกับ git นะครั เราก็ทำตามได้เลยโดยจะมีการสอน git init สอนให้ commit และอื่นๆ


ในส่วนการทดลองของ part I ก็จบลงแล้วนะครับ ติดตามได้ใน part ต่อๆไปนะครับ