ไปเจอบทความการเปิด website TwitBlogs.com ที่ TechCrunch ผมก็เลยลองเล่นว่ามันต่างจาก twitwall อย่างไร
เริ่มกันเลย
Features ที่เหมือนกัน
1. ใช้ username/password จาก twitter ทั้งสองเว็บ
2. เมื่อทำการ post Blog ใหม่ๆ หรือแก้ไขข้อมูล จะทำการ post ไปที่ twitter เสมอ ซึ่งทำเหมือนกันทั้งสองเว็บ
3. เมื่อทำการ comment จะส่งการ comment ไปที่ twitter เสมอ ซึ่งทำเหมือนกันทั้งสองเว็บ
4. Layout, Theme, Tone สี จะเป็นไปตาม Twitter มาก
Feateres ที่แตกต่่างกัน
1. ในการสร้าง blog ที่ TwitBlogs จะสามารถสร้างเป็น Draft ได้ ส่วน Twitwall จะไม่มี
2. TwitBlogs สามารถเปลี่ยน UI ไปทำการ post เหมือนใน Twitter ได้ แต่ UI ที่เป็น CSS ยังไม่ smooth เท่าไร UI นั้นเหมือนเป็น theme ของ iPhone เลย
ส่วน UI ของ Twitwall จะแข็งๆ ไม่มีอะไรมาก แต่มี Editor ช่วยในการเขียนดีกว่า
3. TwitBlogs เพิ่งเปิดมาใหม่ทำให้ link ในหน้าต่างๆ ยังไม่ครบ เช่น about page, Term page, Privacy page
================
แต่ทั้งสองเว็บพยายามที่จะ promote ให้ผู้ใช้งาน twitter ที่ต้องการพิมพ์มากกว่า 140 ตัวอักษร แต่ยังสามารถ post ข้อความใน twitter ได้อยู่
ดูๆ ไปทาง NokNok ซึ่งเป็น Twitter Clone ของคนไทยจะแก้ปัญหานี้ไปในตัวด้วยแล้ว
วันอาทิตย์ที่ 14 ธันวาคม พ.ศ. 2551
วันจันทร์ที่ 8 ธันวาคม พ.ศ. 2551
เพิ่ม Widget ของ Google Friend Connect ใน blog แล้ว
ผมทำการเพิ่ม Widget ของ Google Friend Connect ใน blog แล้วครับ
ใช้งานง่ายดีครับ ใครสนใจใช้ลองไปที่นี่ครับ
http://www.google.com/friendconnect/
หรือไปดูขั้นตอนที่นี่ครับ
http://sitdh.blogspot.com/2008/12/google-friend-connect-social-gadget.html
Related link from Roti
วันศุกร์ที่ 5 ธันวาคม พ.ศ. 2551
Update ข่าวสารของโลก java และ grails ว่ามีอะไรใหม่ๆ อออกมากันบ้าง
Update ข่าวสารของโลก java และ grails ว่ามีอะไรใหม่ๆ อออกมากันบ้าง
1. Grails 1.1 beta
2. JavaFX 1.0
3. JBoss AS 5.0
4. Hibernate Search 3.1 GA
5. Spring Integration 1.0 GA
Related link from Roti
วันจันทร์ที่ 24 พฤศจิกายน พ.ศ. 2551
Google Makes Major Interface Change To Search: SearchWiki
ตอนนี้ google ได้เพิ่ม feature ใหม่เข้ามาในการค้นหาข้อมูลคือ SearchWiki [ Make your own search result ] จาก blog ของคุณ pphetra บอกว่าถ้าต้องการเปิดใช้งานนั้นให้ใส่ * ในการค้นหาข้อมูลเช่น test * เมื่อกดปุ่มค้นหาจะสามารถใช้งาน UI ใหม่ของ Google Search Engine
อ้อ อย่าลืม set preference ของ UI เป็นภาษาอังกฤษด้วย
VDO สาธิตการใช้งาน
ที่มา ::
http://www.techcrunch.com/2008/11/20/google-makes-major-interface-change-to-search-searchwiki/
SearchWiki: make search your own
Related link from Roti
วันพฤหัสบดีที่ 13 พฤศจิกายน พ.ศ. 2551
Sequel, The Database Toolkit For Ruby
Sequel คือ OR Mapping Layer ซึ่งจะ mapping กับ Ruby Object ซึ่งเป็นอีกหนึ่งทางเลือกจาก ActiveRecord และ DataMapper
Features ต่างๆ ที่น่าสนใจของ Sequel ดังนี้
1. Connection Pooling
2. DSL สำหรับการสร้าง SQL
3. สนับสนุน prepared statements
4. Master/Slave Configuration
5. ตัวที่น่าสนใจคือ Database Sharding
ที่มา :: http://www.infoq.com/news/2008/11/sequel-ruby-db-toolkit
Related link from Roti
วันจันทร์ที่ 10 พฤศจิกายน พ.ศ. 2551
เริ่มต้น ActiveRecord with Merb
ตอนแรกคิดว่าจะลองใช้ DataMapper แต่ไปๆ มาๆ ยังไงไม่รู้เลยมาลองที่ตัว ActiveRecord ก่อนก็แล้วกัน
หลังจากที่ลองสร้าง Controller กับ View ไปแล้ว ตอนนี้มาขอพูดการสร้าง Model ตามแนวคิดของ MVC ใน merb
ในการจัดการ Model ใน merb นั้นแนะนำมา 3 ตัวคือ
1. ActiveRecord
2. DataMapper
3. Sequel
ผมเลือก ActiveRecord มาเป็นตัวแรก โดย ActiveRecord นั้นถูกสร้างมาด้วยแนวคิด Active Record Pattern ของคุณ Martin Fowler ซึ่งทำหน้าที่จัดการ RDBMS หรืออาจจะเรียกว่า O/R Mapping ก็ได้
ไม่พูดมากแล้ว มาเริ่มต้นกันเลยดีกว่า
ก่อนอื่นเริ่มที่การติดตั้ง ActiveRecord กันก่อน ด้วยคำสั่ง
$gem install activerecord merb_activerecord merb-helpers
ต่อมาทำการสร้าง merb application ด้วยคำสั่ง
$merb-gen app my_application
ผมเลือกใช้ DBRAS คือ mysql ครับ ดังนั้นอย่างแรกที่ต้องทำคือ การกำหนด database configuration ให้กับ merb application ดังนี้
- กำหนด orm ที่จะใช้ ซึ่งผมใช้ ActiveRecord จึงแก้ไขใน file file config/init.rb ดังนี้
dependency "merb-helpers"
use_orm :activerecord
- กำหนด database connection ใน file config/database.yml ดังนี้
:adapter: mysql
:database:
:username:
:password:
:host:
:socket: /tmp/mysql.sock
:encoding:
ต่อมาผมต้องการจะสร้าง Application ทั่วไปให้สามารถทำการเพิ่มข้อมูลและแสดงผลอยู่ในหน้าเดียวกัน ดังนั้นผมจึงเริ่มการสร้างดังนี้
1. ก่อนอื่นผมขอสร้าง table ขึ้นมาก่อนชื่อว่า post มี column ดังนี้
id int
body varchar(500)
create_date datetime
[ ผมชอบออกแบบ database ก่อนเสมอครับ ]
2. สร้าง Model ชื่อ Post ดังนี้ [ ชื่อเดียวกับ Table ]
$ merb-gen model Post
merb จะสร้าง file /app/models/post.rb ขึ้นมาดังนี้
class Post < posts =" Post.find(" order =""> "create_date DESC" )
render
end
6. ทำการแก้ไข View ที่ /app/views/posts/index.html.erb ดังนี้
http://gist.github.com/23498
โดยผมใช้ partial มาใช้ เนื่องจากผมชอบแนวคิดการ reuse ของ element ต่างๆ ซึ่งจากตัวอย่างนี้จะเป็นการ reuse ข้อมูลแต่ละตัวที่เพิ่มเข้าไปในระบบ
จากนี้สามารถลอง run merb ด้วยคำสั่ง $merb ได้ แล้วเข้าไปลอง run ที่ http://localhost:4000/posts
7. เพิ่มส่วนการเพิ่มข้อมูล ซึ่งผมจะเพิ่มในส่วน View ใน file /app/views/posts/index.html.erb ดังนี้
[ ผมเพิ่มไปที่ท้าย file ]
http://gist.github.com/23500
8. แก้ไข controller ใน file /app/controllers/post.rb ผมจะเพิ่ม action create เข้าไปเพื่อทำการเพิ่มข้อมูลลง table เมื่อทำงานเสร็จจะ redirect ไปยัง action index เพื่อแสดงผลข้อมูลทั้งหมด ดังนี้
def create
Post.create( :body => params[ :body ], :create_date => Time.now )
redirect url(:action => "index")
end
9. จะชักช้าอยู่ใยครับ run merb เลยดีกว่า แล้วเข้าไปทดลองใช้งานที่ http://localhost:4000/posts
10. สุดท้าย ผมมี css เพิ่มเข้าไปใน public/stylesheets/master.css ดังนี้
#posts.container {
border: 10px solid #eaeaea;
min-height: 240px;
position: relative;
}
div.post {
position: relative;
border-bottom: 2px solid #c0c0c0;
}
div.post p.body {
color: #3d4043;
}
div.post p.created {
color: #d5d5d5;
position: absolute;
top: 0px;
right: 10px;
font-weight: bold;
font-size: 15px;
}
form {
background-color: #d5d5d5;
padding: 20px;
}
form input[type=text] {
font: 17px "Helvetica", Helvetica,, sans-serif;
padding: 3px 5px;
color: #424242;
}
form button {
font-size: medium;
padding: 5px 10px;
}
คุณ @punneng บอกว่าแรกๆ ก็แบบนี้แหละครับ พอใช้ไป แล้วไปลอง deploy แล้วจะรู้สึกเองครับ อิอิอิ
ที่มา
http://www.socialface.com/slapp/
http://www.rubyinside.com/merb-tutorials-and-resources-716.html
Related link from Roti
วันอาทิตย์ที่ 9 พฤศจิกายน พ.ศ. 2551
เริ่มต้นกับ Merb
เห็นคุณ @punneng พูดถึง Merb มาตั้งแต่ยังไม่เป็น version 1.0 แต่ตอนนี้มันออก version 1.0 มาแล้ว เลยขอนำมาลองหน่อยว่าเป็นยังไงบ้าง
มาเริ่มการทดลองแบบคนไม่มีอะไรเกี่ยวกับ Ruby เลยครับ
My Environment
- OS : Windows
- ใช้ cygwin
Sotfware
1. Ruby
2. Ruby Gem
มาเริ่มต้นการติดตั้ง
1. install ruby
$./configure --prefix=/usr/local/ruby/myruby
$make
$make install
2. install ruby gem
[ RubyGems is the name of the project that developed the gem packaging system and the gem command ]
$ ruby setup.rb
3. install merb
$gem install merb
4. install mongrel [ Mongrel is a fast HTTP library and server for Ruby ]
$gem install mongrel
5. Hello Merb
$merb-gen app test_01
$cd test_01
$merb
ทดลองเข้า http://localhost:4000 ใน browser ก็จะเจอหน้า Merb
ลองทดสอบสร้าง controller
$merb-gen controller Hello
file Hello.rb จะถูกสร้างที่ app\controllers .ให้แก้ไขดังนี้
class Hello < Application
def index
'Hello Merb'
end
end
แล้วลอง start merb และเข้าไปที่ http://localhost:4000/hello จะแสดงคำว่า Hello Merb ใน browser
เท่านี้ก็ถือว่าเป็นการเริ่มต้นกับ Merb ของผมล่ะครับ
ต่อไปเดี๋ยวจะลองดู DataMapper ครับว่าเป็นยังไง
Related link from Roti
วันพฤหัสบดีที่ 6 พฤศจิกายน พ.ศ. 2551
Solved :: Hibernate + UTF-8
ผมได้ยินคำถามนี้มาจากหลายๆ ที่ว่าทำไมบันทึกข้อมูลภาษาไทยแล้วเป็น ?????? มีหลากหลายวิธีที่จำแก้ปัญหา แต่ผมขอแนะนำไว้ดังนี้
ทุกๆ อย่างๆ ในทุกๆ layer เป็น UTF-8 ดังนี้
- jsp file ก็ใส่ encoding เป็น UTF-8
- Servlet ก็ใส่ Servlet Filter ให้กำหนด request.setcharecterEncoding( "UTF-8" )
- URL Connection String จาก Hibernate ไป DBRMS ก็ใส่ encoding=UTF-8 ไปด้วย ถ้า RDBMS สนับสนุน
- และสุดท้าย DB ของคุณต้องเป็น UTF-8 ด้วยครับ ทั้ง DB, Table, Column
ถ้าคุณทำเพียงเท่านี้คุณก็จะไปเจอปัญหา ??? อีกแล้วครับ
^_^ ^_^ ^_^
Related link from Roti
วันอังคารที่ 28 ตุลาคม พ.ศ. 2551
update ข่าวสาร
1. Google Earth App สำหรับ iPhone สามารถ load ได้ที่ Apple Store สามารถใช้งานได้ทั้งแบบ Online และ Offline
http://www.macnewsworld.com/story/64949.html
2. Widows Live, google, yahoo สนับสนุน Open ID กันหมดแล้ว แล้วเราจะรอช้าอยู่ใย
3. Google ทำการเพิ่ม Gadget ของ Google Docs และ Google Calendar ใน GMail แล้วนะครับ ลองใช้กันดู
4. ICT ใช้งบ 100-500 ล้านบาท ในการ block web ที่หมิ่นเบื้องสูง
5. Yahoo Application Platform [ YAP ]
http://www.macnewsworld.com/story/64949.html
2. Widows Live, google, yahoo สนับสนุน Open ID กันหมดแล้ว แล้วเราจะรอช้าอยู่ใย
3. Google ทำการเพิ่ม Gadget ของ Google Docs และ Google Calendar ใน GMail แล้วนะครับ ลองใช้กันดู
4. ICT ใช้งบ 100-500 ล้านบาท ในการ block web ที่หมิ่นเบื้องสูง
5. Yahoo Application Platform [ YAP ]
วันพุธที่ 15 ตุลาคม พ.ศ. 2551
Oracle :: SQL สำหรับการดึงข้อมูลล่าสุด
SQL สำหรับการดึงข้อมูลล่าสุด โดยใช้บน Oracle Database เป็นดังนี้
ตัวอย่าง จะเป็นการดึงข้อมูล 10 records ล่าสุด
SELECT *
FROM (SELECT ROWNUM rno , my_column
FROM some_table)
WHERE rno > (SELECT (MAX (ROWNUM) - 10)
FROM some_table)
ซึ่งสามารถทำการ ordered หรือเรียงลำดับของ ROWNUM ดังนี้
ROW_NUMBER () OVER (ORDER BY some_column ASC) AS rno
อย่าลืมใส่ index ด้วยนะครับ เพื่อความเร็วของ query ครับ
Related link from Roti
วันศุกร์ที่ 10 ตุลาคม พ.ศ. 2551
java.io.IOException :: Too many open file
ปัญหามีไว้ให้แก้จริงๆ ด้วย
Problem
java.io.IOException :: Too many open file
วิเคราะปัญหา
- มีการ access มายังระบบ 400,000 ครั้ง ซึ่งวิเคราะจาก Access Log ของระบบ
- ใช้คำสั่ง lsof [ List of open file ] ใน Linux เพื่อดูว่าแต่ละ process ทำการเปิด file อยู่เท่าไร ดังนี้
>lsof -p
สาเหตุของปัญหาที่อาจจะเกิดขึ้นได้
- มีการเปิด file หรือ IO จำนวนมากที่ OS จะรับได้
การแก้ไขปัญหา
- มีการเปิด file ใน code แต่ไม่ทำการปิด file ???
- มีการแตก process ย่อยจากการใช้คำสั่ง Runtime.getProcess() ซึ่งคุณรูไหมว่า จะมีการเปิด Stream/Pipe ไว้ 3 ช่องทางคือ
stdin, stdout, stderr [ Input, Output, Error ] ดังนั้นควรจะต้องปิดทั้ง 3 ท่อหรือช่องทางไปด้วย เช่น
process.getInputStream().close();
process.getOutputStream().close();
process.getErrorStream().close();
- ในระดับ OS สามารถกำหนด จำนวนสูงสุดในการเปิด file [ เป็นการต่อลมหายใจของระบบเท่านั้น ]
ซึ่งสามารถดูจำนวนได้ด้วยคำสั่ง
>ulimit -a
ดูในส่วนของ open files และสามารถแก้ไขค่าได้
Website Reference
https://support.bea.com/application_content/product_portlets/support_patterns/wls/TooManyOpenFilesPattern.html
Related link from Roti
วันพฤหัสบดีที่ 9 ตุลาคม พ.ศ. 2551
ทดลองใช้ JSR166y
พอดีไปเห็นบทความเกี่ยวกับ JSR166y ที่นี่ http://groovy.dzone.com/news/concurrency-jsr-166y-meets-gro
โดยเป้าหมายหลักของ JSR166y คือ lightweight task framework สำหรับ Java Platform ซึ่งใช้แนวคิดของ Fork and Join Framework เพื่อนำมาแก้ไขปัญหาการใช้งาน Thread ในระบบแบบขนาน เนื่องจาก Thread นั้นกินทรัพยากรของระบบมากจนเกินไป
๋JSR166y นี้เป็น library ตัวใหม่ที่วางแผนไว้ว่าจะเพิ่มเข้าไปใน JDK 7 ครับ
สำหรับ library นั้นสามารถ Download ได้ที่นี่ http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166y.jar
ส่วน JavaDoc ก็ที่นี่ครับ http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/overview-summary.html
ผมลองทำการทดสอบใช้งานดังนี้
- ทำ application เพื่ออ่าน Rss Feed จากหลายๆ เว็บ ดังนี้
Environment ที่ใช้ทดสอบ
- Windows XP
- JDK 6
String[] url = {
"http://www.grails66.com/blog/feed/",
"http://www.rails66.com/blog/feed/",
"http://www.ajax66.com/blog/feed/",
"http://www.seam66.com/blog/?feed=rss2",
"http://www.ofbiz66.com/blog/?feed=rss2"
};
ForkJoinExecutor fje = ParallelArray.defaultExecutor();
ParallelArray p = ParallelArray.createFromCopy(url, fje);
p.replaceWithMapping(new RssFeed());
System.out.println(p.asList());
สร้าง class RssFeed สำหรับการทำงานในแต่ละ process ที่แตกออกมา ( Fork ) ดังนี้
class RssFeed implements Op {
@Override
public String op(String url) {
System.out.println(System.currentTimeMillis() + " : " + url);
return getData(url);
}
}
เมื่อทำการ run แล้วจะเห้นได้ว่าจะไม่ได้ทำการแบบ sequential เลย จะทำงานแบบ parallel ครับ ตรงนี้ทำงานดูดีครับ
หรืออาจจะกำหนด Pool ของ ForkJoin process ได้เองดังนี้
ForkJoinPool pool = new ForkJoinPool(3); // กำหนดเป็น 3
ParallelArray p = ParallelArray.createFromCopy(url, pool);
ทดสอบ run ก็จะได้ผลอีกแบบครับ
เอกสารเพิ่มเติม
http://groovy.dzone.com/news/concurrency-jsr-166y-meets-gro
โดยเป้าหมายหลักของ JSR166y คือ lightweight task framework สำหรับ Java Platform ซึ่งใช้แนวคิดของ Fork and Join Framework เพื่อนำมาแก้ไขปัญหาการใช้งาน Thread ในระบบแบบขนาน เนื่องจาก Thread นั้นกินทรัพยากรของระบบมากจนเกินไป
๋JSR166y นี้เป็น library ตัวใหม่ที่วางแผนไว้ว่าจะเพิ่มเข้าไปใน JDK 7 ครับ
สำหรับ library นั้นสามารถ Download ได้ที่นี่ http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166y.jar
ส่วน JavaDoc ก็ที่นี่ครับ http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/overview-summary.html
ผมลองทำการทดสอบใช้งานดังนี้
- ทำ application เพื่ออ่าน Rss Feed จากหลายๆ เว็บ ดังนี้
Environment ที่ใช้ทดสอบ
- Windows XP
- JDK 6
String[] url = {
"http://www.grails66.com/blog/feed/",
"http://www.rails66.com/blog/feed/",
"http://www.ajax66.com/blog/feed/",
"http://www.seam66.com/blog/?feed=rss2",
"http://www.ofbiz66.com/blog/?feed=rss2"
};
ForkJoinExecutor fje = ParallelArray.defaultExecutor();
ParallelArray
p.replaceWithMapping(new RssFeed());
System.out.println(p.asList());
สร้าง class RssFeed สำหรับการทำงานในแต่ละ process ที่แตกออกมา ( Fork ) ดังนี้
class RssFeed implements Op
@Override
public String op(String url) {
System.out.println(System.currentTimeMillis() + " : " + url);
return getData(url);
}
}
เมื่อทำการ run แล้วจะเห้นได้ว่าจะไม่ได้ทำการแบบ sequential เลย จะทำงานแบบ parallel ครับ ตรงนี้ทำงานดูดีครับ
หรืออาจจะกำหนด Pool ของ ForkJoin process ได้เองดังนี้
ForkJoinPool pool = new ForkJoinPool(3); // กำหนดเป็น 3
ParallelArray
ทดสอบ run ก็จะได้ผลอีกแบบครับ
เอกสารเพิ่มเติม
http://groovy.dzone.com/news/concurrency-jsr-166y-meets-gro
ป้องกันการ run process แบบไม่สิ้นสุดใน Java
วันนี้ทำการทดสอบ migrate data process ซึ่งจะมีบาง process ทำการ run process ผ่าน java.lang.Process
โดยปัญหาที่พบคือ อาจจะมีบาง process ที่ทำงานไม่จบสักที [ ไม่มี signal ออกมาจาก process นั้น ]
ส่วน code ที่เป้นปัญหาคือ มัน
while( true ) {
try {
int process_status = process.waitFor();
break;
} catch( InterruptedException e ) {
}
}
ปัญหามันเกิดขึ้นมาเมื่อ process ไม่มี signal อะไรออกมา
ดังนั้น สามารถแก้ปัญหาได้โดยการใช้ Timer มาช่วย จะกำหนด timeout ได้ ดังนี้
Timer timer = new Timer();
timer.schedule(new InterruptProcess(Thread.currentThread()), 5000);
try {
exitStatus = proc.waitFor();
}
catch (InterruptedException e) {
proc.destroy();
}
finally {
timer.cancel();
}
และ Class InterruptProcess ซึ่งจะ extends มาจาก timerTask ดังนี้
class InterruptProcess
extends TimerTask {
Thread target = null;
InterruptProcess(Thread target) {
this.target = target;
}
/**
* run
*/
public void run() {
target.interrupt();
System.out.print("-|Run Interrupt|-");
}
}
จากตัวอย่าง ผมทำการกำหนด timeout = 5 วินาที ดังนั้นถ้า process มีเวลาทำงานมากที่สุดคือ 5 วินาทีเท่านั้น ส่วน process ที่ run เสร็จเร็วก็ไม่มีปัญหาอะไร
โดยปัญหาที่พบคือ อาจจะมีบาง process ที่ทำงานไม่จบสักที [ ไม่มี signal ออกมาจาก process นั้น ]
ส่วน code ที่เป้นปัญหาคือ มัน
while( true ) {
try {
int process_status = process.waitFor();
break;
} catch( InterruptedException e ) {
}
}
ปัญหามันเกิดขึ้นมาเมื่อ process ไม่มี signal อะไรออกมา
ดังนั้น สามารถแก้ปัญหาได้โดยการใช้ Timer มาช่วย จะกำหนด timeout ได้ ดังนี้
Timer timer = new Timer();
timer.schedule(new InterruptProcess(Thread.currentThread()), 5000);
try {
exitStatus = proc.waitFor();
}
catch (InterruptedException e) {
proc.destroy();
}
finally {
timer.cancel();
}
และ Class InterruptProcess ซึ่งจะ extends มาจาก timerTask ดังนี้
class InterruptProcess
extends TimerTask {
Thread target = null;
InterruptProcess(Thread target) {
this.target = target;
}
/**
* run
*/
public void run() {
target.interrupt();
System.out.print("-|Run Interrupt|-");
}
}
จากตัวอย่าง ผมทำการกำหนด timeout = 5 วินาที ดังนั้นถ้า process มีเวลาทำงานมากที่สุดคือ 5 วินาทีเท่านั้น ส่วน process ที่ run เสร็จเร็วก็ไม่มีปัญหาอะไร
วันอาทิตย์ที่ 5 ตุลาคม พ.ศ. 2551
เริ่มต้นการพัฒนา Firefox Plug-in Application
หลังจากที่ทิ้งไปนานก็เลยกลับมาศึกษาการพัฒนา Firefox Plug-in Application กันหน่อย
โดยสามารถเริ่มการศึกษาได้ที่นี่
http://developer.mozilla.org/en/Building_an_Extension#Extending_the_Browser_with_XUL
และ slide ที่นี่อธิบายได้ดี
http://www.slideshare.net/skeevs/mozilla-firefox-extension-development/
ก่อนจะพัฒนานั้น ผมก็มานั่งศึกษาก่อนว่าโครงสร้างของ Firefox Plug-in เป็นอย่างไรบ้าง อนุญาตให้เราทำอะไรได้บ้าง
1. เทคดนโลยีที่ใช้ ประกอบไปด้วย
- JavaScript, AJAX, DOM, XML, CSS
- XUL (XML User Interface Language)
- xpcom ( Cross Platform Component Object Model )
2. Tools ที่ใช้ในการพัฒนา
- ผมเลือกใช้ Eclipse + XULBooster plug-in เหตุผลง่ายๆ คือ ฟรี และเป็น tools ที่ใกล้ตัวที่สุด
3. โครงสร้างของ Firefox Plug-in
นามสกุลของ file คือ xpi [ Mozilla/Firefox Browser Extension Archive ] สามารถเปิดด้วย winzip และ winrar ใน file xpi จะประกอบไปด้วย
- install.rdf [ ใช้สำหรับการ install plug-in จะอธิบายเกี่ยวกับ plug-in นั้น มี format เป็น xml ]
- chrome.manifest
- *.xul [ ส่วนแสดงผล ]
- *.js
- *.css
- *.xml
...
มีโครงสร้างของ files ดังรูป

