ãªãªãžãã«ïŒ
www.infoq.com/articles/atdd-from-the-trenchesé«åºŠãªATDD
åå¿è
åãã®åãå
¥ããã¹ãã«ããéçº

ãã®ç¶æ³ã«ãã£ãããšãããå ŽåïŒ

次ã«ããã®èšäºã¯ãã¬ã¬ã·ãŒã³ãŒãã䜿çšããæ¢åã®ãããžã§ã¯ãã§åãå
¥ããã¹ãïŒåãå
¥ããã¹ãé§ååéçºïŒãä»ããŠéçºãéå§ããæ¹æ³ã®å
·äœäŸã§ãã ãã
ã¯æè¡çè² åµã®åé¡ã
解決ãã 1ã€ã®æ¹æ³ã説æããŸãã
ããã¯å®éã®ãããžã§ã¯ãã®äŸã§ããããã¹ãŠã®æ¬ é¥ãšæ¬ ç¹ããããŸãããæ¬ã®æŽç·ŽãããæŒç¿ã§ã¯ãããŸããã ããã§ããã¬ãŒåžœãççšããŠãã ããã 掟æãªãµãŒãããŒãã£ã©ã€ãã©ãªïŒéåžžã¯æªçšãããããšãªãïŒãªãã§ãJavaãšJUnitã䜿çšããŸãã
èŠåïŒãããå¯äžã®æ£ããæ¹æ³ã§ãããšäž»åŒµããŠããã®ã§ã¯ãªããä»ã«ãå€ãã®ATDDãã¹ã¿ã€ã«ãããããŸãã ãŸãããã®èšäºã§ã¯ãæ°ããé©æ°çã§å®çžŸã®ããã¢ãããŒããçµéšã«ã€ããŠã¯ããŸã觊ããŠããããããã§ã¯çŽæ¥èª¬æããŸãã
ããããã£ãããš
æ°æ¥åã
webwhiteboard.comã®ãã¹ã¯ãŒãä¿è·ãéå§ã
ãŸãã ïŒç§ã®ãããžã§ã¯ãã¯è¶£å³ã§ãïŒã ãŠãŒã¶ãŒã¯é·ãéãä»®æ³ãã¯ã€ãããŒãããã¹ã¯ãŒãã§ä¿è·ããæ©èœãè¿œå ããããšãæ±ããŠããã®ã§ãä»ãããããè¡ããšãã§ãã
èšèã§ã¯ç°¡åã«èãããŸãããå®éã«ã¯ãèšèšã«ããªãã®æ°ã®å€æŽãå ããå¿
èŠããããŸãã ãããŸã§ãwebwhiteboards.comã¯ãŠãŒã¶ãŒåããã¹ã¯ãŒããªãã§å¿åãŠãŒã¶ãŒã«ãã£ãŠäœ¿çšãããŠãããšæ³å®ãããŠããŸããã ããŒãããã¹ã¯ãŒãã§ä¿è·ã§ããã®ã¯èª°ã§ããïŒ èª°ã圌女ã«ã¢ã¯ã»ã¹ã§ããŸããïŒ ãã¹ã¯ãŒããå¿ãããã©ããªããŸããïŒ ã·ã³ãã«ã§ãããªãããããªãä¿¡é Œã§ããæ¹æ³ã§ãããå®è£
ããæ¹æ³ã¯ïŒ
webwhiteboardã³ãŒãã¯ãåäœãã¹ããšçµ±åãã¹ãã§ååã«ã«ããŒãããŠããŸãã
ãã ããåãå
¥ããã¹ããã€ãŸããšã³ããŠãŒã¶ãŒã®èŠ³ç¹ãããã¹ãŠã®ã¬ã€ã€ãŒãééãããã¹ãã¯å®å
šã«ååšããŸããã
ãã¶ã€ã³ãæ€èšãã
webwhiteboardã®èšèšã®äž»ãªç®æšã¯ã·ã³ãã«ã§ãããã¹ã¯ãŒããå
¥åããå¿
èŠæ§ãæå°éã«æããã¢ã«ãŠã³ããäœæããã®ã§ã¯ãªããä»ã®åºæ¿ç©ãæžããããšã§ãã ããã§ããã¹ã¯ãŒãã§ä¿è·ãããããŒãã«2ã€ã®å¶éãèšå®ããŸããã
- å¿åãŠãŒã¶ãŒã¯ãããŒãããã¹ã¯ãŒãã§ä¿è·ã§ããŸããã ãããã圌ã¯ãã§ã«ä¿è·ãããããŒããéãããšãã§ããŸãã 圌ã¯ã·ã¹ãã ã«å
¥ãå¿
èŠã¯ãªããä¿è·ãããããŒãã®ãã¹ã¯ãŒããå
¥åããã ãã§ãã
- ãã°ã€ã³ãšãã¹ã¯ãŒãã¯ãå
ã
Googleãæå³ããå€éšOpenId / Oauthã³ã³ããŒãã³ãã«ãã£ãŠç®¡çãããŸãã ãããã£ãŠããŠãŒã¶ãŒã¯å¥ã®ã¢ã«ãŠã³ããäœæããå¿
èŠã¯ãããŸããã
å®è£
ã¢ãããŒã
å€ãã®äžç¢ºå®æ§ããããŸãã å®è£
æ¹æ³ã¯èšããŸã§ããªãããããã©ã®ããã«æ©èœãããã¯ç¥ããŸããã§ããã ããã«ç§ãããããšæ±ºãããã®ããããŸãïŒATDDèªäœïŒïŒ
- ã¹ããã1.ææ¡ãããããã»ã¹ãææžåããŸãã
- ã¹ããã2.ã¹ã¿ãŒãã¢ããåãå
¥ããã¹ãã«å€æããŸã
- ã¹ããã3.åãå
¥ããã¹ããå®è¡ããèœã¡ãããšã確èªããŸã
- ã¹ããã4.åãå
¥ããã¹ãã®ä¿®åŸ©
- ã¹ããã5.ã³ãŒãããããã«ãã
ãããã®æé ã¯äœåºŠãç¹°ãè¿ãããŸãã åã¹ãããã§ãåã®ã¹ãããã«æ»ãå¿
èŠããããŸãïŒããã¯ããªãé »ç¹ã«è¡ããŸããïŒã
ã¹ããã1ïŒææ¡ãããããã»ã¹ãææžåãã
æ©èœãæºåãã§ããŠãããšæ³åããŠãã ããã ãŸãã§å€©äœ¿ã倩ããéããŠããŠãç§ãå¯ãŠããéã«ããããããšããããã®ããã«ã æ¬åœã§ããã«ã¯äœãã«ãè¯ãé³ïŒ äœæ¥ãæ¢ã«è¡ãããããšã確èªããã«ã¯ã©ãããã°ããã§ããïŒ æåã«ç¢ºèªããã·ããªãªã¯ã©ãã§ããïŒ ãããå
¥æããŸãããïŒ
- æ°ããããŒããäœæããŠããŸã
- ãã¹ã¯ãŒããèšå®ããŸã
- ãžã§ãŒãããŒããéãããšããŠããŸããã·ã¹ãã ã¯ãã¹ã¯ãŒããèŠæ±ããŸã
- ãžã§ãŒãééã£ããã¹ã¯ãŒããå
¥åããã¢ã¯ã»ã¹ãæåŠãããŸãã
- ãžã§ãŒã¯åè©Šè¡ããæ£ãããã¹ã¯ãŒããå
¥åããŠã¢ã¯ã»ã¹ããŸãã ïŒããžã§ãŒãã¯ç§ã ãã§ãããå¥ã®ãã©ãŠã¶ããã®ãã®ã§ããããšãç解ããå¿
èŠããããŸãïŒã
ãã®çããã¹ãã¹ã¯ãªãããæžããåŸãèæ
®ããå¿
èŠããã代æ¿ã·ããªãªãä»ã«ãããããããããšã«æ°ä»ããŸããã ãããããããäž»ãªã·ããªãªã§ãããæ©èœãããããšãã§ããã°ã倧ããªäžæ©ãèžã¿åºãããšã«ãªããŸãã
ã¹ããã2ïŒèµ·ååãå
¥ããã¹ãã«å€æãã
ããã»ã©åçŽã§ã¯ãããŸããã ä»ã®åãå
¥ããã¹ãã¯ãããŸããã®ã§ãã©ãããå§ããŸããïŒ æ°ããæ©èœã¯ãèªèšŒãæ
åœããå€éšã³ã³ããŒãã³ããšå¯Ÿè©±ããŸãïŒæåã¯Janrainã䜿çšããããšã«ããŸããïŒã ãŸããããŒã¿ããŒã¹ãšããããã¢ãããã€ã¢ãã°ãããŒã¯ã³ãããŒãžãã©ã³ãžã·ã§ã³ãªã©ãå«ãè€éãªWebã¹ã¿ãããå€æ°ååšããŸãã ãã
åŸæ»ãããæã§ãã ãåãå
¥ããã¹ãã®æžãæ¹ãã®åé¡ã解決ããåã«ããæ¢åã®ã³ãŒãã§åãå
¥ããã¹ããæžãæ¹æ³ãã®ããåçŽãªåé¡ã解決ããå¿
èŠããããŸããïŒ
ãã®è³ªåã«çããããã«ãæåã«ã·ã¹ãã ã«æ¢ã«ååšããã·ããªãªã®ãæãåçŽãªã·ããªãªãã®ãã¹ããäœæããŸãã
ã¹ããã2.1æãç°¡åãªèªååãå
¥ããã¹ããäœæãã
ç§ãå§ããã¹ã¯ãªããã¯æ¬¡ã®ãšããã§ãã
- ååšããªãããŒããéããŠã¿ãŠãã ãã
- 圌女ãèŠããªãããšã確èªããŠãã ãã
ãã®ãããªãã¹ããæžãæ¹æ³ã¯ïŒ ã©ã®ãã¬ãŒã ã¯ãŒã¯ã§ïŒ ã©ããªããŒã«ïŒ ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠãã¹ãããå¿
èŠããããŸããïŒ ãã¹ãã«ã¯ã©ã€ã¢ã³ãã³ãŒããå«ãããããµãŒãã¹ãçŽæ¥åŒã³åºãå¿
èŠããããŸããïŒ
ããããã®è³ªåã ããªãã¯ïŒãããã«çããªãã§ãã ããïŒ ãã¹ãŠããã§ã«éæ³ã®ããã«è¡ãããŠããããšããµããããŠãæ¬äŒŒã³ãŒãã®ãã¹ããæžãã ãã§ãã äŸïŒ
public class AcceptanceTest { @Test public void openWhiteboardThatDoesntExist() {
ç§ã¯ãããèµ·åããåæ ŒããŸããïŒ ãã£ãïŒ ãããšãã§ãåŸ
ã£ãŠãã ãããããã¯ééã£ãŠããŸãïŒ TDDäžè§åœ¢ã®æåã®ã¹ãããïŒãèµ€-ç·-ãªãã¡ã¯ã¿ãªã³ã°ãïŒã¯èµ€ã§ãã ãã®ããããã®èŠä»¶ããŸã å®è£
ãããŠããªãããšã蚌æããããã«ããŸããã¹ãããã©ãŒã«ãããå¿
èŠããããŸãã

ãããããå®éã®ã³ãŒããæžãããšããå§ããŸãããã ããã§ããæ¬äŒŒã³ãŒãã¯æ£ããæ¹åãžã®äžæ©ãèžã¿åºãã®ã«åœ¹ç«ã¡ãŸããã
ã¹ããã2.2æãç°¡åãªèªååãå
¥ããã¹ããèµ€ã«ãã
ãããè¡ãããã«ãAcceptanceTestClientã¯ã©ã¹ãæãä»ãããã¹ãŠã®åé¡ãéæ³ã®ããã«è§£æ±ºããåãå
¥ããã¹ããå®è¡ããããã®åªããé«ã¬ãã«ã®ã€ã³ã¿ãŒãã§ã€ã¹ãæäŸãããµããããŸããã 䜿ãæ¹ã¯æ¬¡ã®ãšããã§ãã
client.openWhiteboardïŒ "xyz"ïŒ;
assertFalseïŒclient.hasWhiteboardïŒïŒïŒ;
ãã®ã³ãŒããæžãããããã¹ãã¹ã¯ãªããã«æé©ãªã€ã³ã¿ãŒãã§ã€ã¹ãå®éã«æãã€ããŸããã ãã¹ãã«ã¯ãæ¬äŒŒã³ãŒãã«ãã£ãã®ãšã»ãŒåãæ°ã®ã³ãŒãè¡ãå¿
èŠã§ãã
次ã«ãEclipseãããããŒã䜿çšããŠã空ã®AcceptanceTestClientã¯ã©ã¹ãšå¿
èŠãªã¡ãœãããèªåçã«çæããŸããã
public class AcceptanceTestClient { public void openWhiteboard(String string) {
ãã¹ãã¯ã©ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
public class AcceptanceTest { AcceptanceTestClient client; @Test public void openWhiteboardThatDoesntExist() {
ãã¹ãã¯éå§ãããŸãããã¯ã©ãã·ã¥ããŸãïŒã¯ã©ã€ã¢ã³ããnullã§ããããïŒã ãããïŒ
ç§ã¯äœãéæããŸãããïŒ ããŸãèšããªãã§ãã ããã ããããããã¯å§ãŸãã§ãã ããã§ãåãå
¥ããã¹ãã®ãã«ããŒã¯ã©ã¹ã®èèœ-AcceptanceTestClientãã§ããŸããã
ã¹ããã2.3 æãç°¡åãªèªååãå
¥ããã¹ããã°ãªãŒã³ã«ãã
次ã®ã¹ãããã¯ãåãå
¥ããã¹ããç·ã«ããããšã§ãã

ä»ãç§ã¯ã¯ããã«ç°¡åãªåé¡ã解決ããå¿
èŠããããŸãã èªèšŒã«ã€ããŠããè€æ°ã®ãŠãŒã¶ãŒã«ã€ããŠãããã®ãããªããšã«ã€ããŠãæ°ã«ããå¿
èŠã¯ãããŸããã ãããã®ã·ããªãªã®ãã¹ãã¯åŸã§è¿œå ã§ããŸãã
AcceptanceTestClientã«é¢ããŠã¯ããã®å®è£
ã¯ããªãæšæºçã§ãã-åœã®ïŒã¢ãã¯ïŒããŒã¿ããŒã¹ïŒãã®ããã®ã³ãŒãã¯æ¢ã«ãããŸããïŒãšã¡ã¢ãªå
ã®webwhiteboardã·ã¹ãã å
šäœã®ããŒãžã§ã³ãèµ·åããŸãã
ããã¯ã»ããã¢ãããã©ã®ããã«èŠãããã§ãïŒ

ïŒç»åãã¯ãªãã¯ãããšæ¡å€§ããŸãïŒ
æè¡ç詳现ïŒWeb Whiteboardã¯GWTïŒGoogle Web ToolkitïŒã䜿çšããŸãã ãã¹ãŠãJavaã§èšè¿°ãããŠããŸãããGWTã¯ã¯ã©ã€ã¢ã³ãã³ãŒããèªåçã«javascriptã«å€æããRPCïŒãªã¢ãŒãããã·ãŒãžã£ã³ãŒã«ïŒåŒã³åºããéæ³ã®ããã«æ¿å
¥ããŠãéåæã¯ã©ã€ã¢ã³ããµãŒããŒçžäºäœçšã®å®è£
ã®äœã¬ãã«ã®è©³çŽ°ããã¹ãŠé ããŸãã
åãå
¥ããã¹ããéå§ããåã«ãã·ã¹ãã ãçŽæ¥ãéãããŠããã¹ãŠã®ãã¬ãŒã ã¯ãŒã¯ãå€éšã³ã³ããŒãã³ããããã³ãããã¯ãŒã¯çžäºäœçšãåãåããŸãã

ïŒç»åãã¯ãªãã¯ãããšæ¡å€§ããŸãïŒ
ããã§ãå®éã®ã¯ã©ã€ã¢ã³ãã³ãŒããšåãããã«webwhiteboardãµãŒãã¹ãšéä¿¡ããAcceptanceTestClientãäœæããŸãã éãã¯ã«ãŒãã³ã®åŸãã«é ããŠããŸãã
- å®éã®ã¯ã©ã€ã¢ã³ãã¯ãGWTç°å¢ã§å®è¡ãããWebãã¯ã€ãããŒããµãŒãã¹ã€ã³ã¿ãŒãã§ã€ã¹ãšéä¿¡ããŸããGWTç°å¢ã§ã¯ãåŒã³åºããèªåçã«RPCã«å€æããããµãŒããŒã«éä¿¡ãããŸãã
- åãå
¥ããã¹ãã¯ãWebãã¯ã€ãããŒããµãŒãã¹ã®Webã€ã³ã¿ãŒãã§ã€ã¹ãšãéä¿¡ããŸãããRPCãªãã§ãµãŒãã¹ã®å®è£
ãçŽæ¥åŒã³åºãããããã¹ãã®èµ·åäžã«GWTã¯äœ¿çšãããŸããã
ãŸããAcceptanceTestClientã®æ§æã¯ãå®éã®mongoããŒã¿ããŒã¹ïŒã¯ã©ãŠãNoSQLããŒã¿ããŒã¹ïŒãRAMã«ããŒã¿ãä¿åããåœç©ã«çœ®ãæããŸãã
ãã¹ãŠã®äŸåé¢ä¿ãã¹ããŒãã£ã³ã°ããäž»ãªçç±ã¯ãç°å¢ãç°¡çŽ åãããã¹ããé«éåãããã¹ãããã¹ãŠã®ã³ã³ããŒãã³ãããã³ãããã¯ãŒã¯æ¥ç¶ããç¬ç«ããŠããžãã¹ããžãã¯ãã«ããŒããããšã確èªããããã§ãã
ãã®èšå®ã¯ãã¹ãŠè€éãããããã«æãããããããŸããããå®éã«ã¯ããã£ã3è¡ã®ã³ãŒãã§æ§æããã1ã€ã®initã¡ãœããã«ãããŸããã
public class AcceptanceTest { AcceptanceTestClient client; @Before public void initClient() { WhiteboardStorage fakeStorage = new FakeWhiteboardStorage(); WhiteboardService service = new WhiteboardServiceImpl(fakeStorage); client = new AcceptanceTestClient(service); } @Test public void openWhiteboardThatDoesntExist() { client.openWhiteboard("xyz"); assertFalse(client.hasWhiteboard()); } }
WhiteboardServiceImplã¯ãwebwhiteboardãµãŒãã¹ã®çã®å®è£
ã§ãã
AcceptanceTestClientã³ã³ã¹ãã©ã¯ã¿ãŒãWhiteboardServiceã®ã€ã³ã¹ã¿ã³ã¹ïŒäŸåæ§æ³šå
¥èšèšãã¿ãŒã³ïŒãåãå
¥ããããã«ãªããŸããã ããã«ãããè¿œå ã®å¯æ¬¡å¹æãåŸãããŸããã€ãŸããæ§æãæ°ã«ããŸããã åãAcceptanceTestClientã¯ã©ã¹ã䜿çšããŠãå®éã®ããŒã¹ã§æ§æãããWhiteboardServiceã®ã€ã³ã¹ã¿ã³ã¹ãæž¡ãã ãã§ãå®éã®ã·ã¹ãã ããã¹ãã§ããŸãã
public class AcceptanceTestClient { private final WhiteboardService service; private WhiteboardEnvelope envelope; public AcceptanceTestClient(WhiteboardService service) { this.service = service; } public void openWhiteboard(String whiteboardId) { boolean createIfMissing = false; this.envelope = service.getWhiteboard(whiteboardId, createIfMissing); } public boolean hasWhiteboard() { return envelope != null; } }
èŠçŽãããšãAcceptanceTestClientã¯å®éã®webwhiteboard Webã¯ã©ã€ã¢ã³ãã®ããã«åäœãããšåæã«ãåãå
¥ããã¹ãçšã®é«ã¬ãã«ã®ã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããŸãã
ãçŽæ¥åŒã³åºãããšãã§ããWhiteboardServiceãæ¢ã«ããã®ã«ããªãAcceptanceTestClientãå¿
èŠãªã®ãããšå°ããããšãã§ããŸãã ããã«ã¯2ã€ã®çç±ããããŸãã
- WhiteboardServiceãµãŒãã¹ã€ã³ã¿ãŒãã§ã€ã¹ã¯äœã¬ãã«ã§ãã AcceptanceTestClientã¯ãåãå
¥ããã¹ãã«å¿
èŠãªã¡ãœãããããã¹ããã§ããã ãæ確ã«ãã圢åŒã§æ£ç¢ºã«æäŸããŸãã
- AcceptanceTestClientã¯ããã¹ãã«éèŠã§ã¯ãªãããããçš®é¡ã®å°ããªããšãé ããŸã-ããšãã°ãWhiteboardEnvelopeã®æŠå¿µãããŒã«åcreateIfMissingãããã³ãã®ä»ã®äœã¬ãã«ã®è©³çŽ°ã å®éããã®ã¹ã¯ãªããã¯UserServiceãWhiteboardSyncServiceãªã©ã®ä»ã®ãµãŒãã¹ã䜿çšããŸãã
ãã®èšäºã¯webwhiteboardããã€ã¹ã«é¢ãããã®ã§ã¯ãªããããAcceptanceTestClientå®è£
ã®è©³çŽ°ã«ã€ããŠã¯ãã説æããŸããã AcceptanceTestClientã¯ãåãå
¥ããã¹ãã®ããŒãºãšããµãŒãã¹ã€ã³ã¿ãŒãã§ã€ã¹ãšã®å¯Ÿè©±ã®å®è£
ã®äœã¬ãã«ã®è©³çŽ°ãçµã³ä»ããŠãããšèšãã°ååã§ãã å®éã®ã¯ã©ã€ã¢ã³ãã³ãŒãã¯ããµãŒãã¹ãšã®å¯Ÿè©±æ¹æ³ã®ãã³ããšãªããããç°¡åã«èšè¿°ã§ããŸããã
ãããã«ãããä»ã§ã¯æãç°¡åãªåãå
¥ããã¹ãã«åæ ŒããŠããŸãïŒ
@Test public void openWhiteboardThatDoesntExist() { myClient.openWhiteboard("xyz"); assertFalse(myClient.hasWhiteboard()); }
次ã®ã¹ãããã¯å°ãæŽçããããšã§ãã

å®éãç§ã¯ãŸã ãã®ã³ãŒãã1è¡ãæžãããŠããŸããïŒãã®æ©èœã¯æ¢ã«ååšããæ©èœããŠããããïŒãããã¯ãã¹ããã¬ãŒã ã¯ãŒã¯ã®ã³ãŒãã«éããŸããã ããã«ãããããããç§ã¯ãããã¯ãªãŒã³ã¢ããããéè€ãåãé€ããã¡ãœããã«ããããããããååãä»ãããªã©ãæ°åãè²»ãããŸããã
æåŸã«ãå®å
šæ§ã®ããã«ããŸãç°¡åã ã£ãã®ã§ãå¥ã®ãã¹ããè¿œå ããŸããïŒoïŒ
@Test public void createNewWhiteboard() { client.createNewWhiteboard(); assertTrue(client.hasWhiteboard()); }
ã»ãããã¹ããã¬ãŒã ã¯ãŒã¯ããããŸãïŒ ãããŠããã¡ãã·ã§ããã«ãªãµãŒãããŒãã£ã©ã€ãã©ãªã¯ãããŸããã JavaãšJunitã®ã¿ã
ã¹ããã2.4ãã¹ã¯ãŒãä¿è·ã®åãå
¥ããã¹ããæžã
次ã«ããã¹ã¯ãŒããã¹ããè¿œå ããŸãã
æ¬äŒŒã³ãŒãã䜿çšããŠããã¹ãã®ãä»æ§ãã説æããããšããå§ããŸãã
@Test public void passwordProtect() {
ãããŠä»ã以åãšåæ§ã«ãAcceptanceTestClientã¯ã©ã¹ã«å¿
èŠãªãã®ããã¹ãŠæã£ãŠãããµããããŠããã¹ãã³ãŒããæžããŠããŸãã ãã®ææ³ã¯éåžžã«äŸ¿å©ã§ãã
@Test public void passwordProtect() {
ãã®ã³ãŒããæžãã®ã«ã»ãã®æ°åãè²»ãããŸãããæžãããšãã«å¿
èŠãªãã®ãæãã€ããããã§ãã ãããã®ã¡ãœããã¯ãAcceptanceTestClientã¯ã©ã¹ã«ã¯ã»ãšãã©ãããŸããïŒãŸã ïŒã
ã³ãŒããæžããŠããéãç§ã¯ãã§ã«ããã€ãã®æ±ºå®ãããªããã°ãªããŸããã§ããã èããããå¿
èŠã¯ãããŸãããæåã«æãã€ããããšãå®è¡ããã ãã§ãã æé«ã®ãã®ã¯åã®æµã§ãããä»ç§ãæãã®ã¯ãååã«è¯ãçµæãã€ãŸããå®è¡ã§ããŠèœã¡ããã¹ããååŸããããšã§ãã ãã®åŸããã¹ããç·è²ã«ãªã£ãããã³ãŒãããªãã¡ã¯ã¿ãªã³ã°ãããã®èšèšãæ¹åããæ¹æ³ã«ã€ããŠããæ
éã«èããŸãã
ç¹ã«ãããã®ã²ã©ãtry / catchã¹ããŒãã¡ã³ãããªãã¡ã¯ã¿ãªã³ã°ããããã«ãããã«ã³ãŒããçµã¿åããå§ããããšããèªæããããŸãã ããããTDDã®æ³åã®1ã€ã¯ããªãã¡ã¯ã¿ãªã³ã°ãéå§ããåã«ãã¹ããã°ãªãŒã³ã«ããããšã§ãããªãã¡ã¯ã¿ãªã³ã°ãããšããã¹ãã«ãã£ãŠä¿è·ãããŸãã ããã§ãã³ãŒãã®ã³ãŒãã³ã°ã延æããããšã«ããŸããã
ã¹ããã3-åãå
¥ããã¹ããå®è¡ããŠãã©ãŒã«ãã
ãã¹ãã®äžè§åœ¢ã«ç¶ããŠã次ã®ã¹ãããã¯ãã¹ããéå§ããŠå€±æãããããšã§ãã

空ã®ã¡ãœãããäœæããããã«ãEclipseãããããŒãå床䜿çšããŸãã çŽ æŽãããã ãã¹ããå®è¡ããŠãåºæ¥äžãããèµ€ã ïŒ
ã¹ããã4ïŒåãå
¥ããã¹ããã°ãªãŒã³ã«ãã
次ã«ã補åã³ãŒããäœæããå¿
èŠããããŸãã ã·ã¹ãã ã«ããã€ãã®æ°ãããšã³ãã£ãã£ãè¿œå ããŠããŸãã è¿œå ããã³ãŒãã¯éåžžã«éèŠãªå Žåããããããåäœãã¹ãã§ã«ããŒããå¿
èŠããããŸããã TDDã§ãããè¡ããŸããã ããã¯ATDDãšåãã§ãããå°èŠæš¡ã§ãã
ãããATDDãšTDDã®é£æºæ¹æ³ã§ãã ATDDãå€åŽã®ã«ãŒããšèããŠãã ããã

ïŒæ°ããæ©èœã®ã¬ãã«ã§ïŒåãå
¥ããã¹ããèšè¿°ããåãµã€ã¯ã«ã«å¯ŸããŠãïŒã¯ã©ã¹ããã³ã¡ãœããã®ã¬ãã«ã§ïŒãŠããããã¹ããèšè¿°ããããã€ãã®ãµã€ã¯ã«ãè¡ããŸãã

ãã®ãããé«ãã¬ãã«ã§ã¯åãå
¥ããã¹ããã°ãªãŒã³ïŒæ°æéãããå ŽåããããŸãïŒã«ããããšã«éäžããŠããŸãããäœãã¬ãã«ã§ã¯ãããšãã°æ¬¡ã®ãŠããããã¹ãã§ããã¬ããïŒããã¯éåžžãæ°åããããŸãïŒã
çéå
¥ãã®ãé©åŒµãTDDãã§ã¯ãããŸããã ãå°ãªããšããåäœãã¹ããšè£œåã³ãŒããäžç·ã«ãã§ãã¯ãããŠããããšã確èªããŠãã ãããã«äŒŒãŠããŸãã ãããŠããã®ãããªãã§ãã¯ã¯1æéã«æ°åè¡ãããŸãã ãTDDã¹ã¿ã€ã«ããšåŒã¶ããšãã§ããŸãïŒoïŒã
ã¹ããã5ã³ãŒããã¯ãªãŒã³ã¢ãããã
éåžžãåãå
¥ããã¹ããç·è²ã«ãªã£ãããã¯ãªãŒãã³ã°ãå®è¡ããŸãã ããã決ããŠç¯çŽããªãã§ãã ããïŒ é£åŸã«ç¿ãæŽãæ¹æ³ã«ã€ããŠã§ã-ããã«ãããããã®ãæåã§ãã

ç§ã¯è£œåã³ãŒãã ãã§ãªãããã¹ãã³ãŒããã¯ãªãŒãã³ã°ããŠããŸãã ããšãã°ãæ±ãtry-catchããã«ããŒã¡ãœãããšããŠåŒ·èª¿è¡šç€ºããã¯ãªãŒã³ã§ããããªãã¹ãã¡ãœãããååŸããŸããã
@Test public void passwordProtect() { myClient.createNewWhiteboard(); String whiteboardId = myClient.getCurrentWhiteboardId(); myClient.protectWhiteboard("bigsecret"); assertCantOpenWhiteboard(joesClient, whiteboardId); assertCantOpenWhiteboard(joesClient, whiteboardId, "wildguess"); joesClient.openProtectedWhiteboard(whiteboardId, "bigsecret"); assertTrue(joesClient.hasWhiteboard()); }
ç§ã®ç®æšã¯ãåãå
¥ããã¹ããçããç°¡æœã§èªã¿ãããããŠãã³ã¡ã³ããåé·ã«ãªãããã«ããããšã§ãã æåã®æ¬äŒŒã³ãŒããšã³ã¡ã³ãã¯ãã³ãã¬ãŒããšããŠã®ã¿æ©èœããŸã-ãããã¯ãã³ãŒããã©ãã»ã©ãããã§ãããã§ãïŒã ã³ã¡ã³ããåé€ãããšåå©æãåŸãããããŒãã¹ãšããŠãã®æ¹æ³ã¯ããã«çããªããŸãïŒ
次ã¯ïŒ
ç¹°ãè¿ããŸãã æåã®åäœãã¹ããååŸãããšããã«ããŸã 足ããªããã®ã«ã€ããŠèããŸããã ããšãã°ãåé ã§ããã°ã€ã³ãããŠãŒã¶ãŒã®ã¿ããã¹ã¯ãŒãã§ããŒããä¿è·ã§ãããšèšããŸããã ããã§ãããã«ãã¹ããè¿œå ããèµ€ãç·ããããŠã³ãŒãããããã«ããŸããã ãªã©ãªã©ã
以äžã¯ããã®æ©èœã®ããã«è¡ã£ããã¹ãã®å®å
šãªãªã¹ãã§ãïŒä»ã®ãšããïŒïŒ
- passwordProtectionRequiresAuthentication
- ä¿è·ãã
- passwordOwnerDoesntHaveToKnowThePassword
- changePassword
- removePassword
- whiteboardPasswordCanOnlyBeChangedByThePersonWhoSetIt
ãã°ãèŠã€ããããæ°ãã䜿çšã·ããªãªãæãã€ããå Žåã¯ãåŸã§ããã€ãã®ãã¹ããè¿œå ããŸãã
å
šäœãšããŠãã³ãŒãã£ã³ã°ã«ã¯çŽ2æ¥ããããŸããã ã»ãšãã©ã®å Žåã以åã«äœæããã³ãŒããšãã¶ã€ã³ã«æ»ãããã«è²»ãããŸãããããã®èšäºãèªãã§ãããšãã®ããã«çŽç·çã§ã¯ãããŸããã§ããã
æåãã¹ãã¯ã©ãã§ããïŒ
ãã¡ãããã°ãªãŒã³åãå
¥ããã¹ããåãåã£ãåŸãå€ãã®æåãã¹ããè¡ããŸããã ããããèªååãå
¥ããã¹ãã¯åºæ¬çãªæ©èœãšå€ãã®ç¹æ®ãªã±ãŒã¹ã®äž¡æ¹ãã«ããŒããŠããããããã䞻芳çã§ç 究çãªãã¹ãã«éäžã§ããŸãã å
šäœçãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã¯ã©ãã§ããïŒ ãã®äžé£ã®ã¢ã¯ã·ã§ã³ã«ã¯æå³ããããŸããïŒ ããããããã§ããïŒ èª¬æããã¹ããè¿œå ããæ¹ãè¯ãã§ããããïŒ çŸçãªèŠ³ç¹ãããã¶ã€ã³ã¯è¯ãã§ããïŒ ãã¶ã€ã³è³ãåè³ããã€ããã¯ãããŸããããèšå¿µç¢çãªããã®ã欲ãããããŸããã
匷åãªäžé£ã®èªååãå
¥ããã¹ãã«ãããéå±ãªå調ãªæåãã¹ãïŒããµã«ãã¹ããïŒãæé€ãããããèå³æ·±ãææ矩ãªã¿ã€ãã®æåãã¹ãã®ããã®æéã解æŸãããŸãã
çæ³çã«ã¯ãæåããèªååãå
¥ããã¹ããéå§ããå¿
èŠããããããããçšåºŠæè¡çãªè² åµãè¿æžããŸããã
ããŒãã€ã³ã
ãã®äŸãã圹ã«ç«ãŠã°å¹žãã§ãïŒ åœŒã¯ããªãå
žåçãªç¶æ³ã瀺ããŠããŸã-ãæ°ããæ©èœãè¿œå ãããã®ã§ãèªååãå
¥ããã¹ããäœæããã®ã¯ããããšã§ããããããžã§ã¯ãã«ã¯ãŸã åãå
¥ããã¹ãããããŸãããã©ã®ãã¬ãŒã ã¯ãŒã¯ã䜿çšããã©ãããå§ããã¹ããããããŸãããã
ç§ã¯ãã®ãã³ãã¬ãŒãã倧奜ãã§ãäœåºŠãå°é¢ããéããããšãã§ããŸããã èŠçŽãããšïŒ
- æ¬åœã«äŸ¿å©ãªãã«ããŒã¯ã©ã¹ïŒç§ã®å Žåã¯AcceptanceTestClientïŒã«ã«ãã»ã«åãããåªãããã¬ãŒã ã¯ãŒã¯ãæ¢ã«æã£ãŠãããµããããŸãã
- çŸåšãã§ã«åäœããŠãããã®ïŒããšãã°ãåã«ã¢ããªã±ãŒã·ã§ã³ãéããªã©ïŒã«ã€ããŠãéåžžã«ç°¡åãªåãå
¥ããã¹ããäœæããŸãã ãã®ãã¹ãã䜿çšããŠãAcceptanceTestClientã®ãããªã¯ã©ã¹ãšãé¢é£ãããã¹ããã€ã³ãã£ã³ã°ïŒå®éã®ããŒã¿ããŒã¹ãä»ã®å€éšãµãŒãã¹ã®ãªãããŸããªã©ïŒãèšè¿°ããŸãã
- æ°ããæ©èœã®åãå
¥ããã¹ããäœæããŸãã å®è¡ããŸãããã¯ã©ãã·ã¥ããŸãã
- ãã¹ããç·è²ã«ããŸãã ã³ãŒããæžããšãã¯ãå€å°è€éãªã³ãŒãã®åäœãã¹ããæžããŠãã ããã
- ãªãã¡ã¯ã¿ãªã³ã°ã ãããŠãã¡ããªãã¯ãæ¹åããããã«ãããã«ããã€ãã®åäœãã¹ããäœæãããããã®éã®å Žå-äžèŠãªãã¹ããŸãã¯ã³ãŒããåé€ããŸãã ã³ãŒããç«ã®åµãšåãããããããã«ããŠãã ããïŒ
ãããè¡ããšãæãå°é£ãªéå£ãå
æã§ããŸãã ATDDã®äœ¿çšãéå§ããŸããïŒ
èè
ã«ã€ããŠ

Henrik Knibergã¯ã¹ããã¯ãã«ã ã®
ã¯ãªã¹ãã®ã¢ãžã£ã€ã«/ãªãŒã³ã³ã³ãµã«ã¿ã³ãã§ãäž»ã«
Spotifyã§åããŠããŸãã 圌ã¯ã人æ°ã®èæžã
Scrum and XP from the Trenches ããã
Kanban and Scrumãäž¡æ¹ãæ倧éã«æŽ»çšãã ãã§èª¬æãããŠããããã«ããœãããŠã§ã¢éçºã®æè¡çåŽé¢ãšäººéçåŽé¢ã®äž¡æ¹ã§äŒæ¥ã®æåãæ¯æŽããŠããŸãããããŠã
æºããã®åŸã ãã
ã¢ã¬ããµã³ããŒã»ã¢ã³ããããïŒ@ alex4ZeroïŒãã¢ã³ãã³ã»ããŽãºã£ã¯ïŒ@bevzukïŒãããããªãŒã»ããããã«ãã翻蚳
ã¹ããŒãã¹ãããã°ã«ãŒã ã