Monday, November 26, 2007

พฤติกรรมของ test mode ใน Grails

ใน Grails เราสามารถปรับแต่ง mode การทำงานได้เป็น 3 mode ก็คือ development สำหรับใช้พัฒนา, test สำหรับใช้ทดสอบ และ production สำหรับใช้งานจริง

พฤติกรรมของแต่ละ mode จะแตกต่างกันเล็กน้อย และเราสามารถตั้งค่าบางอย่างเช่น data source ให้กับแต่ละ mode ของ Grails

Grails จะทำงานใน test mode เมื่อผู้ใช้ต้องการจะทดสอบระบบด้วยคำสั่ง


$ grails test-app



ซึ่งจะเกี่ยวข้องกับการทดสอบเชิงหน่วย (unit tests) และเชิงรวม (integration tests)

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

ดังนั้นเมื่อต้องการทดสอบการทำงานใน test mode จึงจำเป็นต้องแยก data source ออกมาเป็นฐานข้อมูลเฉพาะสำหรับ test และหากเราใช้ BootStrap ในการเตรียมการข้อมูลแล้วนั้น ใน method setUp ของทุก ๆ test case จะต้องมีการเรียกใช้ closure init ของ BootStrap ไว้ทุกครั้ง


class MyTests extends GroovyTestCase {
void setUp() {
new BootStrap().init()
}

void testSomething() { ... }
}

Thursday, November 1, 2007

สรุปหลังสร้าง application ด้วย Grails

ผมได้มีโอกาสสร้าง Grails application สำหรับ production อีกครั้ง เป็น application เล็ก ๆ และครั้งนี้มีเวลาทำเพียง 1 สัปดาห์เศษ

GUI layer ผมใช้ OpenLaszlo อย่างเคย เพราะต้องการ application เป็น AJAX และคุ้นมือกับ OpenLaszlo มาพอสมควรแล้ว
เหตุที่ทำไมไม่ใช้เฟรมเวิร์คอื่น เช่น GWT เหตุผลหลักเพราะไม่ agile, compile-debug cycle สำหรับ GUI layer นั้นดูจะทำได้ช้า (term of agility) กว่า OpenLaszlo
ผมไม่ใช้ UI ที่เป็น JavaScript framework เช่น YUI, Ext หรือ Dojo เพราะทนปวดหัวไม่ไหว
OpenLaszlo อยู่กลาง ๆ ระหว่าง GWT และ JavaScript framework ทั้งหลาย เพราะมี compiler ที่ช่วย check error ได้พอสมควร, ใช้ tag (box model แบบ XUL), ภาษาก็เป็น JavaScript (จริง ๆ แล้ว OpenLaszlo ก็ใช่ว่าจะ debug ง่าย แต่อย่างน้อยก็ง่ายกว่า JavaScript ล้วน ๆ)

ผมออกแบบ layout ของ UI โดยใช้ Photoshop แล้วแยก layer ออกเป็นชิ้น ๆ (ไม่ได้ merge แล้ว slice) save แยกเป็น .png
แล้วเอามารวมกันใน code ของ OpenLaszlo

approach รอบนี้เป็น prototype-driven สร้าง UI เสร็จแล้ว define XML ที่ต้อง bind ด้วยระหว่าง client กับ server
เป็น local XML dataset ของ OpenLaszlo ไว้ก่อน (feature นี้ช่วยได้มากสำหรับ prototyping)
จากนั้นเอาก็ดูจาก schema ของมันไปเขียน code ของ controller และใช้เตรียมโดเมนคลาส

ผมใช้ Grails 1.0-RC1 ไม่ลง plugin เพิ่มเลยนอกจาก Quartz 0.2 (ใช้มันทำ job scheduling) เพราะ application คราวนี้หลัก ๆ เป็น Ajax อย่างที่บอก
- ฝั่ง admin แทบไม่ทำอะไรเลย ใช้ scaffolding ล้วน ๆ
- ด้านที่เชื่อมต่อกับ OpenLaszlo ใช้ REST ล้วน ๆ โดย render XML ออกจาก controller โดยตรง ใช้วิธียิง error code พวก 200, 500 ออกไปให้ UI layer จัดการ check เอาเอง ตรงนี้แยกเป็น 2 กลุ่ม กลุ่มทำงานแบบ RPC กับกลุ่ม CRUD เลยทำให้ได้สร้าง controller framework เล็ก ๆ ของฝั่ง OpenLaszlo ออกมาใช้โดยปริยาย เป็น controller แบบพิเศษนิดหน่อยคือต้องทำงานกับ event

ไม่มี SQL เลยแม้แต่บรรทัดเดียว :)
ไม่ได้ใช้ DTO pattern เพราะใช้ XML เป็น media แทน
การ update data จากฝั่ง client มา server ใช้ก้อน XML แล้วแปลงเป็น Map ด้วย XMLParser ของ Groovy
แล้วส่งให้ GORM ผ่าน obj.properties (มองมุมนี้ก็ยัง preserve data-hiding อยู่ครับ)

ใช้ Java Mail เป็นตัวส่ง mail ผ่าน SSL server (SMTP ของ Google App for your domain)
application มี File upload ตัวรับเป็นกลไลของ Spring (แต่ไม่ต้อง config อะไรเพิ่มใน Grails)

การ authen ใช้ MD5 มีการ encode ตั้งแต่ฝั่ง client แล้วเทียบ password ที่ digest แล้วกับฝั่ง server เพื่อเลี่ยงการใช้ SSL
มีพิเศษตรงการ sync กับ .htaccess ของ Apache httpd เพื่อให้ password คุมการเข้าถึง directory ให้ด้วย
เรื่องสนุกมีอยู่ว่าต้องไปแกะ code htdigest.c ว่ามัน digest อะไร เพราะตอนแรกลองแล้ว ค่า hash ออกมาหน้าตาไม่เหมือนกัน

server ตอนนี้ deploy ลง Jetty 6 เนื่องจากอีกซักพักจะสร้าง Comet app เพื่อแทนที่การ pooling จากฝั่ง UI ที่ใช้อยู่ในปัจจุบัน
ตอนนี้ยังเรียกใช้ ContinuationSupport ใน Grails controller ไม่ได้

สรุปเบา ๆ ว่ารอบนี้ agile กว่าทุกครั้งและงานเสร็จทันเวลา ข้อเสียที่ยังแก้ไม่ตกคือตอนทำยังเปลือง CPU/Memory อยู่เพราะต้ิอง run ทั้ง Grails app และ OpenLaszlo