4. ส่วนการแสดงผล จะสร้างด้วย XUL นั้นสามารถ custom ส่วนต่างๆ ของ Firefox หรือ Chrome UI ได้ดังนี้
- MenuBar
- Toolbox
- Toolbar
- Toolbar button
- Window
- Menu List
- Button
- Status Bar
5. มาทำความรู้จักกับ XUL กันหน่อย
- ย่อมาจาก XML User-interface Language
- โครงสร้างเป็น xml
- จะใช้เป็นส่วนการแสดงผล และการควบคุมการทำงานต่างๆ เช่น Layout, Input, Window
file xul นั้นสามารถ reference ได้ดังนี้
Chrome://my-plugin/content/test.xul
6. การใช้งาน JavaScript ใน xul นั้นสามารถ reference ได้ดังนี้
โดย JavaScript นั้นสามารถจัดการ event ต่างๆ ใน XUL UI , จัดการ DOM Tree และการติดต่อผ่าน xpcom ได้
7. Localization [ L10n ] สนับสนุนหลายๆ ภาษาได้ ซึ่งจะเป็นส่วน label โดยสามารถกำหนดไว้ใน/local/
เมื่อลองศึกษามาบ้าง ผมก็ลองสร้าง Firefox plug-in บ้างโดยความต้องการง่ายๆ คือ
1. ทำการดึงข้อมูลจาก feed ของ paw66.com จากที่นี่ http://www.paw66.com/sandbox/aggregator/rss
2. นำมาแสดงผลในส่วน Status Bar ของ Firefox
3. เมื่อ click ขวาที่ status bar แล้วจะมี menu ขึ้นมาให้เลือกคือ
- ดึงข้อมูลล่าสุด
- เกี่ยวกับ paw66
4. เมื่อ click ซ้ายจะ เปิด tab ใหม่เพื่อเปิด url ของ feed นั้นๆ
รูปแสดงการใช้งาน plugin ที่ผมลองทำดู

