TDD Boot Camp 横æµã§åãã¦Groovy触ã£ãããã£ããããï¾ï¾ï¾wwww #tddbc
1æ¥ãã£ã¦ãã¾ãã¾ãããã11/06ã«TDD Boot Camp 横æµã«åå ãã¦ãã¾ããã詳ããè¨äºã¯ãid:absj31ããã®è¨äºãç´ æ´ãããã¾ã¨ã¾ã£ã¦ããã®ã§ãã覧ãã ããã¾ãã
TDD Boot Camp 横浜に参加してきた #tddbc - Diary of absj31
TDD BCã®ææ³ã¨ãGroovyãåãã¦è§¦ã£ãææ³ã§ã
Groovyãã¢ã«ç«åè£ããçç±
- ãåéãããã¦ããããã§ãç«åè£ããã°ããã®å ´ã§ãã¢æç«
- Groovyã触ã£ããã¨ããªãã¦ã大ä¸å¤«ã¨ããåæ
- ããã°ã©ãã³ã°è¨èªå¥½ãã¨ãã¦ã¯ãGroovy触ã£ã¦ã¿ããã£ã
- æ®éãªãã師å ã¯ç´ã ã«ãè¨èªã®ãã©ã¼ã¹ãæããããªã
- éå¶ã®æ¹ã¨ãTDDãã£ãã»ãã身ã«ã¤ãããï¼
ãããããããªçç±ã ã£ãã¨æãã¾ããæç®ã¨èå³ãäºåäºåã¨ãã£ãã¨ããã§ãããããéå¶ã®æ¹ããGroovyæ¬ãæã£ã¦ãã¦ããã¦ã ãã©ãã©ã¨è¦ã第ä¸å°è±¡ã¯ããJavaã¨rubyã®éã®åãâ¦ããããã§ããã®Groovyã¨ããè¨èªã®ç¬ç¹ã®ã³ã³ã»ããã¯ããããªãã£ãã§ãã
Javaã¨å¯ãæ·»ãè¨èªã¨ãã¦ã®Groovy
Groovyã®ä¸ã¤ã®å¤§ããªç¹å¾´ã¯ãGroovyä¸ããJavaã®ã³ã¼ããããèªç¶ã«å¼ã³åºãããã¨ã¨LLãªãã§ã¯ã®ãæè»ãªæ§æãä½ãåºãããã¨ã§ããããã¯ãTDDã®ã¡ã¤ã³ã§ãããã¹ãã³ã¼ãã®å®è£ ã§åãæãååçºæ®ãã¦ããã¾ããTDDã§ãåºããããé¡ã¯ã
- å ¥åã¨ãã¦ãé¸æã®æå¸æ°ã¨ææ°ã¨å®ææ°ãåãåããé¸æã®æçãè¨ç®ã§ãããã¨ã
- æçã¯å°æ°ç¬¬4ä½ã§åæ¨äºå ¥ãããã¨ã
- æå¸æ°ã0ã®å ´åã¯ãæçãè¨ç®ããªããã¨ã(JavaãªãnullãRubyãªãnilç¸å½)
- æå¸æ°ã0ã§ãªããææ°ã0ã®å ´åã¯ã0.000ãã¨è¨ç®ãããã¨ã
Groovyããã«ã¼ã®@nobeansããã¨ãã¢ããããã¦é ãã¾ãããå
¨ã½ã¼ã¹ã³ã¼ãã¯@nobeansãããgitã«ä¸ãã¦ãã ãã£ã¦ãã¾ãã
https://github.com/nobeans/tddbc-yokohama-201111/tree/master/src
ãªã³ã¯ããã³ã¼ãå°ãå¼ç¨ãã¦ãã¾ãã¾ããâ¦ããããªããï¼ï¼ï¼TDDãªã®ã§ããã¹ãã³ã¼ãã®ä¸é¨ã§ããSpockã使ãã¾ããã
import spock.lang.* class PlayerSpec extends Specification { def "æå¸æ°ã¨ææ°ã¨å®ææ°ãåãåããæçãè¨ç®ãã"() { setup: def player = new Player(box:box, atBat:atBat, hit:hit) expect: player.getBattingAverage() == battingAverage where: box | atBat | hit | battingAverage 3 | 2 | 1 | 0.5 4 | 4 | 1 | 0.25 } def "æå¸æ°ã¨ææ°ã¨å®ææ°ãåãåããå°æ°ç¬¬åä½ã§åæ¨äºå ¥ãã (ç¡éå°æ°ã忍)"() { setup: def player = new Player(box:3, atBat:3, hit:1) expect: player.getBattingAverage() == 0.333 } def "æå¸æ°ã¨ææ°ã¨å®ææ°ãåãåããå°æ°ç¬¬åä½ã§åæ¨äºå ¥ãã (äºå ¥)"() { setup: def player = new Player(box:515, atBat:455, hit:135) expect: player.getBattingAverage() == 0.297 } def "æå¸æ°ã0ã®å ´åã¯ãæçãè¨ç®ããã«nullãè¿ã"() { setup: def player = new Player(box:0, atBat:455, hit:135) expect: player.getBattingAverage() == null } def "ææ°ã0ã®å ´åã¯ã0.000ãè¿ã"() { setup: def player = new Player(box:3, atBat:0, hit:0) expect: player.getBattingAverage().getClass() == BigDecimal.class player.getBattingAverage().scale() == 3 player.getBattingAverage() == 0.000 } }
ç¶ãã¦ãGroovyã§Playerã¯ã©ã¹ãå®è£ ãã¾ããã
import java.math.* class Player { int box int atBat int hit def getBattingAverage() { if (this.box == 0) { return null } if (this.atBat == 0) { return 0.000 } (hit as BigDecimal).divide(atBat, 3, RoundingMode.HALF_UP) } }
å¯èªæ§ã¨ã¡ã³ããã³ã¹ã®ãããã
ã½ã¼ã¹ã³ã¼ããæ¸ãã¦ããã¨ãã«ãããï½ï½ï½ãï½ï½ï½ã¯ï½ï½ï½ãã¨ãã¤ãã¤ã§ããããªã«ããããã¹ãã³ã¼ãããµã¤ãããâ¦
ãã¹ãã³ã¼ãã®ã¡ã³ããã³ã¹æ§ã¯ããã¾ãèªãããªãã®ã§ããããã¹ãã³ã¼ãããã¡ã³ããã³ã¹ããã¦ããªãã¨ãTDDã®ããã»ã¹ã殺ãã¦ãã¾ãã¨åã¯èãã¦ãã¾ããã§ããTDDã®å¤§ããªéå£ã«ããªã£ã¦ãããããªããã¨æããããããã¹ã³ã¼ãã£ã¦TDDåå¿è
ã«ã¨ã£ã¦ã¯ãã¡ã³ããã³ã¹ãã«ãããã§ããå®è£
ã®ã¹ãã¼ãã¯ä½æã§ç¢ºå®ã«è½ã¡ãç¦ããããã®ã§ããã¹ãã³ã¼ãã«ãããæéã¯ãã§ããã ãçããããã¨æã£ã¦ãã¾ãã®ãï¼ç§ãå«ãã¦)åå¿è
ã®æ§ã§ããããçµæãã¡ã³ããããªããã¹ããã§ããããã¨ã
ã²ã¨ã¤ã®ä»æ§ã«å¯¾ãã¦ãä¸ã¤ã®ãã¹ãã±ã¼ã¹ã§ããã®ãã©ãã»ã©ç´ æ´ããããã¨ãâ¦Groovyã¯ãJavaã§ã®TDDã確å®ã«Drivenãã¦ããã¾ããGroovyãåãã¦è§¦ãã¾ããããGroovyã®ãã¯ã¼ãç¥ãã«ã¯ååã§ãããï¼ããã¯ãGroovyã®ãã¯ã¼ã®ä¸é¢ã§ãããªãã§ããã)
id:t-wadaããã®ã³ã¼ãã¬ãã¥ã¼ã®ä¸ã§åèªã¨ãã¦åºã¦ããã4Phaseãã¹ããããããGroovyã§ããã¨ãsetup,expect,whereãããâ¦ãã¨ããæãã§ããï¼é²ç ã¼ããï¼ãUnitãã¹ãã®ãã¹ããã©ã¯ãã£ã¹ãå°ã§è¡ãè¨èªã«æãã¾ããããã¦ãã²ã¨ã¤ã®ä»æ§ã«å¯¾ãã¦ãããããªæ°ãçªã£è¾¼ããã¹ããç°¡åã«ãããã®ã§ãã¡ã³ããã³ã¹æ§ãå¯èªæ§ã¨ãã«â
Groovyã®è¯ããJavaã触ã£ã¦ãã人ã«ä¼ãããªã
- ä»ããå°å ¥ã§ãã¾ããjavaã®è¨èªã®ä¸é¨ã®ããã«ãåãã¾ãã
- javaã®è¨èªã®ç¹å¾´ãåãç¶ãã§ããã®ã§ãããã¸ã§ã¯ãå ¨ä½ã¨ãã¦ã®ã³ã¼ãã®çµ±ä¸æã¯å´©ããªã
- ãjavaã®ã³ã¼ããã¡ã³ããã³ã¹ãããç¨éã«é常ã«åãã¦ããããã¹ãã³ã¼ãã«ãã²
- 仿ã®è¨èªãã¡ããã¡ãã触ã£ã¦ãããã¯ã«ééï¼ä»£è¡¨ä½ï¼ç§ï¼ã§ãå¦ç¿ã³ã¹ãã¯é常ã«ä½ã
- Groovy楽ãã
ã¡ããã¡ãã触ã£ã¦ããç¨åº¦ããè³ç£ã¨ãã¦çããããã¨ããï½ï½ï½æãããåï½ï½ï½ãä»è¨èªã¨å¯ãæ·»ããè¨èªã¨ããã®ãåã«ã¯ãã¨ã¦ãæ°é®®ã§ããã
éå¶ã«ã¤ãã¦
æ½é¸ã«ã¤ãã¦
éå¶ã®æ¹ã ãæ°ã«ãªãã£ã¦ããã£ãããã¾ããã®ã§â¦ç§å人çã«ã¯ãé常ã«å©ããã¾ãããä»äºã䏿®µè½ããã¨ãã«ç³ãè¾¼ã¿ãã¼ã¸ããã§ã«ãã£ã±ãã«ãªã£ã¦ãã¾ã£ã¦ããã®ã§ãä»ååå ã§ããã¯ãæ½é¸ã®ãããã§ãã
å¤è¨èªã§ã®TDD
ã¨ã¦ãæåãã¦ããã¨æãã¾ããä»ã®è¨èªã®ãã¹ãã³ã¼ããè¦æ¯ã¹ããã¨ãã§ããã®ã¯ãã¨ã¦ãé¢ç½ãã§ãã
ãã¢ããã°ã©ãã³ã°
ç´ æ´ãããä½é¨ã§ããããæ¹åããã¨ããã°ä½¿ãã¨ãã£ã¿ã¯ä»å¾ã注æããªãã¨ããã¾ããã
æ°ã¥ãã¨ãããçåã«æã£ãã¨ãã
èªåãæã£ã¦ããã®ããããã¿ã¹ã¯ã®ç²åº¦ããã£ã¨ç´°ãã
id:t-wadaãããTDDã説æãã¦ãã ããæ©ä¼ããã£ãã®ã§ãããçµã¿è¾¼ã¿é¢æ°ã§ã仿§ã¸ã®çè§£ãæªããã¨ããã¯ããã¹ãã³ã¼ãã¨ãã¦æ®ãã¦ãã¾ããã@nobeansããã¨ãã¢ããããã¦ããã ããæããå°ãã®å¤æ´ã§ããã¹ããèµ°ããã¦ãã¾ãããåãå®è£ ããããã¨ãã¦æ¢ããããæ©ä¼ãçµæ§ããã¾ãããTDDãªãã§ã¯ã®ã¿ã¹ã¯ç²åº¦ãããã®ã ããã¨æãã¾ãã
TDDã«ããæ £ãã¦ããæ¹ã¯ãèæ ®æ¼ãã«å¼·ãæ°ããã
ããã¯ã@nobeansããã¨ãã¢ããããã¦ããã ããã¨ãã«æãããã¨ã§ããããã¹ããæ¸ããã¨ãã«ãããããæã¯ãã©ããªãï¼ãã¨ããåãããããã£ããããã¾ãããèªåã§ã¯ãå ¨ãèæ ®ãã¦ããªãã£ããã¨ããããããã£ã¦ããã©ããããããããããµãã«æ°ã¥ããã ï¼ãã¨æããã¨ãããã¾ãããæ £ããªãã ãããâ¦ããæããããã®ã§ã :)
æèçã«REDãæèçã«GREEN
ããã°ã©ãã³ã°ãæ¸ãã¦ãã人éãããããã¯ã赤ãªã¯ãâ¦ããã¯ãç·ã ããï¼ãã¨ããããã«ããã°ã©ãã³ã°ã¨ããè¡çºãå¶å¾¡ã§ããããªãããããTDDã®å¤§ããªç¹å¾´ã ã¨æãã¾ããã
æå¾ã«
主å¬ãã¦ä¸ãã£ã @setoazusa ãããç´ æ´ãããåºèª¿è¬æ¼ããã¦ä¸ãã£ã id:t-wada ãããã¹ã¿ããã®çãããããã¦åå è ã®çãããç´ æ´ãããæéããããã¨ããããã¾ããããããæ¥½ããã£ãã§ãã
Groovyãåèãã ãã£ã@nobeansããã@pocketberserkerãããããã¨ããããã¾ãããGroovyãããããï¼Groovyï¼