ãã¹ããã©ãããã¯ãããŸããŸãªè©³çŽ°ã¬ãã«ã§ãœãããŠã§ã¢ãã¹ããã°ã«ãŒãåããããšãæå³ããã¡ã¿ãã¡ãŒã§ãã ãŸãããããã®åã°ã«ãŒãã«ããã€ã®ãã¹ããè¡ãã¹ãããšããã¢ã€ãã¢ãæäŸããŸãã ãã¹ããã©ãããã®æŠå¿µã¯é·ãéååšããŠãããšããäºå®ã«ãããããããå€ãã®éçºããŒã ã¯ããããæ£ããæ£ããå®è¡ããããšããŠããŸãã ãã®èšäºã§ã¯ããã¹ããã©ãããã®åææŠå¿µã«ã€ããŠèª¬æãããããå®çŸããæ¹æ³ã瀺ããŸãã ãã©ãããã®ããŸããŸãªã¬ãã«ã§ã©ã®ã¿ã€ãã®ãã¹ããæ€çŽ¢ããå¿ èŠããããã瀺ãããããã®å®è£ æ¹æ³ã®å®çšçãªäŸã瀺ããŸãã
å
容
泚é
- èªååã®éèŠæ§ïŒãã¹ãïŒ
- ãã¹ããã©ããã
- æ€èšããããŒã«ãšã©ã€ãã©ãª
- å¿çšäŸ
- åäœãã¹ã
- çµ±åãã¹ã
- å¥çŽãã¹ã
- UIãã¹ã
- ãšã³ãããŒãšã³ãã®ãã¹ã
- åãå ¥ããã¹ã-æ©èœã¯æ£ããæ©èœããŸããïŒ
- ç 究ãã¹ã
- ãã¹ãã®çšèªãšã®æ··å
- å±éãã€ãã©ã€ã³ã§ã®ãã¹ãã®å±é
- ãã¹ãã®éè€ãé¿ãã
- ãã¹ãçšã®ã¯ãªãŒã³ãªã³ãŒããæžã
- ãããã«
泚é
ãœãããŠã§ã¢ã¯ãªãªãŒã¹åã«ãã¹ãããå¿ èŠããããŸãã ãœãããŠã§ã¢æ¥çãæçããã«ã€ããŠããã¹ãææ³ãæçããŸããã ç¡æ°ã®çãããã¹ã¿ãŒã®ä»£ããã«ãéçºè ã¯ã»ãšãã©ã®ãã¹ãã®èªååã«åãæ¿ããŸããã ãã¹ãã®èªååã«ãããæ°æ¥ãŸãã¯æ°é±éåŸã«ã§ã¯ãªããã³ãŒãã«å ¥åãããŠããæ°ç§ããã³æ°åã§ãã°ãèŠã€ããããšãã§ããŸãã
èªåãã¹ãã«ãã£ãŠåŒ·åãããåçã«ççž®ããããã£ãŒãããã¯ã«ãŒãã¯ãã¢ãžã£ã€ã«éçºãã©ã¯ãã£ã¹ãç¶ç¶çããªããªãŒãDevOpsã«ã«ãã£ãŒãšå¯æ¥ã«é¢é£ããŠããŸãã å¹æçãªãã¹ãã¢ãããŒãã«ãããè¿ éãã€ç¢ºå®ãªéçºãå¯èœã«ãªããŸãã
ãã®èšäºã§ã¯ããã€ã¯ããµãŒãã¹ã¢ãŒããã¯ãã£ãã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ããŸãã¯IoTãšã³ã·ã¹ãã ãæ§ç¯ããŠãããã©ããã«é¢ä¿ãªããæè»æ§ãä¿¡é Œæ§ãããã³ãµããŒããå®çŸããããã®æŽåœ¢åŒãã¹ãã¹ã€ãŒãã®å€èŠ³ã«ã€ããŠèª¬æããŸãã ãŸããå¹æçã§èªã¿ãããèªåãã¹ãã®äœæã«ã€ããŠã詳ããèŠãŠãããŸãã
èªååã®éèŠæ§ïŒãã¹ãïŒ
ãœãããŠã§ã¢ã¯ãç§ãã¡ãäœãã§ããäžçã®äžå¯æ¬ ãªéšåãšãªã£ãŠããŸãã ããžãã¹ã®å¹çæ§ãé«ãããšããæ¬æ¥ã®å¯äžã®ç®çãè¶ ããŸããã ä»æ¥ããã¹ãŠã®äŒæ¥ã¯äžæµã®ããžã¿ã«äŒæ¥ã«ãªãããšãç®æããŠããŸãã ç§ãã¡ã¯æ¯æ¥ããŸããŸãå€ãã®ãœãããŠã§ã¢ã®ãŠãŒã¶ãŒãšããŠè¡åããŠããŸãã ã€ãããŒã·ã§ã³ã®é床ã¯å¢å ããŠããŸãã
æ代ã«é ããªãããã«ããã«ã¯ããœãããŠã§ã¢ã®å質ãç ç²ã«ããããšãªããããè¿ éã«ãœãããŠã§ã¢ãæäŸããæ¹æ³ãæ¢ãå¿ èŠããããŸãã ç¶ç¶çãªé ä¿¡ã¯ããã«åœ¹ç«ã¡ãŸããããã¯ããœãããŠã§ã¢ããã€ã§ãæ¬çªç°å¢ã«ãªãªãŒã¹ãããããšãèªåçã«ä¿èšŒãããã©ã¯ãã£ã¹ã§ãã ç¶ç¶çãªé ä¿¡ã§ã¯ãã¢ã»ã³ããªãã€ãã©ã€ã³ã䜿çšããŠãœãããŠã§ã¢ãèªåçã«ãã¹ããããã¹ãç°å¢ããã³éçšç°å¢ã«å±éããŸãã
ããã«ãå¢ãç¶ãããœãããŠã§ã¢ãæåã§ã¢ã»ã³ãã«ããã¹ããå±éããããšã¯äžå¯èœã«ãªããŸã-åäœäžã®ãœãããŠã§ã¢ãæäŸããã®ã§ã¯ãªããæ¥åžžçãªã¿ã¹ã¯ãæåã§è¡ãå Žåãé€ããŸãã å¯äžã®æ¹æ³ã¯ãã¢ã»ã³ããªãããã¹ããå±éãã€ã³ãã©ã¹ãã©ã¯ãã£ã«è³ããŸã§ãã¹ãŠãèªååããããšã§ãã
å³ 1.èªåã§ä¿¡é Œæ§ã®é«ããœãããŠã§ã¢ã®è©Šé転ã«ã¢ã»ã³ããªãã€ãã©ã€ã³ã䜿çšãã
åŸæ¥ããã¹ãã§ã¯ããã¹ãç°å¢ã§ã®å±éãéããŠé床ã®æåäœæ¥ãå¿ èŠã§ããããã®åŸãããšãã°ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®ä»»æã®å Žæãã¯ãªãã¯ããŠãã°ã衚瀺ããããã©ããã確èªãããã©ãã¯ããã¯ã¹ã¹ã¿ã€ã«ã®ãã¹ããå¿ èŠã§ããã å€ãã®å Žåããããã®ãã¹ãã¯ãã¹ãã¹ã¯ãªããã«ãã£ãŠèšå®ããããã¹ã¿ãŒããã¹ãŠãé çªã«ãã¹ãããããã«ããŸãã
æããã«ããã¹ãŠã®å€æŽãæåã§ãã¹ãããã«ã¯å€ãã®æéãããããå調ã§éå±ã§ãã å調ãã¯éå±ã§ãããéå±ã¯ééãã«ã€ãªãããŸãã
幞ããªããšã«ãåãã¿ã¹ã¯ã®ããã®åªããããŒã«ããããŸã ïŒ ãªãŒãã¡ãŒã·ã§ã³ ã
çµ±äžããããã¹ããèªååãããšãéçºè ãšããŠã®ç掻ãå€ãããŸãã ãã¹ããèªååããã°ãããã°ã©ã ã®æ£ããåäœã確èªããããã«ãã¯ãªãã¯ãããã³ã«ãç¡æèã«ãã©ãå¿ èŠããªããªããŸãã ãã¹ããèªååããç®ãå€ããã«ã³ãŒãããŒã¹ãå€æŽããŸãã é©åãªãã¹ãã»ããã䜿çšããã«å€§èŠæš¡ãªãªãã¡ã¯ã¿ãªã³ã°ãè©Šã¿ãããšãããã°ããããã©ã®ãããªææã«ã€ãªããããç¥ã£ãŠããã¯ãã§ãã 誀ã£ãŠããã»ã¹ãééããå Žåãã©ã®ããã«ããŠããããŸããïŒ ããŠããã¹ãŠã®ãã¹ãã±ãŒã¹ãæåã§ã¯ãªãã¯ããå¿ èŠããããŸãã ããããæ£çŽã«èšã£ãŠã¿ãŸããããæ¬åœã«å¥œãã§ããïŒ å€§èŠæš¡ãªå€æŽãè¡ã£ãåŸã§ããã³ãŒããŒã飲ã¿ãªããæ°ç§ä»¥å ã«ãã°ãçŸããŸããïŒ ç§ã®æèŠã§ã¯ãããã¯ã¯ããã«åªããŠããŸãã
ãã¹ããã©ããã
èªååããããã¹ããçå£ã«èããŠããå ŽåãéèŠãªæŠå¿µã1ã€ãããŸãã ãã¹ããã©ãããã§ãã 圌女ã¯Mike Cohnã®èæžScrumïŒ Agile Software Development Using Scrumã§çŽ¹ä»ãããŸããã ããã¯åªããèŠèŠçé phorã§ãããããŸããŸãªã¬ãã«ã®ãã¹ãã瀺åããŠããŸãã ãŸããåã¬ãã«ã§ã®ãã¹ãã®éã瀺ããŸãã
å³ 2.ãã©ãããããã¹ããã
ãã€ã¯ã³ãŒã³ã®å ã®ãã¹ããã©ãããã¯ã3ã€ã®ã¬ãã«ïŒäžããäžïŒã§æ§æãããŠããŸãã
- åäœãã¹ãã
- ãµãŒãã¹ãã¹ã
- ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãã¹ã
æ®å¿µãªããããã培åºçãªã³ã³ã»ããã§ã¯äžååã®ããã§ãã ãã€ã¯ã³ãŒã³ã®ãã¹ãã®ãã©ãããã®åœåãŸãã¯æŠå¿µçãªåŽé¢ã®ãããããå®å šã§ã¯ãªããšäž»åŒµãã人ãããŸãããç§ã¯åæããå¿ èŠããããŸãã çŸä»£ã®èŠ³ç¹ããããã¹ããã©ãããã¯é床ã«åçŽåãããŠããããã«èŠããããã誀解ãæãå¯èœæ§ããããŸãã
ãã ããã·ã³ãã«ãªããããã¹ããã©ãããã®æ¬è³ªã¯ãç¬èªã®ãã¹ãã¹ã€ãŒããäœæããéã®çµéšåã§ãã ãã®ãã©ãããããèŠããŠããã¹ãäž»ãªããšã¯ã2ã€ã®ååã§ãã
- ç°ãªã詳现ã®ãã¹ããäœæããŸãã
- ã¬ãã«ãé«ãã»ã©ããã¹ãã¯å°ãªããªããŸãã
ãã©ãããã®åœ¢ç¶ã«åºå·ããŠãå¥åº·çã§é«éã§ä¿å®å¯èœãªãã¹ãã¹ã€ãŒããäœæããŸãã å°ãããŠçŽ æ©ãåäœãã¹ãã ããããæžããŠãã ããã ããäžè¬çãªãã¹ããããã€ãäœæããã¢ããªã±ãŒã·ã§ã³ãæåããæåŸãŸã§ãã¹ãããé«ã¬ãã«ã®ãšã³ãããŒãšã³ããã¹ããããã€ãäœæããŸãã ãã¹ãã¢ã€ã¹ã¯ãªãŒã ã³ãŒã³ã«ãªã£ãŠããªãããšã確èªããŠãã ãããããã¯ãµããŒãã®æªå€¢ã«ãªããå®äºããã®ã«æéãããããããŸãã
ãã¹ããã©ãããã®åã ã®ã¬ãã«ã®ååã«ããŸãå·çããªãã§ãã ããã å®éã誀解ãæãå¯èœæ§ããããŸããããµãŒãã¹ãã¹ãããšããçšèªã¯ç解ããã®ãé£ããã§ãïŒCohnèªèº«ã¯ã å€ãã®éçºè ããã®ã¬ãã«ãå®å šã«ç¡èŠããŠããããšã«æ³šæããŸããïŒã æè¿ãReactãAngularãEmber.jsãªã©ã®åäžããŒãžã¢ããªã±ãŒã·ã§ã³ã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãUIãã¹ãããã©ãããã®æäžäœã«å±ããªãããšãæããã«ãªããŸãããããããã¹ãŠã®ãã¬ãŒã ã¯ãŒã¯ã§UIãå®å šã«ãã¹ãã§ããŸãã
ãã©ãããã®å ã®ååã®æ¬ ç¹ãèãããšããã¹ãã¬ãã«ã®ä»ã®ååãæãä»ãã®ã¯ããæ®éã®ããšã§ãã äž»ãªãã®ã¯ã圌ããããªãã®ããŒã ã«ãã£ãŠæ¡çšãããããªãã®ã³ãŒããšçšèªã«å¯Ÿå¿ãããšããããšã§ãã
æ€èšããããŒã«ãšã©ã€ãã©ãª
- JUnit ïŒãã¹ããå®è¡ãã
- Mockito ïŒã·ãã¥ã¬ãŒã·ã§ã³ã®äŸåé¢ä¿
- Wiremock ïŒã¹ã¿ãå€éšãµãŒãã¹çš
- åå® ïŒCDCãã¹ããæžãããã«
- Selenium ïŒãšã³ãããŒãšã³ãã®UIãã¹ããæžããã
- RESTä¿èšŒ ïŒãšã³ãããŒãšã³ãREST APIãã¹ããäœæãããã
å¿çšäŸ
ãã©ãããã®ããŸããŸãªã¬ãã«ã®ãã¹ãã䜿çšããŠã ç°¡åãªãã€ã¯ããµãŒãã¹ãäœæããŸããã
ããã¯å žåçãªãã€ã¯ããµãŒãã¹ã®äŸã§ãã RESTã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããããŒã¿ããŒã¹ãšéä¿¡ãããµãŒãããŒãã£ã®RESTãµãŒãã¹ããæ å ±ãæœåºããŸãã Spring Bootã§å®è£ ãããŠããã Spring Bootã䜿çšããããšããªãå Žåã§ãç解ããå¿ èŠããããŸãã
å¿ ãGithubã§ã³ãŒãã確èªããŠãã ããã readmeãã¡ã€ã«ã«ã¯ãã³ã³ãã¥ãŒã¿ãŒã§ã¢ããªã±ãŒã·ã§ã³ãšèªåãã¹ããå®è¡ããããã®æ瀺ãå«ãŸããŠããŸãã
æ©èœæ§
ã¢ããªã±ãŒã·ã§ã³ã«ã¯ã·ã³ãã«ãªæ©èœããããŸãã 3ã€ã®ãšã³ããã€ã³ããæã€RESTã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸãã
GET /hello
"Hello World" . .
GET /hello /{lastname}
. , "Hello {Firstname} {Lastname}" .
GET /weather
, .
é«ã¬ãã«ã®æ§é
倧ãŸãã«èšããšãã·ã¹ãã ã®æ§é ã¯æ¬¡ã®ãšããã§ãã
å³ 3.é«ã¬ãã«ã®ãã€ã¯ããµãŒãã¹æ§é
åœç€Ÿã®ãã€ã¯ããµãŒãã¹ã¯ãHTTPçµç±ã®RESTã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸãã äžéšã®ãšã³ããã€ã³ãã§ã¯ããµãŒãã¹ã¯ããŒã¿ããŒã¹ããæ å ±ãåãåããŸãã ãã以å€ã®å ŽåãHTTPçµç±ã§å€éšAPIã«ã¢ã¯ã»ã¹ããŠãçŸåšã®å€©æ°ãåä¿¡ããŠââ衚瀺ããŸãã
ã€ã³ããªã¢å»ºç¯
å éšã§ã¯ãSpring Serviceã«ã¯Springã®å žåçãªã¢ãŒããã¯ãã£ããããŸãã
å³ 4.ãã€ã¯ããµãŒãã¹ã®å éšæ§é
-
Controller
ã¯ã©ã¹ã¯ã RESTãšã³ããã€ã³ããæäŸãã HTTPèŠæ±ãšå¿çãåŠçããŸã ã -
Repository
ã¯ã©ã¹ã¯ããŒã¿ããŒã¹ãšå¯Ÿè©±ããæ°žç¶ã¹ãã¬ãŒãžãšã®éã§ããŒã¿ãèªã¿æžãããŸãã -
Client
ã¯ã©ã¹ã¯ä»ã®APIãšããåãããŸãããã®äŸã§ã¯ãdarksky.netã®å€©æ°APIããHTTPSçµç±ã§JSONããŒã¿ãååŸããŸã ã -
Domain
ã¯ã©ã¹ã¯ããã¡ã€ã³ããžãã¯ãå«ããã¡ã€ã³ã¢ãã«ããã£ããã£ããŸã ïŒæ£çŽãªãšãããããã¯éåžžã«ç°¡åã§ãïŒã
çµéšè±å¯ãªSpringéçºè ã¯ãé »ç¹ã«äœ¿çšãããã¬ã€ã€ãŒãæ¬ èœããŠããããšã«æ°ä»ãå ŽåããããŸãã åé¡æåã®èšèšã«è§Šçºãããå€ãã®éçºè ã¯ã ãµãŒãã¹ã¯ã©ã¹ã§æ§æããããµãŒãã¹ã¬ã€ã€ãŒãäœæããŸãã ã¢ããªã±ãŒã·ã§ã³ã«ã¯å«ããªãããšã«ããŸããã ãã®çç±ã®1ã€ã¯ãã¢ããªã±ãŒã·ã§ã³ãéåžžã«åçŽã§ããããµãŒãã¹å±€ãäžèŠãªã¬ãã«ã®éæ¥åã«ãªãããšã§ãã å¥ã®çç±ã¯ãç§ã®æèŠã§ã¯ã人ã ã¯ãã°ãã°ãããã®ã¬ã€ã€ãŒã§ããããããããããšã§ãã å€ãã®å ŽåããµãŒãã¹ã¯ã©ã¹ãããžãã¹ããžãã¯å šäœãã«ããŒããã³ãŒãããŒã¹ã確èªããå¿ èŠããããŸãã ãã¡ã€ã³ã¢ãã«ã¯ããŒã¿ã®åãªãã¬ã€ã€ãŒã«ãªããåäœã®ã¬ã€ã€ãŒã§ã¯ãããŸããïŒ è²§è¡ãã¡ã€ã³ã¢ãã« ïŒã ãã¹ãŠã®éèŠãªã¢ããªã±ãŒã·ã§ã³ã§ãåªããã³ãŒãæ§é åãšãã¹ã容ææ§ã®ããã®å€§ããªæ©äŒã倱ããããªããžã§ã¯ãæåã®åãååã«æŽ»çšãããŠããŸããã
ãªããžããªã¯ã·ã³ãã«ã§ãã·ã³ãã«ãªCRUDæ©èœãæäŸããŸãã ã³ãŒããç°¡åã«ããããã«ã Spring Dataã䜿çšããŸããã CRUDãªããžããªã®ã·ã³ãã«ã§æ®éçãªå®è£ ãæäŸããŸãããŸããæ¬çªç°å¢ã®ããã«å®éã®PostgreSQLã䜿çšããã®ã§ã¯ãªããã¡ã¢ãªã«ãã¹ãçšã®ããŒã¿ããŒã¹ããããã€ããããã«æ³šæããŸãã
ã³ãŒãããŒã¹ãèŠãŠãå éšæ§é ã«ç²ŸéããŠãã ããã ããã¯ã次ã®ã¹ãããã§ããã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãã«åœ¹ç«ã¡ãŸãïŒ
åäœãã¹ã
ãã¹ãã¹ã€ãŒãã®åºç€ã¯ãåäœãã¹ãïŒåäœãã¹ãïŒã§æ§æãããŠããŸãã 圌ãã¯ãã³ãŒãããŒã¹ã®å¥ã®ãŠãããïŒ ãã¹ã察象 ïŒãé©åã«æ©èœããŠããããšãæ€èšŒããŸãã åäœãã¹ãã«ã¯ããã¹ãã¹ã€ãŒãå ã®ãã¹ãŠã®ãã¹ãã®äžã§æãçãé åããããŸãã ã»ããå ã®åäœãã¹ãã®æ°ã¯ãä»ã®ãã¹ãã®æ°ãå€§å¹ ã«è¶ ããŠããŸãã
å³ 5.éåžžããŠããããã¹ãã¯å€éšãŠãŒã¶ãŒããã¹ããã€ã¯ã«çœ®ãæããŸãã
ãŠããããšã¯äœã§ããïŒ
ãŠããããã¹ãã®ã³ã³ããã¹ãã§ããŠãããããäœãæå³ãããã3人ã«å°ãããšããããã4ã€ã®ç°ãªããããã«ç°ãªãçããåŸãããŸãã ããçšåºŠãŸã§ãããã¯ããªãèªèº«ã®å®çŸ©ã®åé¡ã§ã-ãããŠãäžè¬ã«åãå ¥ããããæšæºçãªçãããªãããšã¯æ®éã§ãã
é¢æ°åèšèªã§èšè¿°ããå ŽåããŠãããã¯å¥ã®é¢æ°ã«ãªããŸãã åäœãã¹ãã¯ãããŸããŸãªãã©ã¡ãŒã¿ãŒã䜿çšããŠé¢æ°ãåŒã³åºããæåŸ ãããå€ãè¿ããŸãã ãªããžã§ã¯ãæåèšèªã§ã¯ããŠãããã¯åäžã®ã¡ãœããããã¯ã©ã¹å šäœãŸã§ããŸããŸã§ãã
瀟亀çã§å€ç¬ãªãã¹ã
被éšè ã®ãã¹ãŠã®åå è ïŒããšãã°ãã¯ã©ã¹ãšåŒã°ããïŒãã¢ãã¯ãŸãã¯ã¹ã¿ãã«çœ®ãæããŠãå®å šãªåé¢ãäœæããå¯äœçšãè€éãªãã¹ãèšå®ãåé¿ããå¿ èŠããããšäž»åŒµãã人ãããŸãã ä»ã®äººã¯ããã¹ããé ããããã匷ãå¯äœçšïŒããŒã¿ããŒã¹ããããã¯ãŒã¯åŒã³åºãã«ã¢ã¯ã»ã¹ã§ããã¯ã©ã¹ãªã©ïŒã瀺ããåå è ã®ã¿ãã·ãã¥ã¬ãŒã·ã§ã³ãšã¹ã¿ãã«çœ®ãæããå¿ èŠããããšäž»åŒµããŠããŸãã
ãããã®2çš®é¡ã®åäœãã¹ãã¯ãæš¡å£ãã¹ã¿ããå®å šã«äœ¿çšããå Žåã¯åç¬ãšåŒã°ããããšããã ãä»ã®åå è ãšã®å®éã®ã³ãã¥ãã±ãŒã·ã§ã³ã®å Žåã¯ç€Ÿäº€çãšåŒã°ããããšããããŸãïŒãããã®çšèªã¯ãæ¬ãå¹æçãªäœæ¥ã æéãããã°ããŠãµã®ã®ç©Žãäžã£ãŠãããŸããŸãªèŠç¹ã®é·æãšçæãç解ã§ããŸãã
ãã ããæçµçã«ã¯ãã©ã®ã¿ã€ãã®ãã¹ããéžæããŠãããŸããŸããã æ¬åœã«éèŠãªã®ã¯ãèªååã§ãã å人çã«ãç§ã¯åžžã«äž¡æ¹ã®ã¢ãããŒãã䜿çšããŸãã å®éã®åå è ãšäœæ¥ããã®ãäžäŸ¿ãªå Žåã¯ãã·ãã¥ã¬ãŒã·ã§ã³ãšã¹ã¿ããè±å¯ã«äœ¿çšããŸãã å®éã®åå è ãåŒãä»ããããšã§ãã¹ãã«èªä¿¡ãæãŠããšæãããããµãŒãã¹ã®æãé ãéšåã ããããæ¶ããŸãã
æš¡å£ãšã¹ã¿ã
æš¡é åïŒã¢ãã¯ïŒãšã¹ã¿ãïŒã¹ã¿ãïŒã¯ã2ã€ã®ç°ãªãã¿ã€ãã®ãã¹ãããã« ïŒäžè¬çã«ã¯ãã£ãšå€ããããŸãïŒã§ãã å€ãã®çšèªã¯åãæå³ã§äœ¿çšãããŸãã 粟床ãç¶æããããããã®ç¹å®ã®ç¹æ§ã念é ã«çœ®ããæ¹ãè¯ããšæããŸãã å®åã®ãªããžã§ã¯ãã«å¯ŸããŠããã¹ãããã«ã¯ãã¹ãã®å®è£ ãäœæããŸãã
ç°¡åã«èšãã°ãããªãã¯æ¬ç©ïŒã¯ã©ã¹ãã¢ãžã¥ãŒã«ãé¢æ°ãªã©ïŒãåœã®ã³ããŒã«çœ®ãæããŠããŸãã åœç©ã¯å ã®ããã«èŠããåãããã«åäœããŸãïŒåãã¡ãœããåŒã³åºãã«åãçããäžããŸãïŒãããããã¯ãŠããããã¹ãçšã«èªåã§å®çŸ©ããå®çŸ©æžã¿ã®çãã§ãã
ãã¹ãããã«ã¯ãŠããããã¹ãã ãã§ãªã䜿çšãããŸãã ããæŽç·Žãããããã«ã䜿çšããŠãã·ã¹ãã å šäœãå¶åŸ¡ããŠã·ãã¥ã¬ãŒãããŸãã ãã ãããŠããããã¹ãã§ã¯ãçŸä»£ã®å€ãã®èšèªãšã©ã€ãã©ãªã䜿çšãããšç°¡åã«äœæã§ãããããç¹ã«å€ãã®æš¡å£ãšã¹ã¿ãïŒç€Ÿäº€çãã¹ããšåäžãã¹ãã®ã©ã¡ãã奜ããã«ãã£ãŠç°ãªããŸãïŒã䜿çšããŸãã
éžæãããã¯ãããžãŒã«é¢ä¿ãªããèšèªã®æšæºã©ã€ãã©ãªãŸãã¯äžè¬çãªãµãŒãããŒãã£ã©ã€ãã©ãªã«ã¯ãã·ãã¥ã¬ãŒã·ã§ã³ãæ§æããããã®æŽç·Žãããæ¹æ³ãæ¢ã«ãããŸãã ãŸããç¬èªã®ã·ãã¥ã¬ãŒã·ã§ã³ãæåããäœæããå Žåã§ããå®éã®çœ²åãšåãã·ã°ããã£ãšãã¹ãçšã®ã·ãã¥ã¬ãŒã·ã§ã³èšå®ã䜿çšããŠãåœã®ã¯ã©ã¹/ã¢ãžã¥ãŒã«/é¢æ°ãäœæããã ãã§ãã
ãŠããããã¹ãã¯éåžžã«é«éã«åäœããŸãã ãŸãšããªãã·ã³ã§ã¯ãæ°åã§æ°åã®åäœãã¹ããå®è¡ã§ããŸãã ã³ãŒãããŒã¹ã®åé¢ãããå°ããªãã©ã°ã¡ã³ããåé¢ããŠãã¹ãããããŒã¿ããŒã¹ããã¡ã€ã«ã·ã¹ãã ãHTTPãªã¯ãšã¹ããšã®æ¥è§Šãåé¿ããŠïŒããã§ã·ãã¥ã¬ãŒã·ã§ã³ãšã¹ã¿ããèšå®ããããšã«ããïŒé«éãç¶æããŸãã
åºæ¬ãç解ããããæéã®çµéãšãšãã«ãŠããããã¹ããããèªç±ãã€ç°¡åã«èšè¿°ã§ããããã«ãªããŸãã å€éšåå è ãã¹ã¿ãããå ¥åãæ§æãããã¹ããµããžã§ã¯ããåŒã³åºããæ»ãå€ãæåŸ ã©ããã§ããããšã確èªããŸãã ãã¹ãã«ããéçº ïŒTDDïŒãèŠãŠããŠããããã¹ãã§éçºãã¬ã€ãããŸãã ããããæ£ããé©çšããããšã匷åãªã¹ããªãŒã ã«å ¥ããé©åãªãµããŒãã¢ãŒããã¯ãã£ãäœæããå æ¬çã§å®å šã«èªååããããã¹ãã¹ã€ãŒããèªåçã«çºè¡ããã®ã«åœ¹ç«ã¡ãŸãã ããããããã¯æ®éçãªè§£æ±ºçã§ã¯ãããŸããã è©ŠããŠã¿ãŠãTDDãé©åãã©ãããèªåã§ç¢ºèªããŠãã ããã
äœããã¹ãããŸããïŒ
ãŠããããã¹ãã¯ãæ©èœãæå±ããå éšæ§é ã®ã¬ãã«ã«é¢ä¿ãªãããããã¯ã·ã§ã³ã³ãŒãã®ãã¹ãŠã®ã¯ã©ã¹ã«å¯ŸããŠèšè¿°ã§ãããšäŸ¿å©ã§ãã ãŠããããã¹ãã¯ãã³ã³ãããŒã©ãŒããªããžããªããã¡ã€ã³ã¯ã©ã¹ããŸãã¯ãã¡ã€ã«ãªãŒããŒã«é©ããŠããŸãã ãããã¯ã·ã§ã³ã¯ã©ã¹ããšã«1ã€ã®ãã¹ãã¯ã©ã¹ã®å®çšçãªã«ãŒã«ã«åŸãã ãã§ãã
åäœãã¹ãã§ã¯ãå°ãªããšãã¯ã©ã¹ã®ãããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ããã¹ãããå¿ èŠããããŸã ã ãã©ã€ããŒãã¡ãœããã¯å¥ã®ãã¹ãã¯ã©ã¹ããåŒã³åºãããšãã§ããªãããããšã«ãããã¹ãã§ããŸããã ããã±ãŒãžïŒããã±ãŒãžãã©ã€ããŒãïŒã¡ãœããå ã§ã®ã¿ä¿è·ãŸãã¯ã¢ã¯ã»ã¹å¯èœã§ãïŒãã¹ãã¯ã©ã¹ã®ããã±ãŒãžæ§é ãæ¬çªç°å¢ãšåãã§ããå ŽåïŒããã ãããããã®ã¡ãœããã®ãã¹ãã¯æ¢ã«è¡ãéããŠããå¯èœæ§ããããŸãã
åäœãã¹ãã®äœæã«é¢ããŠã¯ã埮åŠãªæ©èœããããŸããããã©ã«ãã®ã¹ã¯ãªãããå¢çç·ã®ç¶æ³ãå«ãããã¹ãŠã®éèŠãªã³ãŒããã¹ããã§ãã¯ãããããã«ããå¿ èŠããããŸãã åæã«ãå®è£ ãšå¯æ¥ã«çµã³ä»ããããã¹ãã§ã¯ãããŸããã
ãªããã
å®åã³ãŒãã«æ·»ä»ãããããŠãããã¹ãã¯ããã«ãããããå§ããŸãã ã³ãŒãããªãã¡ã¯ã¿ãªã³ã°ãããšïŒã€ãŸããå€éšã®åäœãå€æŽããã«ã³ãŒãã®å éšæ§é ãå€æŽãããšïŒããã«ãåäœãã¹ãã¯ããã«äžæããŸãã
ãããã£ãŠãåäœãã¹ãã®éèŠãªå©ç¹ã倱ããŸãïŒã³ãŒãå€æŽã®ã»ãã¥ãªãã£ã·ã¹ãã ãšããŠæ©èœããŸãã ãããã®éŠ¬é¹¿ãããã¹ãã¯ããã«ç²ããŠããŸãããªãã¡ã¯ã¿ãªã³ã°åŸã«æ¯åèœã¡ãã®ã§ãè¯ãåé¡ãããå€ãã®åé¡ãçºçããŸãã ãã¹ããå®è£ ãããã®æããªã¢ã€ãã¢ã¯èª°ã®ã¢ã€ãã¢ã§ããïŒ
ã©ãããïŒ ã³ãŒãã®å éšæ§é ãåäœãã¹ãã«åæ ããªãã§ãã ããã 芳å¯ãããåäœããã¹ãããŸãã äŸïŒ
xãšyã®å€ãå ¥åãããšãçµæã¯zã«ãªããŸããïŒ
代ããã«ïŒ
xãšyãå°å ¥ããå Žåãã¡ãœããã¯æåã«ã¯ã©ã¹Aã«ãªãã次ã«ã¯ã©ã¹Bã«ãªãã次ã«ã¯ã©ã¹Aãšã¯ã©ã¹Bããã®çµæãè¿œå ããŸããïŒ
ååãšããŠããã©ã€ããŒãã¡ãœããã¯å®è£ ã®äžéšãšããŠæ€èšããå¿ èŠããããŸãã ãããããããããã¹ãããããšããé¡æãããããã¹ãã§ã¯ãªãçç±ã§ãã
å€ãã®å ŽåããŠããããã¹ãïŒãŸãã¯TDDïŒã®å察è ããã倧èŠæš¡ãªãã¹ãã«ãã¬ããžã®ããã«ãã¹ãŠã®ã¡ãœããããã¹ãããå¿ èŠãããå ŽåããŠããããã¹ãã®äœæã¯ç¡æå³ã«ãªããšèããŸãã å€ãã®å Žåã100ïŒ ã®ãã¹ãã«ãã¬ããžã«å°éããããã«ãé床ã«çæ°ãªããŒã ãªãŒããŒãã²ãã¿ãŒãã»ãã¿ãŒãããã³ãã®ä»ã®ç°¡åãªã³ãŒãã®ãŠããããã¹ãã匷å¶çã«äœæããã·ããªãªãåç §ããŸãã
ããã¯å®å šã«ééã£ãŠããŸãã
ã¯ãã ãããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ããã¹ãããå¿ èŠããããŸã ã ããããäºçŽ°ãªã³ãŒãããã¹ãããªãããšãããã«éèŠã§ã ã å¿é ããªãã§ãã ããã ã±ã³ãããã¯ã¯ãããæ¿èªããŸã ã åçŽãªã²ãã¿ãŒãŸãã¯ã»ãã¿ãŒãŸãã¯ãã®ä»ã®ç°¡åãªå®è£ ããã¹ãããããšããã¯äœãåŸãããŸããïŒããšãã°ãæ¡ä»¶ä»ãããžãã¯ãªãïŒã æéãç¯çŽã§ããã®ã§ãå¥ã®äŒè°ã«åå ã§ããŸãã
ããããç§ã¯æ¬åœã«ãã®ãã©ã€ããŒãã¡ãœããããã§ãã¯ããå¿ èŠããããŸã
éããã¡ãœãããæ¬åœã«ãæ¬åœã«ãã§ãã¯ããå¿ èŠãããç¶æ³ã«èªåèªèº«ãèŠã€ããå Žåãäžæ©åŸéããŠèªåã«å°ããå¿ èŠããããŸãïŒãªãã§ããïŒ
ãããèšèšäžã®åé¡ã§ããå¯èœæ§ãé«ããšç¢ºä¿¡ããŠããŸãã æãå¯èœæ§ãé«ãã®ã¯ããã©ã€ããŒãã¡ãœããããã¹ãããå¿ èŠããããšæããããšã§ãããã©ã€ããŒãã¡ãœããã¯è€éã§ãããã¯ã©ã¹ã®ãªãŒãã³ã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠã¡ãœããããã¹ãããã«ã¯ãããŸãã«ãäžäŸ¿ãªèšå®ãå¿ èŠã ããã§ãã
ãã®ãããªç¶æ³ã«é¥ã£ããšãã¯ãã€ã§ããéåžžããã¹ããããã¯ã©ã¹ã¯è€éããããšããçµè«ã«éããŸãã 圌ã¯ããéãã§ããã責任ã®å ±æãšããååã«éåããŠããŸãã
ç§ã«ãšã£ãŠã¯ããœãŒã¹ã¯ã©ã¹ã2ã€ã®ã¯ã©ã¹ã«åå²ãããœãªã¥ãŒã·ã§ã³ãããæ©èœããŸãã å€ãã®å Žåã1ã2åèããåŸã倧ããªã¯ã©ã¹ãåã ã®è²¬ä»»ã§2ã€ã®å°ããªã¯ã©ã¹ã«åå²ããè¯ãæ¹æ³ããããŸãã ãã©ã€ããŒãã¡ãœããïŒç·æ¥ã«ãã¹ãããå¿ èŠãããïŒãæ°ããã¯ã©ã¹ã«ç§»åããå€ãã¯ã©ã¹ã«æ°ããã¡ãœãããåŒã³åºãããŸãã ãã¹ãã«ã¯äžäŸ¿ãªãã©ã€ããŒãã¡ãœããã§ããVoilaã¯ãçŸåšå ¬éãããŠããããã¹ãã容æã§ãã ããã«ãåäžè²¬ä»»ã®ååãå°å ¥ããããšã«ãããã³ãŒãæ§é ãæ¹åããŸããã
è©Šéšæ§é
ãã¹ãŠã®ãã¹ãïŒãŠããããã¹ãã ãã§ãªãïŒã®é©åãªæ§é ã¯æ¬¡ã®ãšããã§ãã
- ãã¹ãããŒã¿ã®ã»ããã¢ããã
- ãã¹ãã¡ãœãããåŒã³åºããŸãã
- æåŸ ãããçµæãè¿ãããããšã確èªããŠãã ããã
ãã®æ§é ãèšæ¶ããããã®è¯ãããŒã¢ããã¯ããããŸãïŒ3 AïŒ ArrangeãActãAssert ïŒã BDDã§ã«ãŒããæã€ä»ã®ããŒã¢ããã¯ã䜿çšã§ããŸãïŒåäœã®èª¬æã«åºã¥ããéçºïŒã ãã®ãã©ã€ã¢ãã¯ããäžããããããèšå®ãåæ ããããã€ããã¡ãœããåŒã³åºãã§ãããããã®åŸããã¹ããŒãã¡ã³ãã§ããå Žåã«äžããããŸãã
ãã®ãã¿ãŒã³ã¯ãä»ã®ããé«ãã¬ãã«ã®ãã¹ãã«é©çšã§ããŸãã ãããã®å Žåãããã¹ããç°¡åã§èªã¿ããããªãããã«ããŸãã ããã«ããã®æ§é ã念é ã«çœ®ããŠèšè¿°ããããã¹ãã¯ãéåžžãããçããããè¡šçŸåè±ãã§ãã
åäœãã¹ãã®å®è£
ããã§ããã¹ããã察象ãšåäœãã¹ããæ§æããæ¹æ³ãããããŸããã çŸå®ã®äŸãèŠãŠã¿ãŸãããã
ExampleController
ã¯ã©ã¹ã®ç°¡æããŒãžã§ã³ã䜿çšããŠãã ããã
@RestController public class ExampleController { private final PersonRepository personRepo; @Autowired public ExampleController(final PersonRepository personRepo) { this.personRepo = personRepo; } @GetMapping("/hello/{lastName}") public String hello(@PathVariable final String lastName) { Optional<Person> foundPerson = personRepo.findByLastName(lastName); return foundPerson .map(person -> String.format("Hello %s %s!", person.getFirstName(), person.getLastName())) .orElse(String.format("Who is this '%s' you're talking about?", lastName)); } }
hello(lastname)
ã¡ãœããã®åäœãã¹ãã¯æ¬¡ã®ããã«ãªããŸãã
public class ExampleControllerTest { private ExampleController subject; @Mock private PersonRepository personRepo; @Before public void setUp() throws Exception { initMocks(this); subject = new ExampleController(personRepo); } @Test public void shouldReturnFullNameOfAPerson() throws Exception { Person peter = new Person("Peter", "Pan"); given(personRepo.findByLastName("Pan")) .willReturn(Optional.of(peter)); String greeting = subject.hello("Pan"); assertThat(greeting, is("Hello Peter Pan!")); } @Test public void shouldTellIfPersonIsUnknown() throws Exception { given(personRepo.findByLastName(anyString())) .willReturn(Optional.empty()); String greeting = subject.hello("Pan"); assertThat(greeting, is("Who is this 'Pan' you're talking about?")); } }
ãŠããããã¹ãã¯ãæšæºã®Javaãã¹ããã¬ãŒã ã¯ãŒã¯ã§ããJUnitã§èšè¿°ããŸãã Mockitoã䜿çšããŠãå®éã®
PersonRepository
ã¯ã©ã¹ããã¹ãçšã®ã¹ã¿ããæã€ã¯ã©ã¹ã«çœ®ãæããŸãã ãã®ã¹ã¿ãã䜿çšãããšãã¹ã¿ãã¡ãœãããè¿ãå®çŸ©æžã¿ã®åçãæå®ã§ããŸãã ãã®ã¢ãããŒãã«ããããã¹ããããç°¡åã§äºæž¬ãããããªããããŒã¿æ€èšŒã®èšå®ãç°¡åã«ãªããŸãã
ãã¹ãªãŒAãã®æ§é ã«åŸã£ãŠãåžæãã人ãèŠã€ãããªãå Žåã®ããžãã£ãããã³ãã¬ãã£ãã±ãŒã¹ã«ã€ããŠ2ã€ã®ãŠããããã¹ããäœæããŸãã ããžãã£ããã¹ãã±ãŒã¹ã¯ãæ°ããpersonãªããžã§ã¯ããäœæãã
lastName
ãã©ã¡ãŒã¿ãŒãPanã®å€ã§åŒã³åºããããšãã«ãã®ãªããžã§ã¯ããè¿ãããã«ãªããžããªã·ãã¥ã¬ãŒã·ã§ã³ã«æ瀺ããŸãã 次ã«ããã¹ãã¯ãã¹ãã¡ãœãããåŒã³åºããŸãã æåŸã«ã圌ã¯çããäºæ³ãšæ¯èŒããŸãã
2çªç®ã®ãã¹ããåæ§ã«æ©èœããŸããããã¹ãã¡ãœããããã®ãã©ã¡ãŒã¿ãŒã®äººç©ãªããžã§ã¯ããèŠã€ããããªãã·ããªãªããã¹ãããŸãã
å°éã®ãã¹ããã«ããŒ
ã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ã¬ãã«ã«é¢ä¿ãªããã³ãŒãããŒã¹å šäœã®åäœãã¹ããäœæã§ããããšã¯çŽ æŽãããããšã§ãã 以äžã®äŸã¯ãã³ã³ãããŒã©ãŒã®åçŽãªåäœãã¹ãã瀺ããŠããŸãã æ®å¿µãªãããSpringã³ã³ãããŒã©ãŒã«é¢ããŠã¯ããã®ã¢ãããŒãã«ã¯æ¬ ç¹ããããŸããSpringMVCã³ã³ãããŒã©ãŒã¯ããªã¹ãã³ã°ãã¹ã䜿çšãããHTTPã³ãã³ããURL解æãã©ã¡ãŒã¿ãŒããªã¯ãšã¹ããã©ã¡ãŒã¿ãŒãªã©ã®å®£èšã§ã¢ãããŒã·ã§ã³ãéäžçã«äœ¿çšããŸãã åäœãã¹ãã§ã³ã³ãããŒã©ã¡ãœãããåçŽã«åŒã³åºããŠããããããã¹ãŠã®éèŠãªããšã¯ãã¹ããããŸããã 幞ããªããšã«ãSpringã³ãã¥ããã£ã¯ãã³ã³ãããŒã©ãŒãã¹ãã®æ¹åã«äœ¿çšã§ããåªãããã¹ããã«ããŒãèæ¡ããŸããã å¿ ãMockMVCããã§ãã¯ããŠãã ãã ã ããã«ãããåœã®ã³ã³ãããŒã©ãŒèŠæ±ãçæãããã¹ãŠãæ£åžžã«æ©èœããŠããããšã確èªããããã®åªããDSLãæäŸãããŸãã ã³ãŒãã«äŸãå«ããŸãã ã å€ãã®ãã¬ãŒã ã¯ãŒã¯ã«ã¯ãã³ãŒãã®ç¹å®ã®éšåã®ãã¹ããç°¡çŽ åãããã¹ããã«ããŒããããŸãã ãã¬ãŒã ã¯ãŒã¯ã®ããã¥ã¡ã³ãã調ã¹ãŠãèªåãã¹ãã«åœ¹ç«ã€ãã«ããŒãæäŸãããŠãããã©ããã確èªããŠãã ããã
çµ±åãã¹ã
éèŠãªã¢ããªã±ãŒã·ã§ã³ã¯ãã¹ãŠãä»ã®äžéšïŒããŒã¿ããŒã¹ããã¡ã€ã«ã·ã¹ãã ãä»ã®ã¢ããªã±ãŒã·ã§ã³ãžã®ãããã¯ãŒã¯åŒã³åºãïŒãšçµ±åãããŠããŸãã åäœãã¹ãã§ã¯ãéåžžãããåªããåé¢ãšé床ã®ããã«ããããã·ãã¥ã¬ãŒãããŸãã ãã ããã¢ããªã±ãŒã·ã§ã³ã¯å®éã«ä»ã®éšåãšããåããããããããããã¹ãããå¿ èŠããããŸãã ãã®ããã«ã çµ±åãã¹ããæå³ãããŠããŸãã ãããã¯ãã¢ããªã±ãŒã·ã§ã³å€éšã®ãã¹ãŠã®ã³ã³ããŒãã³ããšã®ã¢ããªã±ãŒã·ã§ã³çµ±åãæ€èšŒããŸãã
èªåãã¹ãã®å Žåãããã¯ãç¬èªã®ã¢ããªã±ãŒã·ã§ã³ã ãã§ãªãçµ±åã³ã³ããŒãã³ããå®è¡ããå¿ èŠãããããšãæå³ããŸãã ããŒã¿ããŒã¹ãšã®çµ±åããã¹ãããŠããå Žåã¯ããã¹ããå®è¡ãããšãã«ããŒã¿ããŒã¹ãå®è¡ããå¿ èŠããããŸãã ãã£ã¹ã¯ããã®ãã¡ã€ã«ã®èªã¿åãã確èªããã«ã¯ããã¡ã€ã«ããã£ã¹ã¯ã«ä¿åããçµ±åãã¹ãã«ããŒãããå¿ èŠããããŸãã
ãŠããããã¹ãã¯ç¡æéã®çšèªã§ãããšå ã«è¿°ã¹ãŸããã ããã¯çµ±åãã¹ãã«ããã«é©çšãããŸãã äžéšã®å Žåããçµ±åããšã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã¹ã¿ãã¯å šäœãä»ã®ã¢ããªã±ãŒã·ã§ã³ãšçµã¿åãããŠãã¹ãããããšãæå³ããŸãã ç§ã¯ãåçµ±åãã€ã³ãã®ããçãå®çŸ©ãšãã¹ããåå¥ã«å¥œã¿ãæ®ãã®ãµãŒãã¹ãšããŒã¿ããŒã¹ããã¹ãã®ç 究ã«çœ®ãæããŸãã å¥çŽãã¹ããšãã¢ã³ããŒã¹ã¿ãã£ãŒããã³å®éã®å®è£ ã«é¢ããå¥çŽãã¹ãã®å®è¡ãšåãããŠãããéããããç¬ç«ãããéåžžã¯ç解ããããçµ±åãã¹ããæãä»ãããšãã§ããŸãã
çãçµ±åãã¹ãã¯ããµãŒãã¹ã®å¢çã§å®è¡ãããŸãã æŠå¿µçã«ã¯ãå€éšããŒãïŒãã¡ã€ã«ã·ã¹ãã ãããŒã¿ããŒã¹ãåå¥ã®ãµãŒãã¹ïŒãšã®çµ±åã«ã€ãªããã¢ã¯ã·ã§ã³ãåžžã«ããªã¬ãŒããŸãã ããŒã¿ããŒã¹çµ±åãã¹ãã¯æ¬¡ã®ãšããã§ãã
å³ 6.ããŒã¿ããŒã¹çµ±åãã¹ãã¯ãã³ãŒããå®éã®ããŒã¿ããŒã¹ãšçµ±åããŸã
- ããŒã¿ããŒã¹ã®å®è¡ã
- ã¢ããªã±ãŒã·ã§ã³ãããŒã¿ããŒã¹ã«æ¥ç¶ããŸãã
- ããŒã¿ããŒã¹ã«ããŒã¿ãæžã蟌ãã³ãŒãã§é¢æ°ãå®è¡ããŸãã
- ããŒã¿ããŒã¹ããããŒã¿ãèªã¿åãããšã«ãããäºæãããããŒã¿ãããŒã¿ããŒã¹ã«æžã蟌ãŸããããšã確èªããŸãã
å¥ã®äŸã REST APIãä»ããŠãµãŒãã¹ãå¥ã®ãµãŒãã¹ãšçµ±åããããã®ãã¹ãã¯æ¬¡ã®ããã«ãªããŸãã
å³ 7.ãã®ã¿ã€ãã®çµ±åãã¹ãã§ã¯ãã¢ããªã±ãŒã·ã§ã³ãåã ã®ãµãŒãã¹ãšé©åã«å¯Ÿè©±ã§ããããšã確èªããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã®èµ·åã
- å¥ã®ãµãŒãã¹ã®ã€ã³ã¹ã¿ã³ã¹ïŒãŸãã¯åãã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãããã¹ãããã¯ã¢ããïŒãèµ·åããŸãã
- å€éšãµãŒãã¹APIããããŒã¿ãèªã¿åãã³ãŒãã§é¢æ°ãå®è¡ããŸãã
- ã¢ããªã±ãŒã·ã§ã³ãå¿çãæ£ãã解æããããšã確èªããŸãã
åäœãã¹ããšåæ§ã«ãçµ±åãã¹ãã¯éåžžã«ééçã«å®è¡ã§ããŸãïŒãã¯ã€ãããã¯ã¹ïŒã äžéšã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ãåæã«èµ·åããåã ã®éšåãã·ãã¥ã¬ãŒãããŠæ£ããçžäºäœçšãæ€èšŒã§ããŸãã
ããŒã¿ãã·ãªã¢ã« åãŸãã¯éã·ãªã¢ã« åããããã¹ãŠã®ã³ãŒãã«å¯ŸããŠçµ±åãã¹ããèšè¿°ããŸãã ããã¯ãæã£ãŠãããããé »ç¹ã«èµ·ãããŸãã 次ã®ããšãèããŠãã ããïŒ
- ãµãŒãã¹ãžã®REST APIåŒã³åºãã
- ããŒã¿ããŒã¹ã®èªã¿åããšæžã蟌ã¿ã
- ä»ã®ã¢ããªã±ãŒã·ã§ã³ãžã®APIåŒã³åºãã
- ãã¥ãŒããèªã¿åããããã«æžã蟌ã¿ãŸãã
- ãã¡ã€ã«ã·ã¹ãã ãžã®æžã蟌ã¿ã
ãããã®å¢çã®åšãã«çµ±åãã¹ããèšè¿°ããããšã«ããããããã®å€éšåå è ããã®ããŒã¿ã®æžã蟌ã¿ãšèªã¿åããæ£åžžã«æ©èœããããšãä¿èšŒãããŸããçãçµ±åãã¹ãã
äœæããå Žåãå€éšã®äŸåé¢ä¿ãããŒã«ã«ã§å®è¡ããŠã¿ãŠãã ããïŒããŒã«ã«MySQLããŒã¿ããŒã¹ãããŒã«ã«ext4ãã¡ã€ã«ã·ã¹ãã ã§ã®ãã¹ããå¥ã®ãµãŒãã¹ãšçµ±åããå Žåã¯ããã®ãµãŒãã¹ã®ã€ã³ã¹ã¿ã³ã¹ãããŒã«ã«ã§éå§ããããå®éã®ãµãŒãã¹ã®åäœãæš¡å£ããåœããŒãžã§ã³ãäœæããŠå®è¡ããŸãã
ãµãŒãããŒãã£ã®ãµãŒãã¹ãããŒã«ã«ã§éå§ã§ããªãå Žåã¯ãå°çšã®ãã¹ãã€ã³ã¹ã¿ã³ã¹ãå®è¡ããçµ±åãã¹ãã§ããããã€ã³ãããããšããå§ãããŸããèªåãã¹ãã§ã¯ãå®éã®æ¬çªã·ã¹ãã ãšã®çµ±åãé¿ããŸããæ¬çªã·ã¹ãã ã«å¯ŸããŠäœåãã®ãã¹ããªã¯ãšã¹ããå®è¡ããããšã¯ããã°ãèšé²ããïŒããããïŒãããµãŒãã¹ãæäŸããïŒææªã®å ŽåïŒããã人ã ãæããã確å®ãªæ¹æ³ã§ãããããã¯ãŒã¯çµ±åã¯ãåºç¯ãªçµ±åãã¹ãã®å žåçãªæ©èœã§ããéåžžããã¹ãã¯èšè¿°ãé£ãããå®è¡é床ãé ããªããŸãã
ãã¹ããã©ãããã«é¢ããŠã¯ãçµ±åãã¹ãã¯åäœãã¹ããããé«ãã¬ãã«ã«ãããŸãããã¡ã€ã«ã·ã¹ãã ãšããŒã¿ããŒã¹ã®çµ±åã¯ãéåžžãã·ãã¥ã¬ãŒã·ã§ã³ã䜿çšããåäœãã¹ãã®å®è¡ãããã¯ããã«é ããªããŸãããŸããå°ããªåäœãã¹ããããèšè¿°ãå°é£ã§ããæåŸã«ããã¹ãã®å€éšéšåã®äœæ¥ã«ã€ããŠèããå¿ èŠããããŸããããã«ãé¢ãããããããã¯å¿ èŠãªãã¹ãŠã®å€éšéšåã§ã¢ããªã±ãŒã·ã§ã³ã®æ£ããåäœã«èªä¿¡ãäžãããããå©ç¹ããããŸããåäœãã¹ãã¯ããã§ã¯åœ¹ã«ç«ã¡ãŸããã
DBçµ±å
PersonRepository
-ã³ãŒãããŒã¹å šäœã§å¯äžã®ãªããžããªã¯ã©ã¹ãSpring Dataã«äŸåããŠãããå®éã®å®è£ ã¯ãããŸãããããã¯åã«ã€ã³ã¿ãŒãã§ãŒã¹
CrudRepository
ãæ¡åŒµããåäžã®ã¡ãœããããããŒãæäŸããŸããæ®ãã¯æ¥ã®éæ³ã§ãã
public interface PersonRepository extends CrudRepository<Person, String> { Optional<Person> findByLastName(String lastName); }
ã€ã³ã¿ãã§ãŒã¹ãä»ããŠ
CrudRepository
ã¹ããªã³ã°ããŒãã¯å®å šã«æ©èœãããªããžããªCRUDã¡ãœãããæäŸãã
findOne
ã
findAll
ã
save
ã
update
ããã³
delete
ãã¡ãœããã®ç¬èªã®å®çŸ©ã¯ã
findByLastName ()
ãã®åºæ¬çãªæ©èœãæ¡åŒµãã人ãã€ãŸããªããžã§ã¯ãã
Person
å§ã§åãåãããšãå¯èœã«ããŸãã Spring Dataã¯ã¡ãœããã®æ»ãå€ã®åãã¡ãœããã®ååã解æããåœåèŠåã«æºæ ããŠãããã©ããããã§ãã¯ããŠãäœããã¹ãããå€æããŸãã
Spring Dataã¯ããŒã¿ããŒã¹ãªããžããªãå®è£ ããäžã§çŽ æŽãããä»äºãããŠããŸãããç§ã¯ãŸã ããŒã¿ããŒã¹çµ±åãã¹ããæžããŸãããããã¯ãã¬ãŒã ã¯ãŒã¯ãã¹ãã§ãããšèšããŸãããä»ã®äººã®ã³ãŒãããã¹ãããŠããã®ã§ãé¿ããã¹ãã§ããããã§ããããã§ã¯å°ãªããšã1ã€ã®çµ±åãã¹ãã®ååšãéåžžã«éèŠã§ãããšèããŠããŸãããŸããmethodã®éåžžã®åäœããã§ãã¯ããŸã
findByLastName
ã次ã«ããªããžããªãSpringãæ£ãã䜿çšããããŒã¿ããŒã¹ã«æ¥ç¶ã§ããããšã蚌æããŸãã
ïŒPostgreSQLããŒã¿ããŒã¹ãã€ã³ã¹ããŒã«ããã«ïŒã³ã³ãã¥ãŒã¿ãŒã§ãã¹ããå®è¡ããããããããã«ããã¹ãã¯H2ã¡ã¢ãªã®ããŒã¿ããŒã¹ã«æ¥ç¶ããŸãã
H2ããã¡ã€ã«å ã®ãã¹ãäŸåé¢ä¿ãšããŠå®çŸ©ããŸãã
build.gradle
ã
application.properties
ãã¹ããã£ã¬ã¯ããªå ã®ãã¡ã€ã«ã¯ãããããã£ãå®çŸ©ããŸãã
spring.datasource
ãããã«ãããSpring Dataã¯ã¡ã¢ãªå ã®ããŒã¿ããŒã¹ã䜿çšããããã«ãªããŸãã圌ã¯ã¯ã©ã¹ãžã®éäžã§H2ãèŠã€ãããããåçŽã«H2ã䜿çšããŸãã
ãããã¡ã€ã«ã䜿çšããå®éã®ã¢ããªã±ãŒã·ã§ã³
int
ïŒããšãã°ãç°å¢å€æ°ãšããŠèšå®ããåŸ
SPRING_PROFILES_ACTIVE=int
ïŒã¯ãã§å®çŸ©ãããŠããPostgreSQLããŒã¿ããŒã¹ã«æ¥ç¶ããŸã
application-int.properties
ã
ããã§ã¯ãSpringã®å€ãã®æ©èœãç¥ã£ãŠç解ããå¿ èŠãããããšãç解ããŠããŸãã倧éã®ããã¥ã¡ã³ããã·ã£ãã«ã§ã·ã£ãã«ããå¿ èŠããããŸããæçµçãªã³ãŒãã®å€èŠ³ã¯åçŽã§ãããSpringã®ç¹å®ã®æ©èœãããããªãå Žåã¯ç解ãå°é£ã§ãã
ããã«ãã¡ã¢ãªå ã®ããŒã¿ããŒã¹ãæäœããããšã¯ãªã¹ã¯ã®é«ãããžãã¹ã§ããæçµçã«ãçµ±åãã¹ãã¯æ¬çªç°å¢ãšã¯ç°ãªãã¿ã€ãã®ããŒã¿ããŒã¹ã§æ©èœããŸãããããè©ŠããŠãSpringã®éæ³ãšã·ã³ãã«ãªã³ãŒãã奜ãããæ瀺çã§ã¯ããããã詳现ãªå®è£ ã奜ãããèªåã§æ±ºããŠãã ããã
ãŸããååãªèª¬æã Personãªããžã§ã¯ããããŒã¿ããŒã¹ã«ä¿åããå§ã§æ€çŽ¢ããç°¡åãªçµ±åãã¹ãã次ã«ç€ºããŸãã
@RunWith(SpringRunner.class) @DataJpaTest public class PersonRepositoryIntegrationTest { @Autowired private PersonRepository subject; @After public void tearDown() throws Exception { subject.deleteAll(); } @Test public void shouldSaveAndFetchPerson() throws Exception { Person peter = new Person("Peter", "Pan"); subject.save(peter); Optional<Person> maybePeter = subject.findByLastName("Pan"); assertThat(maybePeter, is(Optional.of(peter))); } }
ã芧ã®ãšãããçµ±åãã¹ãã¯åäœãã¹ããšåãã3 Aãæ§é ã«åŸããŸãã圌ã¯ããã¯æ®éçãªæŠå¿µã ãšèšã£ãïŒ
åã ã®ãµãŒãã¹ãšã®çµ±å
ãã€ã¯ããµãŒãã¹ã¯ãREST APIãä»ããŠdarksky.netããæ°è±¡ããŒã¿ãåãåããŸãããã¡ããããµãŒãã¹ããªã¯ãšã¹ããæ£ããéä¿¡ããåçã解æããããšã確èªããå¿ èŠããããŸãã
èªåãã¹ããå®è¡ãããšãã¯ãå®éã®darkskyãµãŒããŒãšã®çžäºäœçšãé¿ããããšããå§ãããŸããç¡æã¬ãŒãã®å¶éã¯ããã®çç±ã®1ã€ã«ãããŸãããäž»ãªãã®ã¯ãã«ãããªã³ã°ã§ãã darksky.netã®åªãã人ã ãä»äºãããŠãããã¹ãã¯å®è¡ãããã¯ãã§ãããã·ã³ãdarkskyãµãŒããŒã«å°éã§ããªãå ŽåããŸãã¯ã¡ã³ããã³ã¹ã®ããã«éããããŠããå Žåã§ãã
å®éã®darkskyãµãŒããŒãšã®çžäºäœçšãé¿ããããã«ãçµ±åãã¹ãã®ããã«ç¬èªã®åœã®darkskyãµãŒããŒãå®è¡ããŸããããã¯éåžžã«é£ããäœæ¥ã®ããã«æãããããããŸãããããããWiremockã®ãããªããŒã«ã®ãããã§åçŽåãããŠããŸããèªåã§èŠãŠãã ããïŒ
@RunWith(SpringRunner.class) @SpringBootTest public class WeatherClientIntegrationTest { @Autowired private WeatherClient subject; @Rule public WireMockRule wireMockRule = new WireMockRule(8089); @Test public void shouldCallWeatherService() throws Exception { wireMockRule.stubFor(get(urlPathEqualTo("/some-test-api-key/53.5511,9.9937")) .willReturn(aResponse() .withBody(FileLoader.read("classpath:weatherApiResponse.json")) .withHeader(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .withStatus(200))); Optional<WeatherResponse> weatherResponse = subject.fetchWeather(); Optional<WeatherResponse> expectedResponse = Optional.of(new WeatherResponse("Rain")); assertThat(weatherResponse, is(expectedResponse)); } }
Wiremockã®å Žå
WireMockRule
ãåºå®ããŒãïŒ
8089
ïŒã«ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã DSLã䜿çšããŠãWiremockãµãŒããŒãæ§æãããªãã¹ã³ãããšã³ããã€ã³ãã決å®ããå¿çãäºåå®çŸ©ã§ããŸãã
次ã«ããã¹ãã¡ãœããïŒãµãŒãããŒãã£ãµãŒãã¹ã«ã¢ã¯ã»ã¹ããã¡ãœããïŒãåŒã³åºããçµæãæ£ãã解æãããããšã確èªããŸãã
å®éã®darksky APIã®ä»£ããã«åœã®WiremockãµãŒããŒã䜿çšãã¹ãã§ãããšãã¹ããå€æããæ¹æ³ãç解ããããšãéèŠã§ããç§å¯ã®ãã¡ã€ã«
application.properties
ã«äœçœ®ããŠããŸã
src/test/resources
ããã¹ãã®å®è¡æã«ãSpringãããŒãããŸãããã®ãã¡ã€ã«ã§ã¯ããã¹ãã«é©ããå€ãæã€APIããŒãURLãªã©ã®æ§æãåå®çŸ©ããŸããç¹ã«ãå®éã®WiremockãµãŒããŒã§ã¯ãªããåœã®WiremockãµãŒããŒã«åŒã³åºããå²ãåœãŠãŸãã
weather.url = http://localhost:8089
ããã§å®çŸ©ããããŒãã¯ããã¹ãçšã«WireMockRuleã€ã³ã¹ã¿ã³ã¹ãäœæãããšãã«æå®ãããã®ãšåãã§ãªããã°ãªããªãããšã«æ³šæããŠãã ãããå®éã®APIã®URLãåœã®URLã«çœ®ãæããã«ã¯ãURLãã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ãŒã«å°å ¥ããŸã
WeatherClient
ã
@Autowired public WeatherClient(final RestTemplate restTemplate, @Value("${weather.url}") final String weatherServiceUrl, @Value("${weather.api_key}") final String weatherServiceApiKey) { this.restTemplate = restTemplate; this.weatherServiceUrl = weatherServiceUrl; this.weatherServiceApiKey = weatherServiceApiKey; }
ãã®
WeatherClient
ãããã¢ããªã±ãŒã·ã§ã³ã®ããããã£ã§å®çŸ©ãã
weatherUrl
property ãã©ã¡ãŒã¿ãŒã®å€ãèªã¿åãããã«æ瀺ã
weather.url
ãŸãã
Wiremockã®ãããªããŒã«ã䜿çšãããšãåäžã®ãµãŒãã¹ã®çãçµ±åãã¹ããäœæããã®ã¯éåžžã«ç°¡åãªäœæ¥ã«ãªããŸããæ®å¿µãªããããã®ã¢ãããŒãã«ã¯æ¬ ç¹ããããŸããäœæããåœã®ãµãŒããŒãå®éã®ãµãŒããŒã®ããã«åäœããããšãä¿èšŒããæ¹æ³ã¯ãããŸããïŒçŸåšã®å®è£ ã§ã¯ãå¥ã®ãµãŒãã¹ã§APIãå€æŽã§ããŸããããã¹ãã¯äœãèµ·ãããªãã£ãããã«ãã¹ããŸããçŸåš
WeatherClient
ãåœã®ãµãŒããŒããã®å¿çãåãå ¥ããããšãã§ãããã®ããã¹ãããŠããŸããããã¯å§ãŸãã§ãããéåžžã«å£ããããã§ãããšã³ãããŒãšã³ãã®ãã¹ãã¯åé¡ã解決ããŸããå®éã®ãµãŒãã¹ã§ãã¹ãããŸããããã®æ¹æ³ã§ã¯å¯çšæ§ã«äŸåããŸãã幞ããªããšã«ããã®ãžã¬ã³ãã«å¯Ÿããããè¯ã解決çããããŸã-å¥çŽãã¹ããšã·ãã¥ã¬ãŒã·ã§ã³ãããã³å®éã®ãµãŒããŒã¯ãçµ±åãã¹ãã®ã·ãã¥ã¬ãŒã·ã§ã³ãå ã®ãã®ãšæ£ç¢ºã«äžèŽããããšãä¿èšŒããŸããä»çµã¿ãèŠãŠã¿ãŸãããã
å¥çŽãã¹ã
ããè¿ä»£çãªäŒæ¥ã¯ãç°ãªãããŒã ã«äœæ¥ãåæ£ãããããšã§éçºãæ¡å€§ããæ¹æ³ãèŠã€ããŸãããçžäºã«å¹²æžããããšãªããççµåã®åå¥ã®ãµãŒãã¹ãäœæãããããã倧èŠæš¡ã§ã·ãŒã ã¬ã¹ãªã·ã¹ãã ã«çµ±åããŸãããããããã€ã¯ããµãŒãã¹ã«é¢ããæè¿ã®èªå€§å®£äŒã®ãã¹ãŠã§ãã
ã·ã¹ãã ãå€ãã®å°ããªãµãŒãã¹ã«åå²ãããšããããšã¯ãå€ãã®å Žåããããã®ãµãŒãã¹ãç¹å®ã®ïŒã§ããã°æ確ã«å®çŸ©ãããŠããããã©ã³ãã ã«äœæãããïŒã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠçžäºã«ããåãããå¿ èŠãããããšãæå³ããŸãã
ããŸããŸãªã¢ããªã±ãŒã·ã§ã³éã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãããŸããŸãªåœ¢åŒãšãã¯ãããžãŒã§å®è£ ã§ããŸããæãäžè¬çãªïŒ
- HTTPSçµç±ã®RESTããã³JSONã
- gRPCã®ãããªãã®ã䜿çšããRPC ã
- ãã¥ãŒã䜿çšããŠã€ãã³ãé§ååã¢ãŒããã¯ãã£ãæ§ç¯ããŸãã
åã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯ããµãã©ã€ã€ãšã³ã³ã·ã¥ãŒãã®2ã€ã®åŽé¢ãå«ãŸããŸãããµãã©ã€ã€ãŒã¯ãæ¶è²»è ã«ããŒã¿ãæäŸããŸããæ¶è²»è ã¯ãäŸçµŠè ããåãåã£ãããŒã¿ãåŠçããŸãã RESTã®äžçã§ã¯ããããã€ããŒã¯å¿ èŠãªãã¹ãŠã®ãšã³ããã€ã³ãã䜿çšããŠREST APIãäœæããã³ã³ã·ã¥ãŒããŒã¯ãã®REST APIã䜿çšããŠããŒã¿ãååŸããããå¥ã®ãµãŒãã¹ãžã®å€æŽãéå§ãããããŸããã€ãã³ãé§ååã¢ãŒããã¯ãã£ã®éåæã®äžçã§ã¯ããããã€ããŒïŒå€ãã®å Žåããããªãã·ã£ãŒãšåŒã°ããŸãïŒã¯ãã¥ãŒå ã®ããŒã¿ããããªãã·ã¥ããŸããã³ã³ã·ã¥ãŒãïŒãµãã¹ã¯ã©ã€ããšãåŒã°ããïŒã¯ãããã®ãã¥ãŒã«ãµãã¹ã¯ã©ã€ãããããŒã¿ãèªã¿åããåŠçããŸãã
å³ 8.åã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯ããµãã©ã€ã€ïŒãŸãã¯ãããªãã·ã£ãŒïŒãšã³ã³ã·ã¥ãŒãïŒãŸãã¯ãµãã¹ã¯ã©ã€ããŒïŒãå«ãŸããŸããã€ã³ã¿ãŒãã§ã€ã¹ä»æ§ã¯å¥çŽãšèŠãªãããšãã§ããŸãã
ãµãã©ã€ã€ãšã³ã³ã·ã¥ãŒãã®ãµãŒãã¹ã¯ç°ãªãããŒã ã«åŸã£ãŠåæ£ãããŠããããããããã®éã®ã€ã³ã¿ãŒãã§ãŒã¹ãæ確ã«ç€ºãå¿ èŠãããç¶æ³ã«ãããŸãïŒããããå¥çŽïŒãåŸæ¥ãäŒæ¥ã¯ãã®åé¡ã«æ¬¡ã®ããã«åãçµãã§ããŸãã
- ã€ã³ã¿ãŒãã§ãŒã¹ã®è©³çŽ°ã§è©³çŽ°ãªä»æ§ãèšè¿°ããŸãïŒã³ã³ãã©ã¯ãïŒã
- ç¹å®ã®å¥çŽã«åŸã£ãŠãµãã©ã€ã€ã®ãµãŒãã¹ãå®è£ ããŸãã
- ã€ã³ã¿ãŒãã§ãŒã¹ä»æ§ãã³ã³ã·ã¥ãŒããŒåŽã«è»¢éããŸãã
- ã€ã³ã¿ãŒãã§ã€ã¹ã®äžéšãå®è£ ãããŸã§åŸ ã¡ãŸãã
- 倧èŠæš¡ãªæåã·ã¹ãã ãã¹ããå®è¡ããŠããã¹ãŠãæ€èšŒããŸãã
- äž¡æ¹ã®ããŒã ãåžžã«ã€ã³ã¿ãŒãã§ã€ã¹ã®å®çŸ©ãé å®ããéªéãããªãããšãæãŸããŸãã
æè¿ã®äŒæ¥ã§ã¯ãæé 5ãš6ãèªååãããå¥çŽãã¹ãã«çœ®ãæãã顧客ãšãµãã©ã€ã€ã®å®è£ ãç¹å®ã®å¥çŽã«æºæ ããŠããããšã確èªããŠããŸãããããã¯ååž°ãã¹ãã®åªããã»ããã§ãããå¥çŽããã®éžè±ã®æ©ææ€åºãä¿èšŒããŸãã
ããæè»ãªçµç¹ã¯ãããå¹ççã§ç¡é§ã®å°ãªãã«ãŒããéžæããå¿ èŠããããŸããã¢ããªã±ãŒã·ã§ã³ã¯1ã€ã®çµç¹å ã§äœæãããŸããä»ã®ãµãŒãã¹ã®éçºè ã«é床ã«è©³çŽ°ãªããã¥ã¡ã³ããæããã®ã§ã¯ãªããéçºè ãšè©±ãããšã¯åé¡ã§ã¯ãªãã¯ãã§ããæçµçã«ããããã¯åŸæ¥å¡ã§ãããã«ã¹ã¿ããŒãµããŒããŸãã¯é²åŒŸã®æ³çå¥çŽãéããŠã®ã¿éä¿¡ã§ãããµãŒãããŒãã£ãã³ããŒã§ã¯ãããŸããã
ãŠãŒã¶ãŒæåã®å¥çŽãã¹ãïŒCDCãã¹ãïŒã«ãããæ¶è²»è ã¯å¥çŽã®å®è£ ã管çã§ããŸããæ¶è²»è ã¯CDCã䜿çšããŠãå¿ èŠãªãã¹ãŠã®ããŒã¿ã®ã€ã³ã¿ãŒãã§ã€ã¹ããã¹ããããã¹ããäœæããŸãããã®åŸãããŒã ã¯ãããã®ãã¹ããå ¬éããŠããã³ããŒãµãŒãã¹éçºè ããããã®ãã¹ããç°¡åã«ååŸããŠå®è¡ã§ããããã«ããŸããããã§ãCDCãã¹ããå®è¡ããŠAPIãéçºã§ããŸãããã¹ãŠã®ãã¹ããå®è¡ããåŸã圌ãã¯æ¶è²»è åŽã®ããŒã ã®ãã¹ãŠã®ããŒãºãæºãããŠããããšãç¥ã£ãŠããŸãã
å³ 9.å¥çŽãã¹ãã§ã¯ãã€ã³ã¿ãŒãã§ã€ã¹ã®ãµãã©ã€ã€ãšãã¹ãŠã®ã³ã³ã·ã¥ãŒããç¹å®ã®ã€ã³ã¿ãŒãã§ã€ã¹å¥çŽã«æºæ ããŠããããšã確èªããŸããã€ã³ã¿ãŒãã§ã€ã¹ã³ã³ã·ã¥ãŒãã¯ãCDCãã¹ãã䜿çšããŠãèŠä»¶ãèªåãã¹ãã®åœ¢åŒã§å ¬éããŸãããµãã©ã€ã€ãŒãç¶ç¶çã«ãããã®ãã¹ããåããå®è¡
ãã®ã¢ãããŒãã¯ãæ¬åœã«å¿ èŠãªãã®ã ããå®è£ ããããã®ã€ã³ã¿ãã§ãŒã¹ãããã€ãããŒã ïŒãããã·ã³ãã«ã«ä¿ã€ãããšãã§ããŸã YAGNIããããŠãã¹ãŠïŒããã³ããŒããŒã ã¯ãé倧ãªå€æŽãå³åº§ã«éç¥ããããã«ããããã®CDCãã¹ããïŒã¢ã»ã³ããªãã€ãã©ã€ã³ã§ïŒç¶ç¶çã«åä¿¡ããŠå®è¡ããå¿ èŠããããŸããã€ã³ã¿ãŒãã§ã€ã¹ã«éåãããšãCDCãã¹ãã倱æããé倧ãªå€æŽã劚ããããŸãããã¹ãã«åæ ŒãããšãããŒã ã¯ä»ã®ããŒã ãå¿é ããããšãªããå¿ èŠãªå€æŽãå ããããšãã§ããŸãã顧客å¿åã®å¥çŽã¢ãããŒãã«ãããéçºããã»ã¹ã¯æ¬¡ã®ããã«ççž®ãããŸãã
- æ¶è²»è ããŒã ã¯ãæ¶è²»è ããã®æåŸ ããã¹ãŠæºãããèªåãã¹ããäœæããŸãã
- ãµãã©ã€ã€ããŒã åãã«ãã¹ããå ¬éããŸãã
- ãã³ããŒããŒã ã¯ãCDCãã¹ããç¶ç¶çã«å®è¡ããã³ç£èŠããŸãã
- CDCãã¹ããäžæãããšãããŒã ã¯ããã«äº€æžããŸãã
çµç¹ã§ãã€ã¯ããµãŒãã¹ã¢ãããŒããå®è£ ããŠããå ŽåãCDCãã¹ããå®æœããããšã¯ãèªåŸã°ã«ãŒããäœæããããã®éèŠãªã¹ãããã§ãã CDCãã¹ãã¯ãããŒã ã¯ãŒã¯ãä¿é²ããèªååãããæ¹æ³ã§ããããŒã éã®ã€ã³ã¿ãŒãã§ãŒã¹ãåžžã«æ©èœããããã«ããŸãã倱æããCDCãã¹ãã¯ã圱é¿ãåããããŒã ã«è¡ããAPIã®ä»åŸã®å€æŽã«ã€ããŠè©±ãã次ã«ã©ãã«è¡ãã¹ãããèŠã€ããè¯ãçç±ã§ãã
CDCãã¹ãã®åçŽãªå®è£ ã¯ãAPIãèŠæ±ããå¿ èŠãªãã¹ãŠã®å¿çãè©äŸ¡ããã®ãšåããããç°¡åã§ãããããã®ãã¹ãã¯ãå®è¡å¯èœãã¡ã€ã«ïŒ.gemã.jarã.shïŒã«ããã±ãŒãžåãããå¥ã®ã³ãã³ãïŒããšãã°ãArtifactoryã®ãããªãªããžããªïŒã®ã©ããã«ããŠã³ããŒããããŸãã
è¿å¹ŽãCDCã¢ãããŒããããäžè¬çã«ãªãããã¹ãã®èšè¿°ãšå ±æãç°¡çŽ åããããã®ããã€ãã®ããŒã«ãäœæãããŸããã
åå®ã¯ãããããããã®äžã§æãæåã§ããã³ã³ã·ã¥ãŒããšãµãã©ã€ã€åãã«ãã¹ããèšè¿°ããããã®æŽç·Žãããã¢ãããŒããæäŸããåã ã®ãµãŒãã¹ã«ã¹ã¿ããæäŸããCDCãã¹ããä»ã®ããŒã ãšå ±æã§ããããã«ããŸãã Pactã¯å€ãã®ãã©ãããã©ãŒã ã«ç§»æ€ãããŠãããJVMãRubyã.NETãJavaScriptãããã³ä»ã®å€ãã®èšèªã§äœ¿çšã§ããŸãã
åå®ã¯ãCDCãå§ããããã®è³¢æãªéžæã§ããããã¥ã¡ã³ãã¯æåã¯é©ç°çã§ãããå¿èåãããã°ããããå æã§ããŸãã CDCã確å®ã«ç解ããã®ã«åœ¹ç«ã¡ãŸããããã«ãããä»ã®ããŒã ãšååããŠCDCãä¿é²ããããšã容æã«ãªããŸãã
ãŠãŒã¶ãŒæåã®å¥çŽãã¹ãã¯ãè¿ éãã€èªä¿¡ãæã£ãŠè¡åããèªåŸããŒã ã®äœæ¥ãåçã«ç°¡çŽ åã§ããŸãããé¡ãããŸãããã®ã³ã³ã»ããããã§ãã¯ããŠã¿ãŠãã ãããåªããCDCãã¹ãã»ããã¯ãä»ã®ãµãŒãã¹ãäžæãããä»ã®ããŒã ãæ··ä¹±ããããããããšãªããè¿ éã«éçºãç¶ç¶ããããã«éåžžã«è²Žéã§ãã
æ¶è²»è ãã¹ãïŒç§ãã¡ã®ããŒã ïŒ
åœç€Ÿã®ãã€ã¯ããµãŒãã¹ã¯å€©æ°APIã䜿çšããŠããŸãããããã£ãŠãç§ãã¡ã®è²¬ä»»ã¯ããã€ã¯ããµãŒãã¹ãšæ°è±¡ãµãŒãã¹éã®å¥çŽïŒAPIïŒã«å¯ŸããæåŸ ãå®çŸ©ããæ¶è²»è ãã¹ããæžãããšã§ãã
æåã«ãã³ã³ã·ã¥ãŒããŒãã¹ããèšè¿°ããããã®ã©ã€ãã©ãªãçµã¿èŸŒã¿
build.gradle
ãŸãã
testCompile('au.com.dius:pact-jvm-consumer-junit_2.11:3.5.5')
ãã®ã©ã€ãã©ãªã®ãããã§ãæ¶è²»è ãã¹ããå®è£ ããPactã·ãã¥ã¬ãŒã·ã§ã³ãµãŒãã¹ã䜿çšã§ããŸãã
@RunWith(SpringRunner.class) @SpringBootTest public class WeatherClientConsumerTest { @Autowired private WeatherClient weatherClient; @Rule public PactProviderRuleMk2 weatherProvider = new PactProviderRuleMk2("weather_provider", "localhost", 8089, this); @Pact(consumer="test_consumer") public RequestResponsePact createPact(PactDslWithProvider builder) throws IOException { return builder .given("weather forecast data") .uponReceiving("a request for a weather request for Hamburg") .path("/some-test-api-key/53.5511,9.9937") .method("GET") .willRespondWith() .status(200) .body(FileLoader.read("classpath:weatherApiResponse.json"), ContentType.APPLICATION_JSON) .toPact(); } @Test @PactVerification("weather_provider") public void shouldFetchWeatherInformation() throws Exception { Optional<WeatherResponse> weatherResponse = weatherClient.fetchWeather(); assertThat(weatherResponse.isPresent(), is(true)); assertThat(weatherResponse.get().getSummary(), is("Rain")); } }
ããèŠããšãã«
WeatherClientConsumerTest
éåžžã«ãã䌌ãŠã
WeatherClientIntegrationTest
ãŸããä»åã¯Wiremockã§ã¯ãªããµãŒããŒã¹ã¿ãã®ã¿ã«Pactã䜿çšããŸããæ¶è²»è ãã¹ãèªäœã§ã¯ãçµ±åãã¹ããšåãããã«æ©èœããŸããå®éã®ãµãŒãããŒãã£ãµãŒããŒãã¹ã¿ãã«çœ®ãæããäºæ³ãããå¿çã決å®ããã¯ã©ã€ã¢ã³ãããããæ£ãã解æã§ããããšã確èªããŸãããã®æå³ã§ããã
WeatherClientConsumerTest
ã¯çãçµ±åãã¹ãã§ãã WiremockããŒã¹ã®ãã¹ããããåªããŠããç¹ã¯ãPactãã¡ã€ã«ïŒ
target/pacts/&pact-name>.json
ïŒå¥çŽäžã®æåŸ ãç¹å¥ãªJSON圢åŒã§èšè¿°ããŠããŸãããã®ãã¡ã€ã«ã䜿çšããŠãã¹ã¿ããµãŒããŒãå®éã®ãµãŒããŒã®ããã«åäœããããšã確èªã§ããŸãã pactãã¡ã€ã«ãååŸããŠããããinterfaceã³ãã³ãã«æž¡ãããšãã§ããŸãã圌ãã¯åå®ãã¡ã€ã«ãåããããã§æå®ãããæåŸ å€ã䜿çšããŠãããã€ããŒãã¹ããäœæããŸãããã®ããã圌ãã¯èªåãã¡ã®APIããã¹ãŠã®æåŸ ãæºãããŠãããã©ããã確èªããŸãã
ã芧ã®ãšãããCDCå®çŸ©ã®ã顧客éèŠãã®éšåã¯ããããæ¥ãŠããŸããæ¶è²»è ã¯ãã€ã³ã¿ãŒãã§ãŒã¹ã®å®è£ ãå¶åŸ¡ããæåŸ ãèšè¿°ããŸãããµãã©ã€ã€ãŒã¯ããã¹ãŠã®æåŸ ãæºãããŠããããšã確èªããå¿ èŠããããŸããäžèŠãªä»æ§ã¯ãããŸãããYAGNIããã³ãã¹ãŠã®ãã®ã
ãã³ããŒãã¡ã€ã«ã«åå®ãã¡ã€ã«ãæž¡ãã«ã¯ãããã€ãã®æ¹æ³ããããŸããã·ã³ãã«-ããŒãžã§ã³ç®¡çã·ã¹ãã ã«ç»é²ããåžžã«ææ°ããŒãžã§ã³ã®ãã¡ã€ã«ãååŸãããããã³ããŒããŒã ã«äŒããŸããããé«åºŠãªæ¹æ³ã¯ãAmazon S3ãPact Brokerãªã©ã®ã¢ãŒãã£ãã¡ã¯ããªããžããªã䜿çšããããšã§ããã·ã³ãã«ã«å§ããŠãå¿ èŠã«å¿ããŠæé·ããŸãã
å®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãçµ±åãã¹ããšæ¶è²»è ãã¹ãã®äž¡æ¹ã¯å¿ èŠãããŸããã¯ã©ã€ã¢ã³ãã¯ã©ã¹çšããµã³ãã«ã³ãŒãã«ã¯ãããããã®äœ¿çšæ¹æ³ã瀺ãããã ãã«äž¡æ¹ãå«ãŸããŠããŸããPactã§CDCãã¹ããäœæããå Žåã¯ããã®ãŸãŸäœ¿çšããããšããå§ãããŸãããã®å Žåã®å©ç¹ã¯ãå¥çŽã®äºæ³ãèšèŒãããåå®ãã¡ã€ã«ãèªåçã«åãåãããšã§ããä»ã®ããŒã ã¯ããã䜿çšããŠããµãã©ã€ã€ãŒã®ãã¹ããç°¡åã«è¡ãããšãã§ããŸãããã¡ãããããã¯ãä»ã®ããŒã ã«Pactã䜿çšãããã説åŸã§ããå Žåã«ã®ã¿æå³ããããŸããããã§ãªãå Žåã¯ãé©åãªä»£æ¿æ段ãšããŠWiremockãšã®çµ±åãã¹ãçµ±åã䜿çšããŸãã
ãµãã©ã€ã€ãŒãã¹ãïŒå¥ã®ããŒã ïŒ
ãã³ããŒãã¹ãã¯ã倩æ°APIãæäŸãã人ãå®è£ ããå¿ èŠããããŸãã darksky.netã®ãããªãã¯APIã䜿çšããŸããçè«çã«ã¯ãdarkskyããŒã ã¯ããã³ããŒãã¹ããå®è¡ããã¢ããªã±ãŒã·ã§ã³ãšãµãŒãã¹éã®å¥çŽã«éåããªãããšã確èªããå¿ èŠããããŸãã
æããã«ã圌ãã¯ç§ãã¡ã®ãããããªãã¹ãã¢ããªã±ãŒã·ã§ã³ãæ°ã«ããŸãã-圌ãã¯ç§ãã¡ã®ããã«CDCãã¹ããè¡ããŸããããããªãã¯APIãšãã€ã¯ããµãŒãã¹ã䜿çšããçµç¹ãšã®éã«ã¯å€§ããªéãããããŸãããããªãã¯APIã¯ãåã ã®æ¶è²»è ã®ããŒãºãèæ ®ããããšãã§ããŸãããããããªããšãæ£åžžã«åäœã§ããªããªããŸããçµç¹å ã§ã¯ãããããèæ ®ããããšãã§ããèæ ®ããå¿ èŠããããŸããã»ãšãã©ã®å Žåãã¢ããªã±ãŒã·ã§ã³ã¯ããã€ãã®ãããããã¯æ°åã®æ¶è²»è ã«ãµãŒãã¹ãæäŸããŸããå®å®ããã·ã¹ãã ãç¶æããããã«ããããã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ãã³ããŒãã¹ããæžãããšã劚ãããã®ã¯äœããããŸããã
ãµãã©ã€ã€ããŒã ã¯åå®ãã¡ã€ã«ãåãåãããã®ãµãŒãã¹ã§å®è¡ããŸãããããè¡ãããã«ã圌女ã¯åå®ãã¡ã€ã«ãèªã¿åããããã€ãã®ã¹ã¿ããé 眮ããåå®ãã¡ã€ã«ã§å®çŸ©ãããæåŸ å€ããµãŒãã¹ã«ãã§ãã¯ãããã¹ããå®è£ ããŸãã
Pactãããžã§ã¯ãã³ãã¥ããã£ã¯ããã³ããŒãã¹ããå®è£ ããããã®ã©ã€ãã©ãªãããã€ãäœæããŸããã圌ãã®ã¡ã€ã³ãªããžããªã®GitHubã®å©çšè ãšæäŸã®ããã®ã©ã€ãã©ãªã®è¯ãéžæãæè¡ã¹ã¿ãã¯ã«æé©ãªãã®ãéžæããŠãã ããã
ç°¡åã«ããããã«ãdarksky APIãSpring Bootã«å®è£ ãããŠãããšããŸãããã®å Žåã圌ãã¯Springã®MockMVCã¡ã«ããºã ã«ããŸãæ¥ç¶ããPact Springã©ã€ãã©ãªã䜿çšã§ããŸãã darksky.netããŒã ãå®è£ ã§ããæ¶ç©ºã®ãã³ããŒãã¹ãã¯æ¬¡ã®ããã«ãªããŸãã
@RunWith(RestPactRunner.class) @Provider("weather_provider") // same as the "provider_name" in our clientConsumerTest @PactFolder("target/pacts") // tells pact where to load the pact files from public class WeatherProviderTest { @InjectMocks private ForecastController forecastController = new ForecastController(); @Mock private ForecastService forecastService; @TestTarget public final MockMvcTarget target = new MockMvcTarget(); @Before public void before() { initMocks(this); target.setControllers(forecastController); } @State("weather forecast data") // same as the "given()" in our clientConsumerTest public void weatherForecastData() { when(forecastService.fetchForecastFor(any(String.class), any(String.class))) .thenReturn(weatherForecast("Rain")); } }
ã芧ã®ãšããããµãã©ã€ã€ã¯åå®ãã¡ã€ã«ãããŠã³ããŒãããã ãã§ïŒããšãã°ã
@PactFolder
åãåã£ãåå®ãã¡ã€ã«ã®ããŠã³ããŒãå ã決å®ãïŒãäºåå®çŸ©ãããç¶æ ã®ãã¹ãããŒã¿ãæäŸããæ¹æ³ã決å®ã§ããŸãïŒããšãã°ãMockitoã·ãã¥ã¬ãŒã·ã§ã³ã䜿çšïŒãç¹å¥ãªãã¹ããæžãå¿ èŠã¯ãããŸããããã¹ãŠãåå®ãã¡ã€ã«ããååŸãããŸãããµãã©ã€ã€ãã¹ãã¯ããµãã©ã€ã€ã®ååãšã³ã³ã·ã¥ãŒããã¹ãã§å®£èšãããç¶æ ãšäžèŽããããšãéèŠã§ãã
ãµãã©ã€ã€ãŒãã¹ãïŒç§ãã¡ã®ããŒã ïŒ
ãµãŒãã¹ãšå€©æ°æ å ±ãããã€ããŒéã®å¥çŽããã¹ãããæ¹æ³ãæ€èšããŸããããã®ã€ã³ã¿ãŒãã§ãŒã¹ã§ã¯ãåœç€Ÿã®ãµãŒãã¹ã¯æ¶è²»è ãšããŠæ©èœããæ°è±¡ãµãŒãã¹ã¯äŸçµŠè ãšããŠæ©èœããŸããããã«èããŠã¿ããšãç§ãã¡ã®ãµãŒãã¹ã¯ä»ã®ãµãŒãã¹ã®ãããã€ããŒãšããŠãæ©èœããããšãããããŸããä»ã®ã³ã³ã·ã¥ãŒããŒåãã«è€æ°ã®ãšã³ããã€ã³ããåããREST APIãæäŸããŸãã
å¥çŽãã¹ãã®éèŠæ§ãç¥ã£ãŠããã®ã§ããã¡ãããã®å¥çŽã®ãã¹ããäœæããŸãã幞ããªããšã«ãç§ãã¡ã®å¥çŽã¯é¡§å®¢å¿åã§ããããããã¹ãŠã®æ¶è²»è ããŒã ãç§ãã¡ã«åå®ãã¡ã€ã«ãéä¿¡ããŸããããã䜿çšããŠãREST APIã®ãã³ããŒãã¹ããå®è£ ã§ããŸãã
æåã«ãSpringã®Pactãããã€ããŒã©ã€ãã©ãªããããžã§ã¯ãã«è¿œå ããŸãã
testCompile('au.com.dius:pact-jvm-provider-spring_2.12:3.5.5')
ãã³ããŒãã¹ãã®å®è£ ã¯ã説æãããã®ãšåããã¿ãŒã³ã«åŸããŸããç°¡åã«ããããã«ãåçŽãªã³ã³ã·ã¥ãŒããŒããã®åå®ãã¡ã€ã«ããµãŒãã¹ã®ãªããžããªãŒã«ç»é²ããŸããç§ãã¡ã®å Žåãããã¯ç°¡åã§ãããå®éã«ã¯ãããããããè€éãªã¡ã«ããºã ã䜿çšããŠåå®ãã¡ã€ã«ãé åžããå¿ èŠããããŸãã
@RunWith(RestPactRunner.class) @Provider("person_provider")// same as in the "provider_name" part in our pact file @PactFolder("target/pacts") // tells pact where to load the pact files from public class ExampleProviderTest { @Mock private PersonRepository personRepository; @Mock private WeatherClient weatherClient; private ExampleController exampleController; @TestTarget public final MockMvcTarget target = new MockMvcTarget(); @Before public void before() { initMocks(this); exampleController = new ExampleController(personRepository, weatherClient); target.setControllers(exampleController); } @State("person data") // same as the "given()" part in our consumer test public void personData() { Person peterPan = new Person("Peter", "Pan"); when(personRepository.findByLastName("Pan")).thenReturn(Optional.of (peterPan)); } }
衚瀺ãããŠããã®
ExampleProviderTest
ã¯ãåãåã£ãåå®ãã¡ã€ã«ã«å¿ããç¶æ ã§ããããã ãã§ãããã¹ããå®è¡ãããšãPactã¯pactãã¡ã€ã«ãååŸããæå®ãããç¶æ ã«åŸã£ãŠå¿çããHTTPèŠæ±ããµãŒãã¹ã«éä¿¡ããŸãã
UIãã¹ã
ã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯ãããçš®ã®ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ããããŸããéåžžãWebã¢ããªã±ãŒã·ã§ã³ã®ã³ã³ããã¹ãã§Webã€ã³ã¿ãŒãã§ã€ã¹ã«ã€ããŠèª¬æããŸãã REST APIãŸãã¯ã³ãã³ãã©ã€ã³ã€ã³ã¿ãŒãã§ãŒã¹ã掟æãªWebã€ã³ã¿ãŒãã§ãŒã¹ãšåãUIã§ããããšãå¿ããã¡ã§ãã
UIãã¹ãã¯ãã¢ããªã±ãŒã·ã§ã³ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®æ£ããåäœãæ€èšŒããŸãããŠãŒã¶ãŒã¢ã¯ã·ã§ã³ã¯é©åãªã€ãã³ããããªã¬ãŒããããŒã¿ã¯ãŠãŒã¶ãŒã«æ瀺ãããUIã®ç¶æ ã¯æåŸ ã©ããã«å€åããå¿ èŠããããŸãã
UIãã¹ããšãšã³ãããŒãšã³ããã¹ãã¯åããã®ã§ãããšèšãããããšããããŸãïŒMike Cohnãèšãããã«ïŒãç§ã«ãšã£ãŠãããã¯éåžžã«çŽäº€ããæŠå¿µãæã€2ã€ã®ããšã®èå¥ã§ãã
ã¯ããã¢ããªã±ãŒã·ã§ã³ãæåããæåŸãŸã§ãã¹ãããããšã¯ãå€ãã®å ŽåããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããããšãæå³ããŸãããããããã®éã¯çå®ã§ã¯ãããŸããã
ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®ãã¹ãã¯ããšã³ãããŒãšã³ãã§ããå¿ èŠã¯ãããŸããã䜿çšãããŠãããã¯ãããžãŒã«ãã£ãŠã¯ãUIãã¹ãã¯ããã¥ãŒããããããã¯ãšã³ããåããJavaScriptããã³ããšã³ãã®åäœãã¹ããäœæããã®ãšåããããç°¡åãªå ŽåããããŸããSelenium
ãªã©ã®ç¹å¥ãªããŒã«ã¯ãåŸæ¥ã®Webã¢ããªã±ãŒã·ã§ã³ã®UIããã¹ãããããã«èšèšãããŠããŸããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãREST APIã§ãããšæãããå Žåã¯ãAPIã«é¢ããé©åãªçµ±åãã¹ãã§ååã§ãã
Webã€ã³ã¿ãŒãã§ãŒã¹ã§ã¯ãåäœãã¬ã€ã¢ãŠãã䜿ãããããäŒæ¥IDã³ã³ãã©ã€ã¢ã³ã¹ãªã©ãUIã®ããã€ãã®åŽé¢ããã¹ãããããšãæãŸããã§ãã
幞ããªããšã«ãUIã®åäœã®ãã¹ãã¯éåžžã«ç°¡åã§ãããããã¯ãªãã¯ããŠãããã«ããŒã¿ãå ¥åããUIã®ç¶æ ãããã«å¿ããŠå€åããããšã確èªããŠãã ãããåäžããŒãžã¢ããªã±ãŒã·ã§ã³çšã®ææ°ã®ãã¬ãŒã ã¯ãŒã¯ïŒreactãvue.jsãAngularãã®ä»ïŒããããã®çžäºäœçšãããªãäœãã¬ãã«ïŒãŠããããã¹ãïŒã§åŸ¹åºçã«ãã¹ãããããã®ããŒã«ãšãã«ããŒãä»å±ããŠããããšããããããŸããç¬èªã®ããã³ããšã³ãå®è£ ãããã©JavaScriptã§å±éããå Žåã§ããJasmineãMochaãªã©ã®éåžžã®ãã¹ãããŒã«ã䜿çšã§ããŸããããäŒçµ±çãªãµãŒããŒãµã€ãã¬ã³ããªã³ã°ã¢ããªã±ãŒã·ã§ã³ã®å ŽåãSeleniumããŒã¹ã®ãã¹ããæè¯ã®éžæã§ããWebã¢ããªã±ãŒã·ã§ã³ã¬ã€ã¢ãŠã
ã®æŽåæ§ã確èªããã®ã¯ããå°ãå°é£ã§ããã¢ããªã±ãŒã·ã§ã³ãšãŠãŒã¶ãŒã®ããŒãºã«ãã£ãŠã¯ãã³ãŒãã®å€æŽã誀ã£ãŠãµã€ãã®ã¬ã€ã¢ãŠãã«éåããªãããã«ããå¿ èŠããããŸãã
ããããã³ã³ãã¥ãŒã¿ãŒã¯ããã¹ãŠããæ£åžžã«èŠãããããšãæ€èšŒããã®ã«è²§åŒ±ãªä»äºãããŸãïŒãããããããã€ãã®ã¹ããŒãæ©æ¢°åŠç¿ã¢ã«ãŽãªãºã ã¯å°æ¥ãããå€æŽããã§ãããïŒã
ã¢ã»ã³ããªãã€ãã©ã€ã³ã§Webã¢ããªã±ãŒã·ã§ã³ã®èšèšãèªåçã«ãã§ãã¯ããããšããããŒã«ãããã€ããããŸãããããã®ã»ãšãã©ã¯Seleniumã䜿çšããŠãããŸããŸãªãã©ãŠã¶ãŒãšåœ¢åŒã§Webã¢ããªã±ãŒã·ã§ã³ãéããã¹ã¯ãªãŒã³ã·ã§ãããæ®ãã以åã®ã¹ã¯ãªãŒã³ã·ã§ãããšæ¯èŒããŸããå€ãã¹ã¯ãªãŒã³ã·ã§ãããšæ°ããã¹ã¯ãªãŒã³ã·ã§ãããäºæããç°ãªãå ŽåãããŒã«ã¯ã·ã°ãã«ãåºããŸãã
ãã®ãããªããŒã«ã®1ã€ãGalenã§ããäžéšã®ããŒã ã¯ãã©ã€ã³ããããšåœŒã®å åŒã®JavaããŒã¹ã®jlineupã䜿çšããŠåæ§ã®çµæãéæããŠããŸããã©ã¡ãã®ããŒã«ãåãSeleniumããŒã¹ã®ã¢ãããŒãã䜿çšããŸãã
ãŠãŒã¶ããªãã£ãšåªãããã¶ã€ã³ããã¹ãããããšããã«-èªåãã¹ãã®ã¹ããŒã¹ãé¢ããŸããããã§ã¯ãç 究ãã¹ãããŠãŒã¶ããªãã£ãã¹ãïŒã©ã³ãã ãªäººã«å¯ŸããæãåçŽãªããŒã«ãã¹ããŸã§ïŒã«äŸåããå¿ èŠããããŸãããŠãŒã¶ãŒã¯ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ãè¡ãã補åã奜ããã©ããããã©ã¹ãã¬ãŒã·ã§ã³ãè¿·æãªããã¹ãŠã®æ©èœã䜿çšã§ãããã©ããã確èªããå¿ èŠããããŸãã
ãšã³ãããŒãšã³ãã®ãã¹ã
UIãä»ãããããã€æžã¿ã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãã¯ãå®è¡å¯èœãªæãå æ¬çãªãã¹ãã§ããWebDriverãä»ããäžèšã®UIãã¹ãã¯ããšã³ãããŒãšã³ããã¹ãã®è¯ãäŸã§ãã
å³ 11.çµ±åã·ã¹ãã å šäœããã¹ããã
ãšã³ãããŒãšã³ããã¹ãïŒãšã³ãããŒãšã³ããã¹ãïŒã¯ã€ãã¹ã¿ãã¯ãã¹ããšãåŒã°ããŸãïŒã¯ããœãããŠã§ã¢ãæ©èœãããã©ãããæ倧éã«ä¿èšŒããŸãã Seleniumãš WebDriverãããã³ã«ã䜿çšãããšããããã¬ã¹ãã©ãŠã¶ãŒããããã€æžã¿ãµãŒãã¹ã«èªåçã«éä¿¡ããŠã¯ãªãã¯ãå®è¡ããããŒã¿ãå ¥åããUIã®ã¹ããŒã¿ã¹ã確èªããããšã§ããã¹ããèªååã§ããŸãã SeleniumãçŽæ¥äœ¿çšããããSeleniumã«åºã¥ãã Nightwatchãªã©ã®ããŒã«ã䜿çšã§ããŸãã
ãšã³ãããŒãšã³ãã®ãã¹ãã«ã¯ä»ã®åé¡ããããŸãããããã¯ããã®äžå®å®ããäºæãã¬äºæããªãçç±ã«ãã倱æã§ç¥ãããŠããŸããå€ãã®å Žåããããã¯èª€æ€ç¥ã®å€±æã§ãã UIãè€éã«ãªãã»ã©ããã¹ãã¯è匱ã«ãªããŸãããã©ãŠã¶ã®çãã¿ã€ãã³ã°ã®åé¡ãã¢ãã¡ãŒã·ã§ã³ãäºæããªããããã¢ããã¯ãç§ãæã£ãŠããããããããã°ã«å€ãã®æéãè²»ãããçç±ã®ã»ãã®äžéšã§ãã
ãã€ã¯ããµãŒãã¹ã®äžçã§ã¯ã誰ããããã®ãã¹ããæžã責任ãããã®ãââãäžæã§ãããããã¯ããã€ãã®ãµãŒãã¹ïŒã·ã¹ãã å šäœïŒã察象ãšããŠããããããšã³ãããŒãšã³ãã®ãã¹ããäœæããç¹å®ã®ããŒã ã¯ãããŸããã
äžå åãããå質ä¿èšŒããŒã ãããå Žå圌ãã¯è¯ãåè£ã®ããã«èŠããŸããç¹°ãè¿ããŸãããäžå åãããQAããŒã ãéå§ããããšã¯å³å¯ã«ã¯æšå¥šãããŸãããããã¯ããã¹ãŠã®ããŒã ãçã«æ®éçãªDevOpsã®äžçã§ã¯ãããŸããã誰ããšã³ãããŒãšã³ãã®ãã¹ããææããå¿ èŠããããã«ã€ããŠã®ç°¡åãªçãã¯ãããŸãããããªãã®çµç¹ã«ã¯ããããã管çããããã®äœããã®ã€ãã·ã¢ããã°ã«ãŒããŸãã¯è³ªã®é«ãã®ã«ãããããããããŸãããå€ãã¯ç¹å®ã®çµç¹ã«äŸåããŸãã
ããã«ããšã³ãããŒãšã³ãã®ãã¹ãã«ã¯æ·±å»ãªãµããŒããå¿ èŠã§ãããããªãé ãã§ããå€ãã®ãã€ã¯ããµãŒãã¹ãããå Žåããã¹ãŠã®ãã€ã¯ããµãŒãã¹ãããŒã«ã«ã§å®è¡ããå¿ èŠãããããããšã³ãããŒãšã³ãã®ãã¹ããããŒã«ã«ã§å®è¡ããããšããã§ããŸãããã³ã³ãã¥ãŒã¿ãŒã§äœçŸãã®ã¢ããªã±ãŒã·ã§ã³ãå®è¡ããŠã¿ãŠãã ãããååãªRAMããããŸããã
ã¡ã³ããã³ã¹ã³ã¹ããé«ãããããšã³ãããŒãšã³ããã¹ãã®æ°ã¯æå°éã«æããå¿ èŠããããŸãã
ã¢ããªã±ãŒã·ã§ã³ãšã®æãéèŠãªãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ã«ã€ããŠèããŸãããšã³ãããŒãšã³ãã®ãã¹ãã§ãããã®æé ã®æãéèŠãªæé ãèªååããããã«ãç»é¢ããç»é¢ãžã®ãŠãŒã¶ãŒã®äž»ãªãã«ãŒãããèããŠãã ããã
ããªãããªã³ã©ã€ã³ã¹ãã¢ãããŠããå Žåãæã䟡å€ã®ãããã«ãŒããã¯è£œåãæ€çŽ¢ããããšã§ã-ãã¹ã±ããã«å ¥ããŠ-泚æããŸãã以äžã§ãããã®ã«ãŒããæ©èœããéããç¹ã«åé¡ã¯ãããŸããããšã³ãããŒãšã³ãã®ãã¹ãã®ããã«ãããã«éèŠãªã«ãŒããããã€ãèŠã€ãããããããŸãããä»ã®ãã¹ãŠã¯ãè¯ããããå€ãã®åé¡ãããããå¯èœæ§ããããŸãã
èŠããŠãããŠãã ããããã¹ããã©ãããã«ã¯å€ãã®äœã¬ãã«ã®ãã¹ãããããå¢çç¶æ³ãã·ã¹ãã ã®ä»ã®éšåãšã®çµ±åã«é¢ãããã¹ãŠã®ãªãã·ã§ã³ãæ¢ã«ãã¹ãããŠããŸãããããã®ãã¹ããããé«ãã¬ãã«ã§ç¹°ãè¿ãå¿ èŠã¯ãããŸãããå€å€§ãªä¿å®äœæ¥ãšå€ãã®èª€æ€ç¥ã«ãããäœæ¥ãéåžžã«é ããªããé ããæ©ããããã¹ãã«å¯Ÿããèªä¿¡ããŸã£ãã倱ãããŸãã
ãšã³ãããŒãšã³ãUIãã¹ã
ãšã³ãããŒãšã³ãã®ãã¹ãã§ã¯ãå€ãã®éçºè ãSeleniumãšWebDriverãããã³ã«ãéžæããŸãã Seleniumã䜿çšãããšãä»»æã®ãã©ãŠã¶ãŒãéžæããŠãµã€ãã«èšå®ã§ããŸããã©ãã§ããã¿ã³ãšãªã³ã¯ãæŒããŠãããŒã¿ãå ¥åããUIã§å€æŽã確èªããŸãã
Seleniumã«ã¯ãå®è¡ããŠãã¹ãã«äœ¿çšã§ãããã©ãŠã¶ãŒãå¿ èŠã§ããããŸããŸãªãã©ãŠã¶ãŒçšã®ããããããã©ã€ããŒããããã€ããããŸãã 1ã€ïŒãŸãã¯è€æ°ïŒãéžæããŠããããyoursã«è¿œå ããŸã
build.gradle
ãã©ã®ãã©ãŠã¶ãéžæããå Žåã§ãããã¹ãŠã®éçºè ãšCIãµãŒããŒã«æ£ãããã©ãŠã¶ããŒãžã§ã³ãã€ã³ã¹ããŒã«ãããŠããããšã確èªããå¿ èŠããããŸãããã®ãããªåæã確ä¿ããã®ã¯é£ããå ŽåããããŸããJavaçšã®å°ããªwebdrivermanagerã©ã€ãã©ãªããããŸãããã©ãŠã¶ã®æ£ããããŒãžã§ã³ã®ããŠã³ããŒããšèšå®ãèªååããŸãã次ã®ãããªäŸåé¢ä¿ã2ã€è¿œå ã
build.gradle
ãŸãã
testCompile('org.seleniumhq.selenium:selenium-chrome-driver:2.53.1') testCompile('io.github.bonigarcia:webdrivermanager:1.7.2')
ãã¹ãã¹ã€ãŒãã§ãã«ãã©ãŠã¶ãå®è¡ããããšã¯åé¡ã«ãªãå¯èœæ§ããããŸããç¹ã«ããã€ãã©ã€ã³ãå®è¡ãããŠããé£ç¶é ä¿¡ãµãŒããŒãUIã䜿çšããŠãã©ãŠã¶ãŒãå±éã§ããªãå ŽåïŒããšãã°ãXãµãŒããŒãå©çšã§ããªãããïŒããã®å Žåãxvfbã®ãããªä»®æ³X-Serverãå®è¡ã§ããŸãã
æ°ããã¢ãããŒãã¯ãWebDriverãã¹ãã«ãããã¬ã¹ãã©ãŠã¶ãŒïŒã€ãŸãããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®ãªããã©ãŠã¶ãŒïŒã䜿çšããããšã§ããæè¿ãŸã§ãPhantomJSã¯ãã©ãŠã¶ãŒã¿ã¹ã¯ã®èªååã«æããã䜿çšãããŠããŸãããããããChromiumãšFirefoxãã®ãŸãŸãããã¬ã¹ã¢ãŒããå®è£ ãããšãPhantomJSã¯çªç¶æ代é ãã«ãªããŸããæçµçã«ããŠãŒã¶ãŒãå®éã«äœ¿çšããŠããå®éã®ãã©ãŠã¶ãŒïŒFirefoxãChromeãªã©ïŒã䜿çšããŠãµã€ãããã¹ãããéçºè ãšããŠäŸ¿å©ã ãããšãã£ãŠäººå·¥çãªãã©ãŠã¶ãŒã䜿çšããªãæ¹ãããã§ãããã
FirefoxãšChromeã®ãããã¬ã¹ãã©ãŠã¶ãŒã¯ã©ã¡ããæ°åã§ãããWebDriverãã¹ãã«ã¯ãŸã åºã䜿çšãããŠããŸãããäœãè€éã«ããããããŸãããæ°é®®ãªãããã¬ã¹ã¢ãŒãã«ç ©ããããã®ã§ã¯ãªããåŸæ¥ã®æ¹æ³ãã€ãŸãéåžžã®ãã©ãŠã¶ãšçµã¿åãããSeleniumã«åºå·ããŸãããã Chromeãèµ·åããŠãµãŒãã¹ã«ã¢ã¯ã»ã¹ãããµã€ãã®ã³ã³ãã³ãããã§ãã¯ããç°¡åãªãšã³ãããŒãšã³ãã®ãã¹ãã¯æ¬¡ã®ãšããã§ãã
@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class HelloE2ESeleniumTest { private WebDriver driver; @LocalServerPort private int port; @BeforeClass public static void setUpClass() throws Exception { ChromeDriverManager.getInstance().setup(); } @Before public void setUp() throws Exception { driver = new ChromeDriver(); } @After public void tearDown() { driver.close(); } @Test public void helloPageHasTextHelloWorld() { driver.get(String.format("http://127.0.0.1:%s/hello", port)); assertThat(driver.findElement(By.tagName("body")).getText(), containsString("Hello World!")); } }
ãã®ãã¹ãã¯ããã¹ããå®è¡ãããŠãããã·ã³ïŒããŒã«ã«ã³ã³ãã¥ãŒã¿ãŒãCIãµãŒããŒïŒã«Chromeãã€ã³ã¹ããŒã«ãããŠããå Žåã«ã®ã¿æ©èœããããšã«æ³šæããŠãã ããã
ãã¹ãã¯ç°¡åã§ããã䜿çšããŠãã©ã³ãã ããŒãã§Springã¢ããªã±ãŒã·ã§ã³ãå®è¡ã
@SpringBootTest
ãŸãã次ã«ãChromeã®æ°ãããWebãã©ã€ããŒããäœæããã
/hello
ãã€ã¯ããµãŒãã¹ã®ãšã³ããã€ã³ãã«ç§»åããŠããã©ãŠã¶ãŒãŠã£ã³ããŠã«ãHello WorldïŒããå°å·ãããŠããããšã確èªããããã«æ瀺ãããŸãããããïŒ
REST APIãã¹ã¹ã«ãŒãã¹ã
ãã¹ãã®ä¿¡é Œæ§ãé«ããã«ã¯ãGUIã䜿çšããªãããšããå§ãããŸãããã®ãããªãã¹ãã¯ãå®å šãªãšã³ãããŒãšã³ããã¹ããããå®å®ããŠãããåæã«ã¢ããªã±ãŒã·ã§ã³ã¹ã¿ãã¯ã®å€§éšåãã«ããŒããŸããããã¯ãWebã€ã³ã¿ãŒãã§ãŒã¹ãä»ããã¢ããªã±ãŒã·ã§ã³ã®ãã¹ããç¹ã«é£ããå Žåã«äŸ¿å©ã§ãããŠã§ãã€ã³ã¿ãŒãã§ãŒã¹ããæã£ãŠããªããããããŸããããREST APIã ãããããŸãïŒ1ããŒãžã®ã¢ããªã±ãŒã·ã§ã³ãã©ããã§ãã®APIãšéä¿¡ããããããŸãã¯åã«ãã¹ãŠãçŸãããŠçŽ æŽããããšè»œbecauseããããïŒããããã«ããããã®ç¶æ³ã¯ãGUIã®äžã§ãã¹ãŠããã¹ãããç®äžãã¹ãã«é©ããŠããŸãã REST APIãæäŸããå Žåããã®ãããªãã¹ãã¯æ£ããäŸã«ãªããŸããäŸïŒ
@RestController public class ExampleController { private final PersonRepository personRepository; // shortened for clarity @GetMapping("/hello/{lastName}") public String hello(@PathVariable final String lastName) { Optional<Person> foundPerson = personRepository.findByLastName(lastName); return foundPerson .map(person -> String.format("Hello %s %s!", person.getFirstName(), person.getLastName())) .orElse(String.format("Who is this '%s' you're talking about?", lastName)); } }
REST APIãæäŸãããµãŒãã¹ããã¹ããããšãã«äŸ¿å©ãªå¥ã®ã©ã€ãã©ãªã玹ä»ããŸããRESTä¿èšŒã©ã€ãã©ãªã¯ãå®éã®HTTP APIèŠæ±ãå®è¡ããåä¿¡ããå¿çãè©äŸ¡ããããã®åªããDSLãæäŸããŸãã
ãŸããäŸåé¢ä¿ãyoursã«è¿œå ããŸã
build.gradle
ã
testCompile('io.rest-assured:rest-assured:3.0.3')
ãã®ã©ã€ãã©ãªã䜿çšããŠãREST APIã®ãšã³ãããŒãšã³ããã¹ããå®è£ ã§ããŸãã
@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class HelloE2ERestTest { @Autowired private PersonRepository personRepository; @LocalServerPort private int port; @After public void tearDown() throws Exception { personRepository.deleteAll(); } @Test public void shouldReturnGreeting() throws Exception { Person peter = new Person("Peter", "Pan"); personRepository.save(peter); when() .get(String.format("http://localhost:%s/hello/Pan", port)) .then() .statusCode(is(200)) .body(containsString("Hello Peter Pan!")); } }
Springã¢ããªã±ãŒã·ã§ã³å šäœãã§å床起åã
@SpringBootTest
ãŸãããã®å ŽåãããŒã¿ããŒã¹ã«ãã¹ãããŒã¿
@Autowire
ã
PersonRepository
ç°¡åã«èšé²ã§ããããã«ããŸããããã§ãREST APIã«å人ããã¹ã¿ãŒãã³ãã«ãããã«ã¡ã¯ããšèšãããã«äŸé Œãããšã楜ããæšæ¶ã衚瀺ãããŸãããããïŒ ãŸããWebã€ã³ã¿ãŒãã§ãŒã¹ããŸã£ãããªãå Žåããšã³ãããŒãšã³ãã®ãã¹ãã«ã¯ååã§ãã
åãå ¥ããã¹ã-æ©èœã¯æ£ããæ©èœããŸããïŒ
ãã¹ããã©ãããã®äžäœã«è¡ãã»ã©ã質åãããå¯èœæ§ãé«ããªããŸããæ©èœã¯ãŠãŒã¶ãŒã®èŠ³ç¹ããã¯æ£ããæ©èœããŸãããã¢ããªã±ãŒã·ã§ã³ããã©ãã¯ããã¯ã¹ãšèŠãªãããã¹ãã®æ¹åãéå»ããå€æŽã§ããŸãã
xãšyãå ¥åãããšãæ»ãå€ã¯zã«ãªããŸã
以äžã«ïŒ
äžããããæš©éã®ãããŠãŒã¶ãŒãããããš
ãšããèªè»¢è»ãã®è£œåãæã£ãŠãã補å説æããŒãžãèªè»¢è»ããžã®ãŠãŒã¶ãŒã®ããã²ãŒããšæŒããã¿ã³ã¯ããã«ãŒãã«å ¥ããããããŠè£œåãèªè»¢è»ã¯ãã圌ã®ã¯ã¬ãŒãã«ããããã«
ãã®ãããªãã¹ãã¯ãæ©èœãã¹ããŸãã¯åãå ¥ããã¹ããšåŒã°ããŸããæ©èœãã¹ããšåãå ¥ããã¹ãã¯2ã€ã®ç°ãªããã®ã§ãããšèšã人ãããŸããçšèªãçµã¿åããããããšããããŸããæã ã人ã ã¯èšèé£ããšå®çŸ©ã«ã€ããŠå»¶ã ãšäž»åŒµããŸããå€ãã®å Žåããã®ãããªè°è«ã¯ããã«æ··ä¹±ãæããŸãã
ãã®çç±ã¯æ¬¡ã®ãšããã§ããããæç¹ã§ãæè¡çãªèŠ³ç¹ã ãã§ãªãããŠãŒã¶ãŒã®èŠ³ç¹ããããã°ã©ã ãæ£ããåäœããããšã確èªããå¿ èŠããããŸãããããã®ãã¹ããšåŒã¶ãã®ã¯ãããã»ã©éèŠã§ã¯ãããŸããããããããããã®ãã¹ãã®ååšã¯éèŠã§ããä»»æã®çšèªãéžæããããã«åºå·ããŠããããã®ãã¹ããèšè¿°ããŸãã
ãŸããBDDïŒåäœã®èª¬æã«åºã¥ããéçºïŒãšãã®ããã®ããŒã«ã«èšåããããšãã§ããŸãã BDDãšé©åãªã¹ã¿ã€ã«ã®ãã¹ããæžãããšã¯ãå®è£ ã®è©³çŽ°ãããŠãŒã¶ãŒã®ããŒãºã«ããªãã®æèãå€ããè¯ãããªãã¯ã§ããæããŠè©Šããªãã§ãã ãããCucumber
ãªã©ã®æ¬æ ŒçãªBDDããŒã«ãå®è£ ããå¿ èŠã¯ãããŸããïŒå®è£ ã§ããŸããïŒãchai.jsã®ãããªäžéšã®ã¢ãµãŒã·ã§ã³ã©ã€ãã©ãªã䜿çšãããšããã¹ããBDDã«è¿ã¥ããã¹ã¿ã€ã«ããŒã¯ãŒãã䜿çšããŠã¢ãµãŒã·ã§ã³ãèšè¿°ã§ããŸãããŸãããã®ãããªè¡šèšæ³ãæäŸããã©ã€ãã©ãªã䜿çšããªããŠããã¹ããŒãã§é©åã«èšèšãããã³ãŒãã«ããããŠãŒã¶ãŒã®è¡åã«çŠç¹ãåœãŠããã¹ããäœæã§ããŸããäžéšã®ãã«ããŒã¡ãœãã/é¢æ°ã¯éåžžã«æåããå¯èœæ§ããããŸãã
should
# a sample acceptance test in Python def test_add_to_basket(): # given user = a_user_with_empty_basket() user.login() bicycle = article(name="bicycle", price=100) # when article_page.add_to_.basket(bicycle) # then assert user.basket.contains(bicycle)
åãå ¥ããã¹ãã¯ãããŸããŸãªè©³çŽ°ã¬ãã«ã§å®è¡ã§ããŸããåºæ¬çã«ããããã¯ååã«é«ãã¬ãã«ã§ãããUIãä»ããŠãµãŒãã¹ããã¹ãããŸãããããããã¹ããã©ãããã®æé«ã¬ãã«ã§åãå ¥ããã¹ããèšè¿°ããããã®å¿ é èŠä»¶ã¯æè¡çã«ãªãããšãç解ããããšãéèŠã§ããã¢ããªã±ãŒã·ã§ã³æ§é ãšæ¢åã®ã¹ã¯ãªããã§ãããäœãã¬ãã«ã§åãå ¥ããã¹ããäœæã§ããå Žåã¯ãå®è¡ããŠãã ãããäœãã¹ãã®æ¹ãé«ãã¹ããããåªããŠããŸããåãå ¥ããã¹ãã®æŠå¿µã¯ãã¢ããªã±ãŒã·ã§ã³ã®æ©èœããŠãŒã¶ãŒã«ãšã£ãŠæ£ããæ©èœããããšã蚌æããããã«ããã¹ããã©ããããšå®å šã«çŽäº€ããŠããŸãã
ç 究ãã¹ã
ãã¹ããèªååããããã®æãå€åãªåªåã§ããçæ³çã§ã¯ãããŸãããèªåãã¹ãã§ã¯ãç¹å®ã®å¢çç·ã®ã±ãŒã¹ãã¹ãããããå ŽåããããŸããåäœãã¹ããæžãããšã§ç¹å®ã®ãšã©ãŒãæ€åºããããšãåã«äžå¯èœãªå ŽåããããŸããäžéšã®å質åé¡ã¯ãèªååããããã¹ãã§ã¯ãŸã£ãã衚瀺ãããŸããïŒèšèšãŸãã¯äœ¿ããããã«ã€ããŠèããŠãã ããïŒããã¹ãã®èªååã«é¢ããæåã®æå³ã«ãããããããæåãã¹ãã¯ããã€ãã®ç¹ã§äŸç¶ãšããŠããããã®ãªããã®ã§ãã
å³ 12.ç 究ãã¹ãã§ã¯ãã¢ã»ã³ããªããã»ã¹äžã«æ°ä»ããªãå質ã®åé¡ãç¹å® ãããã¹ãã¹ã€ãŒãã«ç 究ãã¹ãã
å«ããŸãããã®æåãã¹ãæé ã¯ãäœæ¥ã·ã¹ãã ã®å質åé¡ãçºèŠã§ãããã¹ã¿ãŒã®èªç±ãšåµé æ§ã匷調ããŠããŸããã¹ã±ãžã¥ãŒã«ã«å°ãæéããããŠãè¢ããŸãããã¢ããªã±ãŒã·ã§ã³ãäœããã®æ¹æ³ã§ã¯ã©ãã·ã¥ãããŠãã ãããç Žå£çæèãæå¹ã«ããŠãããã°ã©ã ã®åé¡ããšã©ãŒãåŒãèµ·ããæ¹æ³ãèããŠãã ãããèŠã€ãããã®ããã¹ãŠææžåããŸãããã°ãèšèšäžã®åé¡ãé ãå¿çæéãæ¬ èœãŸãã¯èª€è§£ãæããšã©ãŒã¡ãã»ãŒãžãããã³ãŠãŒã¶ãŒãšããŠããªããå°ãããä»ã®ãã®ãæ¢ããŸãã
è¯ããã¥ãŒã¹ã¯ãèŠã€ãã£ãã»ãšãã©ã®ãšã©ãŒã®ãã¹ããç°¡åã«èªååã§ããããšã§ããèŠã€ãã£ããšã©ãŒã®èªåãã¹ããäœæããããšã«ãããå°æ¥ãã®ãšã©ãŒã®ãªã°ã¬ãã·ã§ã³ãçºçããªãããšãä¿èšŒãããŸããããã«ããã°ãä¿®æ£ããéã«åé¡ã®æ ¹æ¬åå ãèŠã€ããã®ã«åœ¹ç«ã¡ãŸãã
æ¢çŽ¢çãã¹ãäžã«ãã¢ã»ã³ããªãã€ãã©ã€ã³ãéãã«ããæããåé¡ãèŠã€ãããŸãããã£ããããªãã§ãã ãããããã¯ãã¢ã»ã³ããªãã€ãã©ã€ã³ãæ¹åããããã®è¯ããã£ãŒãããã¯ã§ããä»ã®ãã£ãŒãããã¯ãšåæ§ã«ãããªãã®åŽã§å¿ ãåå¿ããŠãã ããããã®çš®ã®åé¡ãå°æ¥åé¿ããããã«ã©ã®ãããªè¡åãåãã¹ãããèããŠãã ããããã¶ããããªãã¯èªåãã¹ãã®ç¹å®ã®ã»ãããèŠéãããããããŸããããã®æç¹ã§èªååããããã¹ãã«ã ããããªãã£ãå¯èœæ§ããããä»åŸããã«åŸ¹åºçã«ãã¹ããããã¯ãã§ããããããããã€ãã©ã€ã³ã§ãã®ãããªåé¡ãåé¿ããããã«äœ¿çšã§ãããããçš®ã®çŽ æŽãããæ°ããããŒã«ãŸãã¯ã¢ãããŒãããããŸããã³ã³ãã¢ãšãœãããŠã§ã¢é ä¿¡ã·ã¹ãã å šäœãåã¹ãããã§æ¹åããæ¹åãããããã«ãå¿ ãåå¿ããŠãã ããã
ãã¹ãã®çšèªãšã®æ··å
ãã¹ãã®ããŸããŸãªåé¡ã«ã€ããŠè©±ãããšã¯åžžã«å°é£ã§ããåäœãã¹ãïŒåäœãã¹ãïŒã«ã€ããŠã®ç§ã®ç解ã¯ãããªãã®ãã®ãšã¯å°ãç°ãªããããããŸãããçµ±åãã¹ãã¯ããã«æªãã§ããäžéšã®äººã ã«ãšã£ãŠãçµ±åãã¹ãã¯ã·ã¹ãã å šäœã®ããŸããŸãªéšåããã¹ãããéåžžã«åºç¯ãªæŽ»åã§ããç§ã«ãšã£ãŠãããã¯ããªãçããã®ã§ããäžåºŠã«1ã€ã®å€éšããŒããšã®çµ±åã®ã¿ããã¹ãããŸãããã®çµ±åãã¹ããåŒã³åºããã®ãã³ã³ããŒãã³ããã¹ããåŒã³åºããã®ããµãŒãã¹ãã¹ããšããçšèªã奜ããã®ããããŸãã誰ãããããã¯äžè¬ã«3ã€ã®å®å šã«ç°ãªããã®ã ãšèšãã§ããããæ£ããå®çŸ©ãééã£ãå®çŸ©ã¯ãããŸããããœãããŠã§ã¢éçºè ã®ã³ââãã¥ããã£ã¯ããã¹ãã§æ確ã«å®çŸ©ãããçšèªã確ç«ããªãã£ãã ãã§ãã
ãããŸããªçšèªã«ãã ãããªãã§ãã ããããšã³ãããŒãšã³ããã¹ããã¯ã€ãã¹ã¿ãã¯ãã¹ãããŸãã¯æ©èœãã¹ããšåŒãã§ãããŸããŸãããçµ±åãã¹ãã®æå³ãä»ã®äŒç€Ÿã®äººãšç°ãªãå Žåã¯é¢ä¿ãããŸãããã¯ããç§ãã¡ã®æ¥çãçšèªãæ確ã«å®çŸ©ã§ãããã¹ãŠãããããé å®ã§ããã°éåžžã«è¯ãã§ããããæ®å¿µãªãããããã¯ãŸã èµ·ãã£ãŠããŸããããŸãããã¹ãã«ã¯å€ãã®åŸ®åŠãªéãããããããäžé£ã®åå¥ã®ã»ãããããå¹ åºããã¹ããæ±ãããšã«ãªããæ確ãªçšèªãããã«è€éã«ãªããŸãã
ãã®ããã«ããããšãéèŠã§ããããªããšããªãã®ããŒã ã«åœ¹ç«ã€çšèªãèŠã€ããã ãã§ããèšè¿°ãããããŸããŸãªã¿ã€ãã®ãã¹ããæ確ã«å®çŸ©ããŠãã ãããããŒã ã®æ¡ä»¶ã«åæããåã¿ã€ãã®ãã¹ãã®ç¯å²ã«é¢ããã³ã³ã»ã³ãµã¹ãèŠã€ããŸããããŒã å ïŒãŸãã¯çµç¹å šäœïŒã§ãããã®çšèªã«äžè²«ããŠããå Žåã¯ãããã§ååã§ãããµã€ã¢ã³ã¹ãã¥ã¯ãŒãã¯ãGoogleã䜿çšããã¢ãããŒãã§ãããããŸããŸãšããŸãããããã¯ãååãæ £ç¿ã«åºå·ããã¹ãã§ã¯ãªããšããçŽ æŽããããã¢ã³ã¹ãã¬ãŒã·ã§ã³ã ãšæããŸãã
å±éãã€ãã©ã€ã³ã§ã®ãã¹ãã®å±é
ç¶ç¶çã€ã³ãã°ã¬ãŒã·ã§ã³ãŸãã¯ç¶ç¶çããªããªã䜿çšããå Žåãå±éãã€ãã©ã€ã³ã¯ããœãããŠã§ã¢ã«å€æŽãå ãããã³ã«èªåãã¹ããå®è¡ããŸããéåžžããã€ãã©ã€ã³ã¯ããã€ãã®æ®µéã«åãããŠãããããã°ã©ã ãå®çšŒåç°å¢ã§å±éã§ããç¶æ ã«ãããšããèªä¿¡ãåŸã ã«äžããŠããŸããããããçš®é¡ã®ãã¹ãã«ã€ããŠèããããšãããã®ã§ãå±éãã€ãã©ã€ã³ã«ã©ã®ããã«é 眮ããã®ãçåã«æããããããŸãããããã«çããã«ã¯ãç¶ç¶çããªããªã®æãåºæ¬çãªå€ã®1ã€ïŒæ¥µç«¯ãªããã°ã©ãã³ã°ãšã¢ãžã£ã€ã«éçºã®éèŠãªå€ã®1ã€ïŒã«ã€ããŠèããå¿ èŠããããŸããã¯ã€ãã¯ãã£ãŒãããã¯ã§ãã
é©åãªã¢ã»ã³ããªãã€ãã©ã€ã³ã¯ãã§ããã ãæ©ããšã©ãŒãå ±åããŸããææ°ã®å€æŽãããã€ãã®åçŽãªåäœãã¹ãã«éåããããšã確èªããã®ã«1æéåŸ ããªãã§ãã ãããã³ã³ãã¢ã®åäœãéåžžã«é ãå Žåã¯ããã£ãŒãããã¯ãå±ãããšãã«ãã§ã«å®¶ã«åž°ãããšãã§ããŸãããã€ãã©ã€ã³ã®åæ段éã§ã®è¿ éãªãã¹ãããæ°ç§ãŸãã¯æ°å以å ã«æ å ±ãåŸãããã¯ãã§ããéã«ãã¯ã€ãã¯ãã¹ãããã®ãã£ãŒãããã¯ãé ããªããªãããã«ãããé·ããã¹ãïŒéåžžã¯ããåºããšãªã¢ãå«ãïŒãåŸã®æ®µéã«é 眮ãããŸããã芧ã®ãšãããå±éãã€ãã©ã€ã³ã®æé ã¯ãã¹ãã®çš®é¡ã§ã¯ãªãããã¹ãã®é床ãšç¯å²ã«ãã£ãŠæ±ºãŸããŸãããããã£ãŠãæãé«éã§ãã£ãŒãããã¯ãåŸããããšããçç±ã ãã§ããŠããããã¹ããšåã段éã§ãæãçããŠéãçµ±åãã¹ãã®ããã€ããé 眮ããããšã¯éåžžã«åççã§ãããããŠãæ£åŒãªã¿ã€ãã®ãã¹ãã«åŸã£ãŠå³å¯ãªç·ãåŒãå¿ èŠã¯ãããŸããã
ãã¹ãã®éè€ãé¿ãã
é¿ããã¹ããã©ããããã1ã€ãããŸãããã©ãããã®ç°ãªãã¬ãã«ã§ãã¹ããè€è£œããããšã§ããæèœã¯ãå€ãã®ãã¹ãããªããšèšããŸãããç§ã¯ããªãã«ä¿èšŒãããŠãã ããïŒããã¯èµ·ãããŸãããã¹ããããã®åãã¹ãã¯ãç¡æã§ã¯ãªãè¿œå ã®æè·ç©ã§ãããã¹ãã®äœæãšå®è¡ã«ã¯æéãããããŸããä»ã®äººã®ãã¹ããèªãã§ç解ããã«ã¯æéãããããŸãããããŠãã¡ããããã¹ãã®å®è¡ã«ãæéãããããŸãã
å®åã³ãŒããšåæ§ã«ãåçŽåãå³ããéè€ãé¿ããŠãã ããããã¹ããã©ãããã®å®è£ ã®ã³ã³ããã¹ãã§ã¯ã2ã€ã®çµéšåããããŸãã
- äžäœã¬ãã«ã®ãã¹ãã§ãšã©ãŒãæ€åºãããããäžäœã¬ãã«ã®ãã¹ãã§ã¯æ€åºãããªãã£ãå Žåãäžäœã¬ãã«ã®ãã¹ããèšè¿°ããå¿ èŠããããŸãã
- ãã¹ãããã©ãããã¬ãã«å šäœã§å¯èœãªéãäœã移åããŸãã
æåã®ã«ãŒã«ã¯éèŠã§ããäœã¬ãã«ã®ãã¹ãã¯ãç¯å²ãçãããšã©ãŒãåé¢ããŠåçŸããã®ã«åªããŠããããã§ãããããã¯ããéãåäœããè¥å€§åãå°ãªããæåã®ãããã°ã«åœ¹ç«ã¡ãŸãããããŠãå°æ¥çã«ã¯ãããã¯è¯ãååž°ãã¹ããšããŠæ©èœããŸãã 2çªç®ã®ã«ãŒã«ã¯ããã¹ãã¹ã€ãŒãããã°ããå®è¡ããããã«éèŠã§ããäœãã¬ãã«ã®ãã¹ãã§ãã¹ãŠã®æ¡ä»¶ãèªä¿¡ãæã£ãŠãã¹ãããå Žåãé«ãã¬ãã«ã®ãã¹ãã¯å¿ èŠãããŸããã圌ã¯ãã¹ãŠãããŸããããšããèªä¿¡ãä»ãå ããŸãããéå°ãªãã¹ãã¯è² æ ã«ãªããæ¥åžžæ¥åã§æ©ã¿å§ããŸãããã¹ãã¹ã€ãŒãã®åäœã¯é ããªããã³ãŒããå€æŽããå Žåã¯ãããã«ãã¹ããå€æŽããå¿ èŠããããŸãã
å¥ã®èšãæ¹ãããã°ãããé«ãã¬ãã«ã®ãã¹ãããã¢ããªã±ãŒã·ã§ã³ãæ£åžžã«åäœããŠãããšããèªä¿¡ãäžããå Žåããã®ãããªãã¹ããå¿ èŠã§ããã³ã³ãããŒã©ãŒã¯ã©ã¹ã®åäœãã¹ããäœæãããšãã³ã³ãããŒã©ãŒèªäœã®å éšã®ããžãã¯ã確èªã§ããŸãããã ãããã®ã³ã³ãããŒã©ãŒãæäŸããRESTãšã³ããã€ã³ããå®éã«HTTPèŠæ±ã«å¿çããŠãããã©ããã¯ããããŸããããããã£ãŠããã¹ããã©ããããäžã«é²ãããããæ£ç¢ºã«ãã§ãã¯ãããã¹ããè¿œå ããŸããããã以äžã®ããšã¯è¡ããŸãããäžäœã¬ãã«ã®ãã¹ãã§ã¯ãäžäœã¬ãã«ã®åäœãã¹ãã§ãã§ã«ã«ããŒãããŠããæ¡ä»¶ä»ãããžãã¯ãšå¢çç·ã®ãã¹ãŠã®ã±ãŒã¹ããã¹ãããããã§ã¯ãããŸãããé«ã¬ãã«ã®ãã¹ãããäœã¬ãã«ã®ãã¹ãã§ã«ããŒãããŠããªããã®ã®ã¿ã«çŠç¹ãåãããŠããããšã確èªããŠãã ããã
ç§ã¯ã䟡å€ã®ãªããã¹ããé€å€ããããšã«å³æ Œã§ããäžäœã¬ãã«ã§ãã§ã«ã«ããŒãããŠããé«ã¬ãã«ã®ãã¹ããåé€ããŸãïŒè¿œå ã®äŸ¡å€ãæäŸããªãå ŽåïŒãå¯èœã§ããã°ãé«ã¬ãã«ã®ãã¹ããäœã¬ãã«ã®ãã¹ãã«çœ®ãæããŸããäœåãªãã¹ããåé€ããã®ãé£ããå ŽåããããŸããç¹ã«ç°¡åã«æãä»ããªãå Žåã¯ãªãããã§ãããã ãããµã³ã¯ã³ã¹ããçºçããå¯èœæ§ãããããã[åé€]ãã¯ãªãã¯ããŠãã ããããã¯ã圹ã«ç«ããªããã¹ãã«è²Žéãªæéã浪費ããçç±ã¯ãããŸããã
ãã¹ãçšã®ã¯ãªãŒã³ãªã³ãŒããæžã
éåžžã®ã³ãŒããšåæ§ã«ãé©åã§ã¯ãªãŒã³ãªãã¹ãã³ãŒãã«æ³šæããå¿ èŠããããŸããéå§ããŠèªåãã¹ãã¹ã€ãŒããäœæããåã«ããµããŒããããŠãããã¹ãã³ãŒããäœæããããã®ãã³ãã次ã«ç€ºããŸãã
- , . . « » â .
- . .
- (arrange, act, assert) «, , » â , .
- . DRY ( « »). , . DRY DAMP (DAMP â Descriptive And Meaningful Phrases, ).
- , . Use before reuse .
ãããã«
以äžã§ãïŒããã¯ããã¹ããå®æœããçç±ãšæ¹æ³ã«ã€ããŠã®é·ããŠé£ãã説æã§ãããçŽ æŽããããã¥ãŒã¹ã¯ããã®æ å ±ã«ã¯å®è³ªçã«å¶éã®èŠå®ããªããäœæããŠããããã°ã©ã ã«äŸåããªãããšã§ããããªãã¯ãã€ã¯ããµãŒãã¹ãIoTããã€ã¹ãã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ããŸãã¯Webã¢ããªã±ãŒã·ã§ã³ã«åãçµãã§ããŸãããã®èšäºã®æèšã¯ãã¹ãŠã«åœãŠã¯ãŸããŸãã
ãã®èšäºã«äœã圹ã«ç«ã€ãã®ãããã°ããã®ã§ããããããå ã«é²ã¿ããµã³ãã«ã³ãŒãã調ã¹ãŠãååŸããæŠå¿µããã¹ãã¹ã€ãŒãã«é©çšããŸããå ç¢ãªãã¹ãã¹ã€ãŒããäœæããã«ã¯ãããçšåºŠã®åªåãå¿ èŠã§ããé·ãç®ã§èŠãã°å ±ãããããªãã®éçºè ã®ç掻ããããªã©ãã¯ã¹ãããã®ã«ãªããšä¿¡ããŠããŸãã
ãã¡ããã芧ãã ããïŒ
ããœãããŠã§ã¢ãã¹ãã®ã¢ã³ããã¿ãŒã³ã