ผม upload plug-in ไว้ที่นี่ http://www.pai-pa.com/somkiat/ff/paw66-feed.xpi
นี่ก็คือการลองสร้าง Firefox plug-in application แบบง่ายๆ ครับ
โดยสามารถเริ่มการศึกษาได้ที่นี่
http://developer.mozilla.org/en/Building_an_Extension#Extending_the_Browser_with_XUL
และ slide ที่นี่อธิบายได้ดี
http://www.slideshare.net/skeevs/mozilla-firefox-extension-development/
ก่อนจะพัฒนานั้น ผมก็มานั่งศึกษาก่อนว่าโครงสร้างของ Firefox Plug-in เป็นอย่างไรบ้าง อนุญาตให้เราทำอะไรได้บ้าง
1. เทคดนโลยีที่ใช้ ประกอบไปด้วย
- JavaScript, AJAX, DOM, XML, CSS
- XUL (XML User Interface Language)
- xpcom ( Cross Platform Component Object Model )
2. Tools ที่ใช้ในการพัฒนา
- ผมเลือกใช้ Eclipse + XULBooster plug-in เหตุผลง่ายๆ คือ ฟรี และเป็น tools ที่ใกล้ตัวที่สุด
3. โครงสร้างของ Firefox Plug-in
นามสกุลของ file คือ xpi [ Mozilla/Firefox Browser Extension Archive ] สามารถเปิดด้วย winzip และ winrar ใน file xpi จะประกอบไปด้วย
- install.rdf [ ใช้สำหรับการ install plug-in จะอธิบายเกี่ยวกับ plug-in นั้น มี format เป็น xml ]
- chrome.manifest
- *.xul [ ส่วนแสดงผล ]
- *.js
- *.css
- *.xml
...
มีโครงสร้างของ files ดังรูป

