วันพุธที่ 22 มีนาคม พ.ศ. 2560

Building Software II : Test-Driver Development With python Tutorial

http://chimera.labs.oreilly.com/books/1234000000754/ch01.html#_obey_the_testing_goat_do_nothing_until_you_have_a_test

จาก Text Book ด้านบน

สิ่งที่ได้เรียนรู้เพิ่มเติมจากการไปทดลองทำตาม (แบบเหมือนกันทุกขั้นตอน)

เพิ่มเติมคือได้นำไฟล์ geckodriver ไปไว้ใน 

/usr/local/bin

ของเครื่องด้วย

CH1 :

ได้ รู้จักการใช้งาน .gitignore แบบผ่าน commandline

CH2 :

Functional Test - การทดสอบภายใต้ มุมมอง ของผู้ใช้งาน (User โดยไม่รู้อะไรเกี่ยวกับ ระบบด้านในเลย) หรือเรียกได้หลายแบบเช่น Acceptance test , ene to end test ก็ได้เช่นกัน

เขาแนะนำว่า การเขียน คอมเม้น ของการ test แบบ นี้ เราควรจะเขียน ให้ สามารถอ่านได้เข้าใจง่ายว่า ทดสอบอะไรอยู่ อย่างในตัวอย่างเขาจะยกสถาณะการต่างๆ เลยว่า User คิดอย่างไรต้องการอย่างไร และ ทดสอบยังไง (เช่น เธอต้องการให้ title เว็ป เป็น To-Do list เป็นต้น ก็ได้ทำการทดสอบว่า

# She notices the page title and header mention to-do lists
assert 'To-Do' in browser.title
 
 
 
 
 เราไม่ควร คอมเม้น ในสิ่งที่ไร้สาระเช่น บอกว่า increase a by 1 เพราะ จากโค้ดที่ b += 1 เราก็ทราบอยู่แล้ว แต่เราควรจะบอกไปว่า + 1 เพื่ออะไร ทำใม

assert 'To-Do' in browser.title, "Browser title was " + browser.title
       

จากโค้ด ด้านบนจะเห็นว่าเราสามารถ ทำให้ AssertError เป็นไปตามที่เราต้องการได้
จากโค้ด ถ้ามัน Error จะขึ้น บอกว่า Browser title was ????


และต่อมา

from selenium import webdriver
import unittest

class NewVisitorTest(unittest.TestCase):  #

    def setUp(self):  #
        self.browser = webdriver.Firefox()

    def tearDown(self):  #
        self.browser.quit()

    def test_can_start_a_list_and_retrieve_it_later(self):  #
        # Edith has heard about a cool new online to-do app. She goes
        # to check out its homepage
        self.browser.get('http://localhost:8000')

        # She notices the page title and header mention to-do lists
        self.assertIn('To-Do', self.browser.title)  #
        self.fail('Finish the test!')  #

        # She is invited to enter a to-do item straight away
        [...rest of comments as before]

if __name__ == '__main__':  #
    unittest.main(warnings='ignore')  #

 
เมื่อเรารันไฟลฺ์ นี้ มันจำทำการ Test ทุกฟังก์ชั่นที่ขึ้นต้น ด้วย test_
และก่อนทำการ test จะใช้ฟังก์ชั่น setUp ก่อนทุกครั้ง และ เมื่อจบการ test หรือ error จะใช้งาน tearDown เมื่อเสร็จ
 ส่วน self.fail จะเป็นการ บังคับให้ error ได้

และได้เรียนรู้ Git -a เพิ่มมา (auto add any track)

User story - เรื่องราวของ ผู้ใช้งาน (เช่นต้องการอะไร เพราะอะไร ทำใม ใช้ในการเขียน comment และ เป็นแนวทางในการทดสอบ ระบบ จากมุมมองของผู้ใช้งาน)

CH3 :

การทดสอบต้องคิดเสมอว่า เราจะทดสอบอะไร ทำใม เพื่ออะไร เพื่อไม้ให้ เราทดสอบผิดพลาด(หรือผิดวัตถุ ประสงค์)

Unit test - เป็นการทดสอบใน มุมมอง ของผู้ พัฒนา หรือ เป็นการทดสอบจากด้านใน สนใจโครงสร้าง ของโค้ด ความถูกต้องของ การทำงาน โดยจะทดสอบ ทีละส่วน ย่อยๆ ของการทำงานเลย

ขั้นตอน คร่าวๆ

 1 ทดสอบจากมุมมองของ User ( functional_test ) พบ Bug ?!!!
 2 ทำการพยายามแก้ไขข้อผิดพลาดนั้น โดยการ ทดสอบในส่วนย่อยๆลงไปของโค้ด เพราะพยายามหาส่วนที่ทำงานผิดพลาดนั้นๆและแก้ไขมัน
 3 ถ้าพบ Unit test ไม่ผ่าน ก็ทำการทดสอบในขนาดที่เล็กลงไปอีก จนกว่าจะแก้ไขได้
[บางครั้งต้องทำ 2 3 วนไปเรื่อยๆ ] 
 4 ลองรัน functional_test อีกรอบ ถ้าผ่านก็ ถือว่าโอเค

ต่อมา เขา พูดถึงบทความว่า

Functional tests should help you build an application with the right functionality, and guarantee you never accidentally break it. Unit tests should help you to write code that’s clean and bug free.

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


ต่อมา พบว่า django มี ส่วนช่วยในการทำ Unit test อยู่แล้ว (ไฟล์ tests.py ใน folder app)
ซึ่งการรัน ทำได้โดยการพิม python3 manage.py test มันจะทำการทดสอบทุกๆฟังก์ชั่นที่ขึ้นต้องด้วย test

MVC ของ django จะแปลกๆ (ที่เรารู้ๆกันอยู่)

 model - model.py
 control - view.py
 view - template

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

We can start to settle into the TDD unit-test/code cycle now:
  1. In the terminal, run the unit tests and see how they fail.
  2. In the editor, make a minimal code change to address the current test failure.
And repeat!

คือ Cycle ดังนี้
 1 ทำการ รัน UNIT TEST และพบว่ามัน fail
 2 ทำการแก้ไขให้สั้นที่สุด
ทำวนไปเรื่อยๆ

เน้น ว่า แก้ไข ให้สั้นที่สุดหรือน้อยที่สุดเท่าที่จะทำให้มันทำงานได้ !!

จากที่เขาให้ลองทำนั้นคือ เขาพยายาม แก้ไข น้อยมากคือตั้งแต่ พบว่า 

self.assertTrue(response.content.startswith(b'<html>'))
 
 
เขา ก็ทำการเพิ่มส่วนหน้า <html> ไปเท่านั้นและทำการทดสอบใหม่ทันทีแม้ว่าจะเห็นว่า มันไม่มีเนื้อหาด้านในอีกก็ได้(ซึ่งควรมี)

ซึ่งเขาก็จะเจอ assert error ที่เตือนว่าไม่มีเนื้อหาด้านในตามที่จะทบสอบ และเขาก็เพิ่มส่วนนั้นเข้าไปและทดสอบต่อทันทีเช่นเดิม

และต่อมาได้ เจอการใช้ git log --oneline เพิ่มขึ้นมาสำหรับดู log แบบบรรทัดเดียวต่อ 1 commit

CH4 :

Soon ..

[ ติดสอบ ] 




 



ไม่มีความคิดเห็น:

แสดงความคิดเห็น