ããã«ã¡ã¯ ãã€ã¯ããµãŒãã¹ã®ãšã³ãããŒãšã³ãã®ãã¹ãã®ããã®æ°ããããŒã«-Catcherã玹ä»ããã
ãã¹ãããçç±
ãªãe2eãã¹ããå¿ èŠãªã®ã§ããïŒ ããŒãã£ã³ã»ãã¡ãŠã©ãŒã¯ ãããåçŽãªãã¹ããæ¯æããŠãããé¿ããããšãæšå¥šããŸãã
ãã ãããã¹ããé«ãã»ã©ãæžãæãã¯å°ãªããªããŸãã åäœãã¹ãã¯ã»ãŒå®å šã«æžãçŽãããŠããŸãã æ©èœãã¹ãã¯ãæ·±å»ãªãªãã¡ã¯ã¿ãªã³ã°ã®å Žåã«ãæéãè²»ããå¿ èŠããããŸãã ãšã³ãããŒãšã³ãã®ãã¹ãã§ã¯ãããžãã¹ããžãã¯ããã¹ãããå¿ èŠããããå€æŽã®é »åºŠã¯å°ãªããªããŸãã
ããã«ããã¹ãŠã®ãã€ã¯ããµãŒãã¹ã®å®å šãªãã¹ãç¯å²ã§ããããããã®æ£ããçžäºäœçšãä¿èšŒããŸããã éçºè ã¯ããããã³ã«ã誀ã£ãŠå®è£ ããå ŽåããããŸãïŒåå/ããŒã¿åã®ãšã©ãŒïŒã
ãŸãã¯ãããã¥ã¡ã³ãã®ããŒã¿ã¹ããŒã ã«äŸåããæ°ããæ©èœãå®è£ ããã¹ããŒã ã®äžäžèŽãšã©ãŒã®åœ¢ã§è£œåç°å¢ã«é©ããèŠããŸããããŒã¿ã®æ··ä¹±ãããŒã¿ã¹ããŒã ã®æŽæ°ãå¿ãã人ã
ãŸããé¢é£ããåãµãŒãã¹ã®ãã¹ãã¯ã°ãªãŒã³ã«ãªããŸãã
èªåãã¹ããè¡ãçç±
æ¬åœã«ã ç§ã®ä»¥åã®å€åå°ã§ã¯ãèªååããããã¹ãã®å±éã«æéãè²»ããããšã¯ãé·ãããå°é£ã§ãè²»çšãããããšå€æãããŸããã ã·ã¹ãã ã¯å€§ãããããŸããïŒäžè¬çãªã«ãã«ã䜿çšãã10ã15åã®ãã€ã¯ããµãŒãã¹ïŒã CTOã¯ãããã¹ãã¯éèŠã§ã¯ãªããäž»ãªããšã¯ã·ã¹ãã ãæ©èœããããšã ããšå€æããŸããã ããã€ãã®ç°å¢ã§æåã§ãã¹ãããŸããã
å€èŠ³ïŒäžè¬çãªããã»ã¹ïŒïŒ
- ä»ã®éçºè ã«åæããïŒæ°ããæ©èœã«åå ããŠãããã¹ãŠã®ãã€ã¯ããµãŒãã¹ãå±éããïŒ
- ãã¹ãŠã®ãµãŒãã¹ãå±éãã
- ãªã¢ãŒãkafkaã«æ¥ç¶ããŸãïŒdmzã®ããã«sshïŒ
- k8sãã°ã«æ¥ç¶ããŸã
- kafkaã«ã¡ãã»ãŒãžãæåã§äœæããŠéä¿¡ããŸãïŒgod jsonã«æè¬ïŒ
- ãã°ãèŠãŠãåäœãããã©ãããç解ããŠãã ããã
ãããŠä»ããã®ãã§ã³ã¬ãŒãã®æšœã«ã¯å°ãã®ã¿ãŒã«ããããŸããã»ãšãã©ã®ãã¹ãã§ã¯ããŠãŒã¶ãŒãäœæããå¿ èŠããããŸãããæ¢åã®ãã®ãåå©çšããã®ã¯é£ããããã§ãã
ãŸããã·ã¹ãã ãåæ£ããŠãããšããäºå®ã«ãããããã€ãã®ãµãŒãã¹ã«ã¯ãŠãŒã¶ãŒã«é¢ããæ å ±ãå«ãç¬èªã®ããŒã¿ããŒã¹ããããŸããã
第äºã«ãkafkaã¯æ°žç¶çãªããŒã¿ã¹ãã¬ãŒãžã«äœ¿çšãããŸããã ã€ãŸã ããŒã¿ããŒã¹å ã®æ å ±ãåé€/å€æŽãããŠãããµãŒãã¹ã¯åèµ·åæã«ãããèªã¿è¿ããŸãã
æ°ãããã¹ããŠãŒã¶ãŒã®ç»é²ã¯ã©ã®ãããªãã®ã§ãããïŒæŠç®ïŒïŒ
- ããŒã¿ïŒååãã¡ãŒã«ãªã©ïŒãå ¥åããŸã
- å人ããŒã¿ã®å ¥åïŒäœæãé»è©±çªå·ãçšåæ å ±ïŒ
- éè¡ããŒã¿ã®å ¥åïŒå®éã«ã¯ãéè¡ããŒã¿ïŒ
- 20ã40ã®è³ªåã«çããŸãïŒãã§ã«çã¿ãæããŠããŸããïŒïŒ
- IDNowã® IDã確èªããŸãïŒãµã³ãããã¯ã¹ãæã éè² è·ã«ãªãããã éçºç°å¢ã§ç¡å¹ã«ããããšãç¥ã«æè¬ããŸããã¹ããŒãžã§ã¯çŽ5å以äžã§ãïŒ
- ãã®ã¹ãããã§ã¯ããµãŒãããŒãã£ã·ã¹ãã ã§ã¢ã«ãŠã³ããéãå¿ èŠããããããã³ããšã³ãã§ã¯äœãã§ããŸããã sshã§kafkaã«ã¢ã¯ã»ã¹ããæš¡æ¬ãµãŒããŒãšããŠåäœããå¿ èŠããããŸãïŒã¢ã«ãŠã³ããéããŠãããšããã¡ãã»ãŒãžãéä¿¡ããŸãïŒ
- 次ã«ãã¢ãã¬ãŒã¿ãŒã®å人ã¢ã«ãŠã³ãã®å¥ã®ããã³ããšã³ãã«ç§»åããŠããŠãŒã¶ãŒã確èªããå¿ èŠããããŸãã
ã¹ãŒããŒããŠãŒã¶ãŒãç»é²ãããŸããïŒ è»èãå°ãé£ã¶ããã«ãªããŸãããäžéšã®ãã¹ãã§ã¯ãè€æ°ã®ãã¹ããŠãŒã¶ãŒãå¿ èŠã§ãã ãŸãããã¹ããåããŠå€±æããããšããããŸãã
ãããŠãæ°æ©èœã®æ€èšŒãšããžãã¹ããŒã ããã®ç¢ºèªã¯ã©ãã§ããïŒ
次ã®ç°å¢ã§ãåãããšãç¹°ãè¿ãå¿
èŠããããŸãã
èšããŸã§ããªãããã°ãããããšã圌ã¯ãã¿ã³ãæŒããã ãã§ããŠãŒã¶ãŒãç»é²ããç¿ã®ããã«æãå§ããŸãã
äžéšã®éçºè ïŒéåžžã¯ããã³ããšã³ãïŒã¯ãkafkaãžã®æ¥ç¶ã«åé¡ããããŸããã ãããŠã端æ«ã«ãã°ãããã80æå以äžã®æååããããŸãïŒtmuxã«ã€ããŠèª°ããç¥ã£ãŠããããã§ã¯ãããŸããïŒã
é·æ ïŒ
- äœãèšå®/æžã蟌ãå¿ èŠã¯ãããŸããã å®è¡äžã®ç°å¢ã§æ£ãããã¹ãããŸãã
- é«ãè³æ Œã¯å¿ èŠãããŸããïŒå®ãå°é家ãã§ããŸãïŒ
çæ ïŒ
- æéãããããŸãïŒé ãã«ãªãã»ã©ãããå€ããªããŸãïŒ
- éåžžãæ°ããæ©èœã®ã¿ããã¹ããããŸãïŒæ¢åã®æ©èœãå£ããŠãããã©ããã¯æ確ã§ã¯ãããŸããïŒ
- å€ãã®å Žåãçç·Žããéçºè ãæåãã¹ãã«åŸäºããŠããŸãïŒé«äŸ¡ãªå°é家ãå®äŸ¡ãªäœæ¥ãè¡ããŸãïŒã
èªååããæ¹æ³ã¯ïŒ
é ãããªãããŠãã¯ããããã¯çŽ æŽãããããã»ã¹ã§ããã¿ããªåœŒããäœãããŠããã®ãç¥ã£ãŠããŸãããšèšã£ãŠãããèªãã ããèå³ã¯ãããŸããã
èªå®¶è£œã®e2eãã¹ãã«ã¯2ã€ã®ã¿ã€ãããããã©ã¡ãã®ããã°ã©ããŒãããèªç±ã ã£ããã«ãã£ãŠç°ãªããŸãã
- ãã¹ãç°å¢ã«ååšããããã¯ãšã³ãã ãã¹ãããžãã¯ãä¿è·ããŸãããã¹ãããžãã¯ã¯ããšã³ããã€ã³ããééããŸãã CIãšã®çžäºäœçšã«ãããéšåçã«èªååããããšãã§ããŸãã
- åãã¯ã€ã€ãŒãããžãã¯ã䜿çšããã¹ã¯ãªããã å¯äžã®éãã¯ãã©ããã«è¡ã£ãŠããããå®è¡ããå¿ èŠãããããšã§ãã CIãä¿¡é ŒããŠããå Žåã¯ãèªåçã«å®è¡ããããšãã§ããŸãã
ããã§ããã åé¡ïŒ
ã¯ãããã®ãããªãã¹ãã¯ãããããæžãã人ãç¥ã£ãŠããããšã«ã€ããŠæžãããŠããŸãã éåžžããããã¯rubãpythonãªã©ã®ã¹ã¯ãªããèšèªã§ããããã®çš®ã®ããšããã°ããç°¡åã«æžãããšãã§ããŸãã ãã ããbashã¹ã¯ãªããã®æãCããŸãã¯ãããšããŸããã¯ãªãã®ã«åºãããããšããããŸãïŒã¹ã¯ãªãããæ¡åŒµå¯èœã§ãªããªã£ããããbashã¹ã¯ãªããã§èªè»¢è»ãpythonã«ã³ããŒããã®ã«1é±éããããŸããã ã
ãããžã§ã¯ãäŸã¯ãã¡ã
é·æ ïŒ
- èªåå
çæ ïŒ
- éçºè ã®è³æ Œã«ã¯è¿œå ã®èŠä»¶ãããå ŽåããããŸãïŒJavaã§éçºããŠããããã¹ããPythonã§äœæãããŠããå ŽåïŒ
- èšè¿°ãããã³ãŒãããã¹ãããããã®ã³ãŒãã®èšè¿°ïŒèª°ããã¹ãããã¹ãããŸããïŒïŒ
æºåã¯ã§ããŠããŸããïŒ
ãã¡ããã BDDã®æ¹åãèŠãŠãã ããã ãã ãã ã ã²ãŒãžããããŸãã
èŠããã«ãéçºè ã¯ç¹å¥ãªèšèªã§ããžãã¹ã·ããªãªãèšè¿°ããã³ãŒãå ã®ã¹ã¯ãªããã®ã¹ããããå®è£ ããŸãã éåžžããã®èšèªã¯äººéãèªãã圢åŒã§ãããéçºè ã ãã§ãªããããžã§ã¯ããããŒãžã£ãŒãèªã¿æžãã§ãããšæ³å®ãããŠããŸãã
ã¹ã¯ãªããã¯ãã¹ãããã®å®è£ ãšãšãã«å¥ã®ãããžã§ã¯ãã«ããããµãŒãããŒãã£è£œåïŒCucumber / Gauge / ...ïŒã«ãã£ãŠå®è¡ãããŸãã
ã¹ã¯ãªããã¯æ¬¡ã®ããã«ãªããŸãã
Customer sign-up ================ * Go to sign up page Customer sign-up ---------------- tags: sign-up, customer * Sign up a new customer with name "John" email "jdoe@test.de" and "password" * Check if the sign up was successful
ãããŠå®è£ ïŒ
@Step("Sign up as <customer> with email <test@example.com> and <password>") public void signUp(String customer, String email, String password) { WebDriver webDriver = Driver.webDriver; WebElement form = webDriver.findElement(By.id("new_user")); form.findElement(By.name("user[username]")).sendKeys(customer); form.findElement(By.name("user[email]")).sendKeys(email); form.findElement(By.name("user[password]")).sendKeys(password); form.findElement(By.name("user[password_confirmation]")).sendKeys(password); form.findElement(By.name("commit")).click(); } @Step("Check if the sign up was successful") public void checkSignUpSuccessful() { WebDriver webDriver = Driver.webDriver; WebElement message = webDriver.findElements(By.className("message")); assertThat(message.getText(), is("You have been signed up successfully!")); }
å®å šãªãããžã§ã¯ãã¯ãã¡ã
é·æ ïŒ
- ããžãã¹ããžãã¯ã¯äººéãèªããèšèªã§èšè¿°ããã1ãæã«ä¿åãããŸãïŒããã¥ã¡ã³ããšããŠäœ¿çšã§ããŸãïŒ
- æ¢è£œã®ãœãªã¥ãŒã·ã§ã³ã䜿çšãããéçºè ã¯ãããã®äœ¿çšæ¹æ³ãç¥ãã ãã§ãã
çæ ïŒ
- ãããŒãžã£ãŒã¯ã¹ã¯ãªãããèªã¿æžãããŸãã
- ä»æ§ãšãã®å®è£ ã®äž¡æ¹ã«åŸãå¿ èŠããããŸãïŒããã¯ã³ãŒãã®èšè¿°ãšä»æ§ã®ç·šéã§ãïŒ
ããã§ã¯ããªããã£ããã£ãŒãªã®ã§ããããïŒ
ãã¡ãããããã»ã¹ãç°¡çŽ åããããã«ã
éçºè ã¯json / yamlã«ã¹ã¯ãªããã®ã¿ãèšè¿°ããCatcherãããããå®è¡ããŸãã ã¹ã¯ãªããã¯ãé£ç¶ããŠå®è¡ãããã¹ãããã§æ§æãããŸããäŸïŒ
steps: - http: post: url: '127.0.0.1/save_data' body: {key: '1', data: 'foo'} - postgres: request: conf: 'dbname=test user=test host=localhost password=test' query: 'select * from test where id=1'
Catcherã¯jinja2ãã³ãã¬ãŒãããµããŒãããŠãããããäžèšã®äŸã§ã¯ã¯ã€ã€ãŒãå€ã®ä»£ããã«å€æ°ã䜿çšã§ããŸãã ã°ããŒãã«å€æ°ã¯ãïŒã¢ã³ãµã³ãã«ã®ããã«ïŒã€ã³ãã³ããªãã¡ã€ã«ã«ä¿åããç°å¢ããååŸããŠãæ°ãããã®ãç»é²ã§ããŸãã
variables: bonus: 5000 initial_value: 1000 steps: - http: post: url: '{{ user_service }}/sign_up' body: {username: 'test_user_{{ RANDOM_INT }}', data: 'stub'} register: {user_id: '{{ OUTPUT.uuid }}' - kafka: consume: server: '{{ kafka }}' topic: '{{ new_users_topic }}' where: equals: {the: '{{ MESSAGE.uuid }}', is: '{{ user_id }}'} register: {balance: '{{ OUTPUT.initial_balance }}'}
ããã«ããã¹ãã¹ããããå®è¡ã§ããŸãã
- check: # check user's initial balance equals: {the: '{{ balance }}', is: '{{ initial_value + bonus }}'}
ãŸããä»ã®ã¹ã¯ãªããããããã€ãã®ã¹ã¯ãªãããå®è¡ããããšãã§ããŸããããã¯ãã³ãŒãã®ã¯ãªãŒã³ããšåå©çšïŒã¿ã°ã·ã¹ãã ãä»ããã¹ãããã®äžéšã®ã¿ã®éå§ãèµ·åã®é 延ãªã©ïŒã«åªããå¹æããããããŸãã
include: file: register_user.yaml as: sign_up steps: # .... some steps - run: include: sign_up # .... some steps
ã¹ã¯ãªãããæ¿å ¥ããŠäœ¿çšããããšã§ããªãœãŒã¹ãåŸ æ©ããåé¡ã解決ã§ããŸãïŒèµ·åäžã«ãµãŒãã¹ãåŸ æ©ããŸãïŒã
æ¢è£œã®çµã¿èŸŒã¿æé ãšè¿œå ã®ãªããžããªã«å ããŠïŒãPythonïŒ ExternalStepãç¶æ¿ããã ãïŒãŸãã¯ä»ã®èšèªã§ã¢ãžã¥ãŒã«ãæžãããšãã§ããŸãïŒ
#!/bin/bash one=$(echo ${1} | jq -r '.add.the') two=$(echo ${1} | jq -r '.add.to') echo $((${one} + ${two}))
ãããŠäœ¿çšïŒ
--- variables: one: 1 two: 2 steps: - math: add: {the: '{{ one }}', to: '{{ two }}'} register: {sum: '{{ OUTPUT }}'}
ã¹ã¯ãªããã¯dockerãã¡ã€ã«ã«é 眮ãããCIãä»ããŠå®è¡ãããŸãã
ãŸãããã®ç»åãMarathon / K8sã§äœ¿çšããŠãæ¢åã®ç°å¢ããã¹ãã§ããŸãã çŸæç¹ã§ã¯ããã¹ãããã»ã¹ãããã«ç°¡åãã€äŸ¿å©ã«ããããã«ãããã¯ãšã³ãïŒAnsibleTowerã®ã¢ããã°ïŒã«åãçµãã§ããŸãã
é·æ ïŒ
- ã³ãŒããèšè¿°ããå¿ èŠã¯ãããŸããïŒã«ã¹ã¿ã ã¢ãžã¥ãŒã«ã®å Žåã®ã¿ïŒ
- ã€ã³ãã³ããªãã¡ã€ã«ã䜿çšããç°å¢ã®åãæ¿ãïŒã¢ã³ãµã³ãã«ãªã©ïŒ
- ç¬èªã®ã¢ãžã¥ãŒã«ã䜿çšã§ããŸãïŒã©ã®èšèªã§ããshã§ãïŒ
çæ ïŒ
- 人éãèªããªãæ§æïŒBDDããŒã«ãšæ¯èŒããŠïŒ
çµè«ã®ä»£ããã«
ãã®ããŒã«ãäœæãããšããç§ã¯éåžžããã¹ãã«è²»ããæéãççž®ãããã£ãã ãã§ãã ãã®ãããæ°ããäŒç€Ÿã¯ãã¹ãŠãã®ãããªã·ã¹ãã ãäœæïŒãŸãã¯æžãæãïŒããå¿ èŠããããŸããã
ãã ãããã®ããŒã«ã¯äºæ³ãããæè»æ§ãé«ãããšãå€æããŸããã 誰ãããã®èšäºïŒãŸãã¯ããŒã«èªäœïŒã«èå³ãããå Žåã¯ãCatcherã䜿çšããŠéäžç§»è¡ãæŽçãããã€ã¯ããµãŒãã¹ã·ã¹ãã ãæŽæ°ããæ¹æ³ã説æã§ããŸãã
æŽæ°
ã³ã¡ã³ãã§ææãããããã«ããã®ãããã¯ã¯å
¬éãããŠããŸããã
ããã§æãç©è°ãéžãè«æã瀺ããããšããŸãã
- ãšã³ãããŒãšã³ããã¹ãã¯åäœãã¹ãã§ã¯ãããŸããã ãã®èšäºã§ã¯ããã§ã«M. Fowlerã«ã€ããŠèšåããŸããã åäœãã¹ãã¯ãã¹ãããã¯ãšã³ããããžã§ã¯ãïŒæšæº
tests
ãã£ã¬ã¯ããªïŒã«ãããã³ãŒããCIã«å€æŽããããã³ã«å®è¡ãããŸãã ãŸããe2eãã¹ãã¯å¥ã®ãããžã§ã¯ãã§ããéåžžã¯æéãããããåå ããŠãããã¹ãŠã®ãµãŒãã¹ã®çžäºäœçšããã¹ããããããžã§ã¯ãã®ã³ãŒãã«ã€ããŠã¯äœãç¥ããŸããïŒãã©ãã¯ããã¯ã¹ïŒã - çµ±åïŒããã³ä»¥äžïŒãã¹ãã«Catcherã䜿çšããªãã§ãã ããã é«äŸ¡ã§ãã çŸåšã®ããã¯ãšã³ãã®èšèªã§ãã¹ããæžãæ¹ãã¯ããã«é«éã§ãã ãšã³ãããŒãšã³ãã®ãã¹ããå¿ èŠãªã®ã¯ãããžãã¹ããžãã¯ã2ã€ä»¥äžã®ãµãŒãã¹ã«åæ£ããŠããå Žåã®ã¿ã§ãã
- ãã£ããã£ãŒãBDDã§ãã ç§ã®èŠ³ç¹ãããGauge / Cucumberã«å¯Ÿããäž»ãªå©ç¹ã¯ãæ¢è£œã®ã¢ãžã¥ãŒã«ãšè¿œå ã®å®¹æãã§ãã çæ³çã«ã¯ããã¹ãã®ã¿ãèšè¿°ãããŸãã åã®äŒç€Ÿã§ã¯ãããã°ã©ãã³ã°ãäžåè¡ããã«ãæšæºã³ã³ããŒãã³ãã§4ã€ã®ãã¹ããã¹ãŠãäœæããŸããã ãããã£ãŠãè³æ ŒèŠä»¶ïŒããã³ãã®ãããªå°é家ã®äŸ¡æ ŒïŒã¯äœããªããŸãã json / yamlã®ç¥èãšä»æ§ãèªãèœåã®ã¿ãå¿ èŠã§ãã
- Catcherãã¹ããäœæããã«ã¯ãCatcher-DSLãåŠç¿ããå¿ èŠããããŸãã æ²ããããªãããã¯æ¬åœã§ãã æåã¯ããã€ã¯ããçŽæ¥ããã¹ãã«èªåã§æžããŠãããããã£ãã ãããããã®åŸãç§ã¯åœŒãããã®åŸç§ãäžå¿ èŠã«è§£éãããšæã£ã;ïŒäžèšã®ããã«-ãã£ããã£ãŒDSLã¯æšæºã®json / yamlãšã¹ãããä»æ§ã§ãã åºæ¬çã«æ°ãããã®ã¯ãããŸããã
- æšæºã®ãã¯ãããžãŒã䜿çšããŠãç¬èªã®ãã®ãäœæã§ããŸãã ãã ãããã€ã¯ããµãŒãã¹ã«ã€ããŠè©±ããŠããã ããã¯ãå€æ°ã®ç°ãªãæè¡ãšæ žå µåšãšå€æ°ã®ããŒã ã§ãã ãŸããjavaã³ãã³ãjunit + testcontainersãæçœãªéžæã§ããå Žåãã¢ãŒã©ã³ããŒã ã¯å¥ã®ãã®ãéžæããŸãã æäžäœã«30以äžã®ããŒã ããã倧äŒæ¥ã§ã¯ããã¹ãŠã®ãã¹ããæ°ããã€ã³ãã©ã¹ãã©ã¯ãã£/ QAããŒã ã«æåºããããšã決å®ããŸãã ãã®åç©åã§åœŒããã©ãã»ã©å¹žããæ³åã§ããŸããïŒ
- 4ã5åã®e2eãã¹ããããå Žåã¯ããã¹ãŠã®ã¹ã¯ãªããèšèªã§ãã¹ãŠãèšè¿°ãããããå¿ããããšãã§ããŸãã ãã ããããžãã¯ãæéãšãšãã«å€åããå Žåã¯ã2ã4幎åŸã«ãªãã¡ã¯ã¿ãªã³ã°ãè¡ãããã¹ãã®ããžãã¹ããžãã¯ãšã¢ã¯ã»ã¹ã¡ãœããã®å®è£ ããã¹ã察象ã®ã³ã³ããŒãã³ãã«çŽæ¥é åžããå¿ èŠããããŸãã ãã®ãããæçµçã«ã¯ãã£ããã£ãŒãäœæããŸãããããã»ã©æè»ã§ã¯ãããŸããã ãããç解ããã«ã¯4ã€ã®å®è£ ãå¿ èŠã§ãã;ïŒ