4. ส่วนการแสดงผล จะสร้างด้วย XUL นั้นสามารถ custom ส่วนต่างๆ ของ Firefox หรือ Chrome UI ได้ดังนี้
- MenuBar
- Toolbox
- Toolbar
- Toolbar button
- Window
- Menu List
- Button
- Status Bar
5. มาทำความรู้จักกับ XUL กันหน่อย
- ย่อมาจาก XML User-interface Language
- โครงสร้างเป็น xml
- จะใช้เป็นส่วนการแสดงผล และการควบคุมการทำงานต่างๆ เช่น Layout, Input, Window
file xul นั้นสามารถ reference ได้ดังนี้
Chrome://my-plugin/content/test.xul
6. การใช้งาน JavaScript ใน xul นั้นสามารถ reference ได้ดังนี้
โดย JavaScript นั้นสามารถจัดการ event ต่างๆ ใน XUL UI , จัดการ DOM Tree และการติดต่อผ่าน xpcom ได้
7. Localization [ L10n ] สนับสนุนหลายๆ ภาษาได้ ซึ่งจะเป็นส่วน label โดยสามารถกำหนดไว้ใน
เมื่อลองศึกษามาบ้าง ผมก็ลองสร้าง Firefox plug-in บ้างโดยความต้องการง่ายๆ คือ
1. ทำการดึงข้อมูลจาก feed ของ paw66.com จากที่นี่ http://www.paw66.com/sandbox/aggregator/rss
2. นำมาแสดงผลในส่วน Status Bar ของ Firefox
3. เมื่อ click ขวาที่ status bar แล้วจะมี menu ขึ้นมาให้เลือกคือ
- ดึงข้อมูลล่าสุด
- เกี่ยวกับ paw66
4. เมื่อ click ซ้ายจะ เปิด tab ใหม่เพื่อเปิด url ของ feed นั้นๆ
รูปแสดงการใช้งาน plugin ที่ผมลองทำดู

