Continuous Integration – เทคนิคการพัฒนาโปรแกรมแบบบูรณาการต่อเนื่อง

เข้าเรื่องดีกว่า Continuous Integration หรือการทำบูรณาการอย่างต่อเนื่อง … อ่านชื่อไทยคงจะงง เอาเป็นว่าผมขอเรียกย่อ ๆ ว่า CI ละกัน CI เป็นวิธีปฎิบัติในการพัฒนาซอฟต์แวร์อย่างหนึ่งที่เน้นให้นักพัฒนารวมเอาโค๊ดของตัวเองเข้ามาในโค๊ดสายหลักอย่างต่อเนื่อง และนักพัฒนาแต่ละคนจะทำงานอยู่บนฐานโค๊ด (Code Base) เดียวกัน ทำให้มีความแตกต่างระหว่างกันน้อยที่สุด

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

คีย์เวิร์ดของขั้นตอนการปฎิบัตินี้คือคำว่า “ต่อเนื่อง” หลายคนคงคิด คำว่า “ต่อเนื่อง” นั้นมันคือบ่อยขนาดไหน ? ที่เคยอ่านเจอหลาย ๆ ที่จะบอกว่า “ทุก ๆ วัน” ผมว่าการที่เราเช็คอินโค๊ดทุกวันเนี่ยมันจะว่าห่างก็ได้ (กับคนที่ทำงานชิ้นเล็ก ๆ ) หรือจะว่าถี่ก็ได้ (กับคนที่ทำงานชิ้นใหญ่ ๆ ) ดังนั้นผมว่าไอ้คำว่า “ทุก ๆ วัน” มันฟังดูไม่ค่อยมีความหมายชอบกล

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

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

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

นอกจากจะต้องเช็คอินบ่อย ๆ แล้ว เราต้องอัพเดตฐานโค๊ดบ่อย ๆ อีกด้วย อันนี้อาจจะตั้งเป็นสักวันละครั้ง การเช็คอินบ่อย ๆ และอัพเดตบ่อย ๆ เช่นนี้เป็นการลดการรวมโค๊ดเป็นชุดใหญ่ ๆ ที่ทำด้วยตัว version control ไม่ได้ แล้วพอรวมโค๊ดด้วยมือเองก็มักจะเกิดปัญหารวมแล้วผิด รวมแล้วใช้ไม่ได้ หรือใช้เวลาการรวมโค๊ดนานมาก อาจจะทำให้เกิดปัญหาถดถอย (regression) ของโปรแกรมทำให้ต้องทดสอบแบบถดถอยใหม่อีกด้วย

การรวมโค๊ดบ่อย ๆ แต่เป็นชุดเล็ก ๆ นั้นมองเผิน ๆ อาจจะเป็นภาระของโปรแกรมเมอร์เพราะต้องทำบ่อย  แต่ว่าโปรแกรม version control นั้นมีความสามารถในการรวมโค๊ดด้วยตัวมันเองอยู่แล้วในระดับหนึ่ง ดังนั้นเอาเข้าจริง ๆ มันมีผลกระทบต่อตัวโปรแกรมเมอร์น้อยมาก

ส่วนต่อไปที่สำคัญสำหรับ CI ก็คือการบิลด์โปรแกรมอย่างต่อเนื่อง ทุก ๆ วัน หรือที่เรามักจะเรียกกันว่า Nightly Build การบิลด์ทุกวันแบบนี้เป็นการทดสอบโค๊ดขั้นแรกเพื่อที่จะหาปัญหาขั้นต้นของโปรแกรม ก็คือปัญหาคอมไพล์ไม่ผ่าน ทำให้เราสามารถแก้ไขได้อย่างทันท่วงทีอีกเช่นกัน ในโมเดลเดิมที่กำหนดวันบิลด์โปรแกรมจะพบว่าหลายครั้งที่เราเจอว่าพบปัญหาบิลด์โปรแกรมไม่ได้ในวันสุดท้ายซึ่งหลาย ๆ ครั้งมีโค๊ดที่ขัดแย้งกันมากทำให้ไม่สามารถแก้ไขปัญหาได้ภายในวันนั้น (กับโปรเจคเล็ก ๆ อาจจะไม่มี แต่ถ้าเจอโปรเจคใหญ่อย่างเช่นแกนของ Linux แล้วเรื่องนี้ไม่ใช่เรื่องแปลก) แต่กับ CI ที่มีการบิลด์โปรแกรมทุกวันแล้วเราจะพบปัญหานี้ก่อนและสามารถแก้ไขปัญหาได้ทันท่วงทีครับ

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

แต่ถ้ามีแค่การทดสอบว่าโปรแกรมมันคอมไพล์ผ่านมันก็ออกจะน้อยไปอีก หลังจากที่มีการทำ Nightly Build แล้วตัวโปรแกรมจะถูกรันชุดทดสอบหน่วยโปรแกรม (Unit Test Suite) ซึ่งเป็นการทดสอบว่าหน่วยย่อย ๆ ของโปรแกรม เช่น ฟังก์ชั่น คลาส มาโคร และอื่น ๆ นั้นทำงานได้ถูกต้องตามที่ออกแบบไว้หรือไม่

ในขั้นตอนนี้ในอดีตนั้นจะทำกันด้วยมือ ซึ่งเป็นอะไรที่ใช้เวลานานมาก แต่ว่าในปัจจุบันด้วยการมาของตัว Unit Test Framework อย่าง JUnit หรือ NUnit ก็ทำให้เราสามารถที่จะตั้งให้มันทำงานอัตโนมัติได้อีกเช่นกัน ดังนั้นเราจึงสามารถรันมันได้ทุกคืนนั่นเอง แต่ทั้งนี้โปรแกรมเมอร์จะต้องเขียนโปรแกรม Unit Test ขึ้นมาเองด้วยนะครับ ถ้าเป็นโค๊ดที่เก่าและอยู่มานานแล้วก็ออกจะเป็นปัญหาอยู่ ดังนั้นก็ควรจะเขียนโปรแกรม Unit Test ขึ้นมาเสียแต่เนิ่น ๆ นะครับ

พอถึงจุดที่ Unit Test จบแล้ว ถ้าใช้วิธี Agile ควบคู่ด้วยขั้นตอนต่อไปก็คงเป็นการส่งตัวโปรแกรมไปให้ QA ทดสอบต่อในขั้นต่อไป (Functional Testing) นะครับ ซึ่งจะไม่พูดถึง

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

เขียนเองแล้วก็อยากทำ แต่ว่าด้วยลักษณะของงานตัวเองคงไม่มีโอกาสล่ะครับ แฮะ ๆ

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

This site uses Akismet to reduce spam. Learn how your comment data is processed.