ผม upload plug-in ไว้ที่นี่ http://www.pai-pa.com/somkiat/ff/paw66-feed.xpi
นี่ก็คือการลองสร้าง Firefox plug-in application แบบง่ายๆ ครับ
วันพุธที่ 1 ตุลาคม พ.ศ. 2551
เพิ่ม Search ของคุณลงใน FireFox กันไหม
ว่างๆ ไม่มีไรทำเลยหาเรื่องใส่ตัวสักหน่อย
แว่วๆๆ ว่า คนแถวๆ office จะไปจ้างใครไม่รู้ทำ FireFox Plugin เพื่อช่วยให้เข้าใช้งาน web app ง่ายมากขึ้น ได้ฟังแล้วมันฟุ้งซ่านขึ้นมาทันที ของมันไม่ได้ยากเลย ยังจะจ้างกันอีก ก็เลยลองเริ่มขั้นตอนแรกให้หายงงก่อน คือ เพิ่ม Search ของ Web ที่จะทำลงไปยัง FireFox ก่อนดีกว่า ซึ่งจะไปเพิ่มตรงนี้ ดังรูป

จะเพิ่มยังไง ??
1. ขั้นแรก ต้องบอกก่อนผมใช้ Firefox 3.0.3 นะครับ
2. ไปที่ C:\Program Files\Mozilla Firefox\searchplugins [ ติดตั้งที่ drive ไหนก็ไปตามนั้นครับ ส่วนผมติดตั้งไว้ที่ drive c: ]
3. ใน folder นี้จะมี xml หลายๆ ตัว ดังนั้นผมเอาบ้าง สร้าง my_search.xml เลย หน้าตาของ xml จะประมาณนี้ครับ
http://gist.github.com/14072
ส่วนที่สำคัญคือ
- Image จะเป็น data image ที่เป็น base64 ครับ ใครอยากลองแปลงก็ตาม url นี้ หรือแปลงเองก็ได้นะ ใช้ js ง่ายๆ
http://www.greywyvern.com/code/php/binary2base64
- Url ให้ใส่ end point url ของ search ที่คุณต้องการครับ และสามารถใส่ parameter ได้ด้วย
- {searchTerms} คือข้อมูลที่จะกรอกมาจากหน้าของ FireFox
4. ทำการ restart Firefox ครับ แล้วจะเห็นประมาณนี้

5. เลือกใช้กันหน่อย อิอิอิ แต่ไม่ซะใจ ตั้งให้เป็น Default Search ไปเลยครับ
- ไปที่ about:config
- แก้ไขค่าของ key browser.search.order.1 เป็น Custom Search
- restart Firefox แล้วจะได้แบบนี้

เป็นอันเสร็จสิ้นครับผม
Website References
http://www.greywyvern.com/code/php/binary2base64
http://labnol.blogspot.com/2006/09/learn-to-create-firefox-search-plugin.html
แว่วๆๆ ว่า คนแถวๆ office จะไปจ้างใครไม่รู้ทำ FireFox Plugin เพื่อช่วยให้เข้าใช้งาน web app ง่ายมากขึ้น ได้ฟังแล้วมันฟุ้งซ่านขึ้นมาทันที ของมันไม่ได้ยากเลย ยังจะจ้างกันอีก ก็เลยลองเริ่มขั้นตอนแรกให้หายงงก่อน คือ เพิ่ม Search ของ Web ที่จะทำลงไปยัง FireFox ก่อนดีกว่า ซึ่งจะไปเพิ่มตรงนี้ ดังรูป

จะเพิ่มยังไง ??
1. ขั้นแรก ต้องบอกก่อนผมใช้ Firefox 3.0.3 นะครับ
2. ไปที่ C:\Program Files\Mozilla Firefox\searchplugins [ ติดตั้งที่ drive ไหนก็ไปตามนั้นครับ ส่วนผมติดตั้งไว้ที่ drive c: ]
3. ใน folder นี้จะมี xml หลายๆ ตัว ดังนั้นผมเอาบ้าง สร้าง my_search.xml เลย หน้าตาของ xml จะประมาณนี้ครับ
http://gist.github.com/14072
ส่วนที่สำคัญคือ
- Image จะเป็น data image ที่เป็น base64 ครับ ใครอยากลองแปลงก็ตาม url นี้ หรือแปลงเองก็ได้นะ ใช้ js ง่ายๆ
http://www.greywyvern.com/code/php/binary2base64
- Url ให้ใส่ end point url ของ search ที่คุณต้องการครับ และสามารถใส่ parameter ได้ด้วย
- {searchTerms} คือข้อมูลที่จะกรอกมาจากหน้าของ FireFox
4. ทำการ restart Firefox ครับ แล้วจะเห็นประมาณนี้

5. เลือกใช้กันหน่อย อิอิอิ แต่ไม่ซะใจ ตั้งให้เป็น Default Search ไปเลยครับ
- ไปที่ about:config
- แก้ไขค่าของ key browser.search.order.1 เป็น Custom Search
- restart Firefox แล้วจะได้แบบนี้

เป็นอันเสร็จสิ้นครับผม
Website References
http://www.greywyvern.com/code/php/binary2base64
http://labnol.blogspot.com/2006/09/learn-to-create-firefox-search-plugin.html
วันอังคารที่ 30 กันยายน พ.ศ. 2551
วันศุกร์ที่ 26 กันยายน พ.ศ. 2551
ติดตั้ง RabbitMQ บน windows
หลังจากลองศึกษามาพอสมควรกับ Message Queue Server ตัวนี้ เริ่มจากลองดุที่ภาษา Erlang ซึ่งเป็นภาษาที่เหมาะสมกับระบบที่มี concurrent user จำนวนมาก แตก thread การทำงานได้เยอะๆ [ เขาว่ามาอย่างนั้น ] และมาเจอ MQ ที่ implement ด้วย Erlang คือ RabbitMQ มันยังถูกใช้ใน Twitter ซึ่งปัจจุบันใช้อยู่ประจำ จึงยิ่งทำให้เกิดความสนใจมากขึ้น ไม่พูดมากแล้ว เริ่มเลยดีกว่า ...
ขั้นตอนการติดตั้ง
1. download RabbitMQ Windows Bundle ที่ http://www.rabbitmq.com/download.html โดยใน zip file จะประกอบไปด้วย
- Erlang :: otp_win32_xxxx.exe
- RabbitMq Server :: rabbitmq-server-windows-xxxx.zip
- RabbitMq Client for Java :: rabbitmq-java-client-bin-xxxx.zip
2. ทำการติดตั้ง Erlang
3. extract rabbitmq-server-windows-xxxx.zip จะมี folder -> ebin, sbin, src, include
4. กำหนด env ตาม Link สรุปง่ายๆ เป็นดังนี้
- กำหนด ERLANG_HOME คือ folder ที่ทำการติดตั้ง erlang
- กำหนด RABBITMQ_BASE คือ folder ที่จะใช้เก็บข้อมูลต่างๆ ของ mq เช่น user account, message
5. ทดสอบ run rabbitmq server
- ไปที่ folder sbin ทำการ run
>>rabbitmq-server.bat
จะแสดงผลดังนี้ เป็นอันเสร็จสิ้น
มาดูการจัดการหลังการติดตั้ง สามารถเข้าไปดูได้ที่ี่ http://www.rabbitmq.com/admin-guide.html โดยหลักจะทำการ
- Manage Server : stop, start
- Manage User Account
- Manage VirtualHost
- Manage Realm
- Grant permmision to user
ค่า default ของ rabbitmq เป็นดังนี้
username = guest
password = guest
virtualhost = /
realm = /data
host = localhost/ip/127.0.0.1
ผมใช้ client เป็น java ตามสิ่งที่ load มาตั้งแต่แรก ซึ่ง API ที่ให้มาก้ใช้งานไม่ยาก สามารถอ่านจากเอกสารได้ที่ http://www.rabbitmq.com/api-guide.html
ตัวอย่าง code การติดต่อ จะประกอบไปด้วย
1. Create Channel
ConnectionParameters params = new ConnectionParameters();
params.setUsername("guest");
params.setPassword("guest");
params.setVirtualHost("/");
params.setRequestedHeartbeat(0);
ConnectionFactory factory = new ConnectionFactory(params);
Connection conn = factory.newConnection("localhost", 5672);
Channel channel = conn.createChannel();
int ticket = channel.accessRequest("/data");
channel.exchangeDeclare(ticket, "exchangeName", "direct", true);
channel.queueDeclare(ticket, "queueName");
channel.queueBind(ticket, "queueName", "exchangeName","routingKey");
2. Publish Message to broker [ RabbitMQ ]
byte[] messageBodyBytes = "Hello, world!".getBytes();
channel.basicPublish(ticket, "exchangeName", "routingKey", null, messageBodyBytes);
3. Retrieve Message from broker [ RabbitMQ ]
GetResponse response = channel.basicGet(ticket, "queueName", noAck);
if (response == null) {
// No message retrieved.
} else {
AMQP.BasicProperties props = response.getProps();
byte[] body = response.getBody();
long deliveryTag = response.getEnvelope().getDeliveryTag();
channel.basicAck(deliveryTag, false);
System.out.println(new String(body));
}
4. Close channel
channel.close(AMQP.REPLY_SUCCESS, "Goodbye");
conn.close(AMQP.REPLY_SUCCESS);
เท่านี้ก็สามารถเริ่มใช้งาน RabbitMQ ในเบื้องต้นได้แล้วครับ
RabbitMQ is an implementation of AMQP, the emerging standard for high performance enterprise messaging
ขั้นตอนการติดตั้ง
1. download RabbitMQ Windows Bundle ที่ http://www.rabbitmq.com/download.html โดยใน zip file จะประกอบไปด้วย
- Erlang :: otp_win32_xxxx.exe
- RabbitMq Server :: rabbitmq-server-windows-xxxx.zip
- RabbitMq Client for Java :: rabbitmq-java-client-bin-xxxx.zip
2. ทำการติดตั้ง Erlang
3. extract rabbitmq-server-windows-xxxx.zip จะมี folder -> ebin, sbin, src, include
4. กำหนด env ตาม Link สรุปง่ายๆ เป็นดังนี้
- กำหนด ERLANG_HOME คือ folder ที่ทำการติดตั้ง erlang
- กำหนด RABBITMQ_BASE คือ folder ที่จะใช้เก็บข้อมูลต่างๆ ของ mq เช่น user account, message
5. ทดสอบ run rabbitmq server
- ไปที่ folder sbin ทำการ run
>>rabbitmq-server.bat
จะแสดงผลดังนี้ เป็นอันเสร็จสิ้น
...
starting database ...done
starting core processes ...done
starting recovery ...done
starting persister ...done
starting builtin applications ...done
starting TCP listeners ...done
ิbroke running
มาดูการจัดการหลังการติดตั้ง สามารถเข้าไปดูได้ที่ี่ http://www.rabbitmq.com/admin-guide.html โดยหลักจะทำการ
- Manage Server : stop, start
- Manage User Account
- Manage VirtualHost
- Manage Realm
- Grant permmision to user
ค่า default ของ rabbitmq เป็นดังนี้
username = guest
password = guest
virtualhost = /
realm = /data
host = localhost/ip/127.0.0.1
ผมใช้ client เป็น java ตามสิ่งที่ load มาตั้งแต่แรก ซึ่ง API ที่ให้มาก้ใช้งานไม่ยาก สามารถอ่านจากเอกสารได้ที่ http://www.rabbitmq.com/api-guide.html
ตัวอย่าง code การติดต่อ จะประกอบไปด้วย
1. Create Channel
ConnectionParameters params = new ConnectionParameters();
params.setUsername("guest");
params.setPassword("guest");
params.setVirtualHost("/");
params.setRequestedHeartbeat(0);
ConnectionFactory factory = new ConnectionFactory(params);
Connection conn = factory.newConnection("localhost", 5672);
Channel channel = conn.createChannel();
int ticket = channel.accessRequest("/data");
channel.exchangeDeclare(ticket, "exchangeName", "direct", true);
channel.queueDeclare(ticket, "queueName");
channel.queueBind(ticket, "queueName", "exchangeName","routingKey");
2. Publish Message to broker [ RabbitMQ ]
byte[] messageBodyBytes = "Hello, world!".getBytes();
channel.basicPublish(ticket, "exchangeName", "routingKey", null, messageBodyBytes);
3. Retrieve Message from broker [ RabbitMQ ]
GetResponse response = channel.basicGet(ticket, "queueName", noAck);
if (response == null) {
// No message retrieved.
} else {
AMQP.BasicProperties props = response.getProps();
byte[] body = response.getBody();
long deliveryTag = response.getEnvelope().getDeliveryTag();
channel.basicAck(deliveryTag, false);
System.out.println(new String(body));
}
4. Close channel
channel.close(AMQP.REPLY_SUCCESS, "Goodbye");
conn.close(AMQP.REPLY_SUCCESS);
เท่านี้ก็สามารถเริ่มใช้งาน RabbitMQ ในเบื้องต้นได้แล้วครับ
วันพฤหัสบดีที่ 25 กันยายน พ.ศ. 2551
Process ที่เป็นอยู่
while (true) {
identify_and_fix_bottlenecks();
drink();
sleep();
notice_new_bottleneck();
}
This loop runs many times a day.
identify_and_fix_bottlenecks();
drink();
sleep();
notice_new_bottleneck();
}
This loop runs many times a day.
BDD with easyb
หลายสัปดาห์มาแล้วได้เรียนรู้เกี่ยวกับ BDD :: Behavior Driven Development ซึ่งฟังดูไปจะคล้ายๆ กับ TDD :: Test-Driven Developement แต่แตกต่างตรงที่
TDD คือ เขียน test -> coding -> Run Test -> Refactoring
แต่ BDD นั้นจะเป็นการทดสอบระบบงานให้เป็นไปตาม specification/requirement ไม่ได้ทำการทดสอบในระดับ unit test แต่การพัฒนานั้นสามารถใช้คู่กันได้อย่างปกติ [ BDD ไม่ได้มาทดแทน แต่มาช่วยทำให้ทั้งฝ่าย business และ developer เข้าใจกันมากขึ้น ]
TDD -> test
BDD -> spec
ฺBDD framework มีหลายตัวที่น่าสนใจเช่น
RSpec :: http://rspec.info/
JBehave :: http://jbehave.org/
easyb :: http://easyb.org/
JDave :: http://www.jdave.org/
framework ที่ผมสนใจคือ easyb เนื่องจากพัฒนาเพื่อใช้งานบน java platform และที่สำคัญสามารถใช้งานกับ groovy และ grails ได้ครับ
มาดูการใช้งานคร่าวๆ
ก่อนอื่นต้องเข้าใจ story และ specification
โดย story จะประกอบด้วย scenario ซึ่งใน scenario แต่ละตัวจะมี
- Given
- When
- Then
ตัวอย่างของ scenario
scenario "check username/password", {
given "user account already exists", {
}
when "user logins", {
}
then "should return a valid account", {
}
}
ใน { ... } นั้นสามารถแทรก code การทำงานในแต่ละส่วนเข้าไปเพื่อทดสอบได้
มาดูการ run easyb กัน
1. download easyb จาก http://easyb.org/download.html
2. extract และ run ตามนี้
java org.disco.easyb.BehaviorRunner MyStory.groovy
-> MyStory.groovy คือ story ที่เก็บ scenario ด้านบน โดยชื่อ file ต้องมี suffix เป็น Story
3. สามารถ generate report ได้ 2 แบบคือ
3.1 Text file
>>java org.disco.easyb.BehaviorRunner MyStory.groovy -txtstory mystory.txt
3.2 Xml file
>>java org.disco.easyb.BehaviorRunner MyStory.groovy -xmleasyb mystory.xml
ใน easyb version 1.0 จะสามารถ generate เป็น html ได้ครับ ต้องตั้งหน้าตั้งตารอคอยครับ
ถ้าต้องการใช้ใน grails สามารถใช้ plug-in มาช่วยได้ที่นี่ครับ EasyBTest
ใช้งานก็ง่ายดังนี้ครับ
การติดตั้ง
$grails install-plugin grails-easybtest-latest.zip
ทดสอบ run
$grails easyb-test
ส่วน BDD Framework ภาษาไทยก็มีนะครับ คือ TSpec
นี่ก็คือจุดเริ่มต้นในการศึกษาและใช้งาน BDD ครับ
Web Reference
http://www.grails66.com
http://easyb.org/
http://java.dzone.com/articles/is-easyb-easy
http://www.javaworld.com/javaworld/jw-09-2008/jw-09-easyb.html
TDD คือ เขียน test -> coding -> Run Test -> Refactoring
แต่ BDD นั้นจะเป็นการทดสอบระบบงานให้เป็นไปตาม specification/requirement ไม่ได้ทำการทดสอบในระดับ unit test แต่การพัฒนานั้นสามารถใช้คู่กันได้อย่างปกติ [ BDD ไม่ได้มาทดแทน แต่มาช่วยทำให้ทั้งฝ่าย business และ developer เข้าใจกันมากขึ้น ]
TDD -> test
BDD -> spec
ฺBDD framework มีหลายตัวที่น่าสนใจเช่น
RSpec :: http://rspec.info/
JBehave :: http://jbehave.org/
easyb :: http://easyb.org/
JDave :: http://www.jdave.org/
framework ที่ผมสนใจคือ easyb เนื่องจากพัฒนาเพื่อใช้งานบน java platform และที่สำคัญสามารถใช้งานกับ groovy และ grails ได้ครับ
มาดูการใช้งานคร่าวๆ
ก่อนอื่นต้องเข้าใจ story และ specification
โดย story จะประกอบด้วย scenario ซึ่งใน scenario แต่ละตัวจะมี
- Given
- When
- Then
ตัวอย่างของ scenario
scenario "check username/password", {
given "user account already exists", {
}
when "user logins", {
}
then "should return a valid account", {
}
}
ใน { ... } นั้นสามารถแทรก code การทำงานในแต่ละส่วนเข้าไปเพื่อทดสอบได้
มาดูการ run easyb กัน
1. download easyb จาก http://easyb.org/download.html
2. extract และ run ตามนี้
java org.disco.easyb.BehaviorRunner MyStory.groovy
-> MyStory.groovy คือ story ที่เก็บ scenario ด้านบน โดยชื่อ file ต้องมี suffix เป็น Story
3. สามารถ generate report ได้ 2 แบบคือ
3.1 Text file
>>java org.disco.easyb.BehaviorRunner MyStory.groovy -txtstory mystory.txt
3.2 Xml file
>>java org.disco.easyb.BehaviorRunner MyStory.groovy -xmleasyb mystory.xml
ใน easyb version 1.0 จะสามารถ generate เป็น html ได้ครับ ต้องตั้งหน้าตั้งตารอคอยครับ
ถ้าต้องการใช้ใน grails สามารถใช้ plug-in มาช่วยได้ที่นี่ครับ EasyBTest
ใช้งานก็ง่ายดังนี้ครับ
การติดตั้ง
$grails install-plugin grails-easybtest-latest.zip
ทดสอบ run
$grails easyb-test
ส่วน BDD Framework ภาษาไทยก็มีนะครับ คือ TSpec
นี่ก็คือจุดเริ่มต้นในการศึกษาและใช้งาน BDD ครับ
Web Reference
http://www.grails66.com
http://easyb.org/
http://java.dzone.com/articles/is-easyb-easy
http://www.javaworld.com/javaworld/jw-09-2008/jw-09-easyb.html
สมัครสมาชิก:
บทความ (Atom)