Cucumber-js: ๊ฐ ๊ธฐ๋Šฅ ํŒŒ์ผ์— ๋Œ€ํ•ด ๋‹จ๊ณ„ ์ •์˜ ํŒŒ์ผ์„ ์ง€์ •ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

์— ๋งŒ๋“  2017๋…„ 02์›” 02์ผ  ยท  18์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: cucumber/cucumber-js

๋‚ด ๋ชฉํ‘œ

๋Œ€๊ทœ๋ชจ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ ๋ฐ ๋‹จ๊ณ„ ์ •์˜์˜ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ฒซ ๋ฒˆ์งธ ์žฅ๋ฉด์€ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„ ์ •์˜์— ๋™์ผํ•œ ๋‹จ๊ณ„ ํŒจํ„ด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก step_definition ํŒŒ์ผ์„ ๊ธฐ๋Šฅ์— ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ์ฝ”๋“œ

ํ˜„์žฌ ์˜ˆ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๋‚ด ํด๋” ๊ตฌ์กฐ:

/features/sample.feature
/features/example.feature
/features/step_definitions/sample_steps.js
/features/step_definitions/example_steps.js
/features/step_definitions/common/common_steps.js

๋‚ด sample.feature ์—๋Š” ๋‹ค์Œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  Scenario: Launching Cucumber
  Given I have some step definitions
   When I check some step definition with parameter "any"
   Then I should see all green "sample"

๋‚ด example.feature ์—๋Š” ๋‹ค์Œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  Scenario: Launching Cucumber
  Given I have some step definitions
   When I check some step definition with parameter "any"
   Then I should see all green "example"

Given ๋ฐ When ๋‹จ๊ณ„๋Š” /common/common_steps.js ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉฐ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

Then ๋‹จ๊ณ„๋Š” sample_steps.js ๋ฐ example_steps.js ๋ชจ๋‘์— ์ •์˜๋˜์ง€๋งŒ ๋‹ค๋ฅด๊ฒŒ ์ •์˜๋ฉ๋‹ˆ๋‹ค.

๋‚ด sample_steps.js์—๋Š” ๋‹ค์Œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Then('I should see all green {stringInDoubleQuotes}', (arg) => {
   if (arg !== 'sample') {
     throw 'I should see all green when the argument is "sample"';
   }
   return;
 });

๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ๋‚ด example_steps.js์—๋Š” ๋‹ค์Œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Then('I should see all green {stringInDoubleQuotes}', (arg) => {
   if (arg !== 'example') {
     throw 'I should see all green when the argument is "example"';
   }
   return;
 });

์˜ค๋ฅ˜

๋‚ด ์ฃผ์š” ๋ชฉํ‘œ๋Š” ์—ฌ๊ธฐ์—์„œ ๋ชจ๋“  ๋…น์ƒ‰์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ๋ฌผ๋ก  ์ž‘๋™ํ•˜์ง€ ์•Š๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช…๋ฐฑํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Multiple step definitions match:
   I should see all green {stringInDoubleQuotes} - features\step_definitions\example_steps.js:6
   I should see all green {stringInDoubleQuotes} - features\step_definitions\sample_steps.js:6

์˜ค์ด-JVM

์˜ค์ด-jvm์—์„œ ๊ธฐ๋Šฅ๊ณผ step_definitions๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” glue ์†์„ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ ์ œ๊ฐ€ ์ฐพ๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์˜ค์ด-js์—์„œ๋Š” ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์˜ ์˜ˆ:

@RunWith(Cucumber.class)
@Cucumber.Options( glue = { "com.app.stepdefinitions.common", "com.app.stepdefinitions.sample" } )
public class SampleFeature{
}

@RunWith(Cucumber.class)
@Cucumber.Options( glue = { "com.app.stepdefinitions.common", "com.app.stepdefinitions.example" } )
public class ExampleFeature{
}

๋งˆ์นจ๋‚ด

์˜ค์ด-js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ cucumbr-jvm๊ณผ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

IMO ๋ฒ”์œ„ ์ง€์ •์ด ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์„ฑ์žฅํ•จ์— ๋”ฐ๋ผ ๊ธฐ๋Šฅ์˜ ์ˆ˜๊ฐ€ ํ™•์žฅ๋˜๊ณ  ๋‹ค๋ฅธ ์ปจํ…์ŠคํŠธ์—์„œ ์„ค๋ช…์ด ์ถฉ๋Œํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ ํšŒ์‚ฌ์—์„œ ์šฐ๋ฆฌ ์ œํ’ˆ์—๋Š” ์ˆ˜๋ฐฑ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์ด ์žˆ๊ณ  QA์—๋Š” 10๋งŒ ๊ฐœ ๋ฒ”์œ„์˜ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
cucumber ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ถ„๋ช…ํžˆ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ๋ฒ”์œ„ ๋Œ€์‹  ์ปจํ…์ŠคํŠธ๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
์ „์ฒด๋Š” ์•„๋‹ˆ์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๋‹จ๊ณ„ ์ •์˜๋ฅผ ๊ธฐ๋ณธ ์ปจํ…์ŠคํŠธ(๋˜๋Š” ์ปจํ…์ŠคํŠธ ์—†์Œ)์— ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ ์‚ฌ์šฉ์ž ์ง€์ • DSL ์—†์ด ์ปจํ…์ŠคํŠธ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ BA ๋ฐ QA์ด๋ฉฐ ๋ชจ๋“  ์‚ฌ์šฉ์ž ์ง€์ • DSL์€ ํ˜ผ๋ž€๊ณผ ์ €ํ•ญ์„ ์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋Šฅ/์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ์ด๋ฏธ ์ •์˜์— ๋”ฐ๋ผ ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๋ฏ€๋กœ Gherkin ๊ตฌ๋ฌธ์— ๋“ค์—ฌ์“ฐ๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํƒœ๊ทธ ๋ฐ ์‚ฌ์šฉ์ž ์ •์˜ DSL์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์†”๋ฃจ์…˜ ๋Œ€์‹  ๊ตฌํ˜„ ์ œํ•œ(์˜ˆ: ํ•ดํ‚น, IMO)์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

https://github.com/cucumber/cucumber-js/issues/745 ๋ฅผ ๊ณ ๋ คํ•˜๋ฉด์„œ ์ด๊ฒƒ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

defineStep Scenario ๋ฅผ ํ™•์žฅํ•˜๊ณ  {Given, When, Then} ๋ฅผ ์ฝœ๋ฐฑ์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์ฆ‰:

import {defineSupportCode} from 'cucumber'

defineSupportCode(({ Scenario, Given, When, Then }) => {
  Given(...)
  When(...)
  Then(...)
  Scenario('<match scenario description>', ({ Given, When, Then}) => {
    Given('<take precedent of non-contexted>', ...)
    ...
  })
})

๋ชจ๋“  18 ๋Œ“๊ธ€

๋Œ€๊ทœ๋ชจ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ ๋ฐ ๋‹จ๊ณ„ ์ •์˜์˜ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ฒซ ๋ฒˆ์งธ ์žฅ๋ฉด์€ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„ ์ •์˜์— ๋™์ผํ•œ ๋‹จ๊ณ„ ํŒจํ„ด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก step_definition ํŒŒ์ผ์„ ๊ธฐ๋Šฅ์— ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๋งค์šฐ ํฅ๋ฏธ๋กœ์šด. ์˜ค์ด-js๋Š” ๋‹น์‹ ์ด ์ œ๊ณตํ•œ ์˜ค์ด-์ž๋ฐ” ์˜ˆ์ œ์ฒ˜๋Ÿผ ๋‚ด์žฅ๋œ ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์ด๋Ÿฐ ์œ ํ˜•์— ๋Œ€ํ•ด ์ข‹์•„ํ•˜๋Š” ์•„์ด๋””์–ด๋Š” ์ด ๋…ผ๋ฆฌ ์ „ํ™˜์„ ์„ธ๊ณ„ ์„ค์ • ๋˜๋Š” ์ธ์Šคํ„ด์Šค๋กœ ๋ฐ€์–ด ๋„ฃ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–ด๋Š ์ชฝ์ด๋“  ๋‹จ ํ•˜๋‚˜์˜ ๋‹จ๊ณ„ ์ •์˜๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค. ์ง€์› ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ ์ „ํ™˜ํ•˜๋Š” ์—ฌ๋Ÿฌ ์„ธ๊ณ„ ์ •์˜๋ฅผ ๊ฐ€์ง€๊ฑฐ๋‚˜ ์ปจํ…์ŠคํŠธ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋ฅผ ๋…ธ์ถœํ•˜๋Š” ๋‹จ์ผ ์„ธ๊ณ„ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ํ˜„์žฌ ์‹œ๋‚˜๋ฆฌ์˜ค์˜ ํŒŒ์ผ์„ ์‹คํ–‰ ๋‹จ๊ณ„์— ๋…ธ์ถœํ•˜์ง€ ์•Š์ง€๋งŒ ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปจํ…์ŠคํŠธ๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์‹ค์ œ๋กœ ์ด๊ฒƒ์„ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” nightwatch-cucumber ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์…€๋ ˆ๋Š„ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ํ˜„์žฌ๋กœ์„œ๋Š” ๊ฐ ๋‹จ๊ณ„์— ์ ‘๋‘์‚ฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์œ ์ผํ•œ ํ•ด๊ฒฐ์ฑ…์ž…๋‹ˆ๋‹ค.

Given [comp1] I click on "Open dialog"

๋Œ€

Given [comp2] I click on "Open dialog"

์ด๋Š” ๋ชจํ˜ธํ•œ ๋‹จ๊ณ„ ์ •์˜๋ฅผ ํ”ผํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ฝ์„ ์ˆ˜ ์—†๋Š” ๊ธฐ๋Šฅ ํŒŒ์ผ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค.
์˜ค์ด.js ์†Œ์Šค๋ฅผ ์ˆ˜์ •ํ•ด ๋ณด์•˜์ง€๋งŒ ์ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•  ์ข‹์€ ํžŒํŠธ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ผ๋ถ€ ํ›„ํฌ ๋˜๋Š” ๋Œ€์•ˆ ์„ธ๊ณ„๋กœ ์‹คํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@leipert ์–ด๋–ค ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ์ด ๋…ผ๋ฆฌ๊ฐ€ ์„ธ๊ณ„์— ์กด์žฌํ•˜๊ฑฐ๋‚˜ ์—ฌ๋Ÿฌ ์„ธ๊ณ„ ๊ฐœ์ฒด๋ฅผ ์ง€์›ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹จ๊ณ„ ์ •์˜๋Š” ์ž‘์€ ์˜ค์ด ์ผ์น˜ ํ•ญ๋ชฉ์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ณ  ์ ์ ˆํ•œ ์„ธ๊ณ„ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋Š” ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•  ์„ธ๊ณ„ ๊ฐœ์ฒด๋ฅผ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•œ CLI ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ๋กœ์„œ๋Š” ๋‹ค์ค‘ ์„ธ๊ณ„/๋‹จ๊ณ„ ์ •์˜๋ฅผ ๊ฐ–๊ณ  ์‹ถ๋‹ค๋ฉด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ ํด๋”์— ๋„ฃ๊ณ  ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ํ•˜๋‚˜๋งŒ ์š”๊ตฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค(--require CLI ์˜ต์…˜ ์‚ฌ์šฉ).

์Œ, "์˜ค์ด ์ฑ…"์€ ํŠนํžˆ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์˜ ๋‹จ๊ณ„ ์„ค๊ณ„๋ฅผ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹จ๊ณ„๋Š” ์„ค๊ณ„์ƒ ์‹œ๋‚˜๋ฆฌ์˜ค ๊ฐ„์— ๊ณต์œ ๋˜๋ฉฐ ๋™์ผํ•œ ๋ฌธ์žฅ์€ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ผ๊ด€๋œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ๊ณ„์˜ ๋ฒ”์œ„๋ฅผ ์†Œ๊ฐœํ•˜๋ฉด ์–ธ์–ด ํ•จ์ •์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์ •๋ง ์‰ฝ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€๋Š” cucuber.js์—์„œ ํƒœ๊ทธ๋งŒ ๋ชฉ์ ์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ›„ํฌ๋งŒ ํƒœ๊ทธ์—๋งŒ ํ•ด๋‹นํ•œ๋‹ค๊ณ  ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋‹น์‹ ์˜ ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•œ ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ํ™•์‹ ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹จ๊ณ„ ํŒจํ„ด์—์„œ [๊ธฐ๋Šฅ ์ด๋ฆ„]๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํ•œ DSL์„ ๋ฐœ๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@pinxue ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ์œ ์šฉํ•œ ์‘๋‹ต์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ดํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์Œ, "์˜ค์ด ์ฑ…"์€ ํŠนํžˆ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์˜ ๋‹จ๊ณ„ ์„ค๊ณ„๋ฅผ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ฐ™์€ ํ–‰๋™ ๋ฌธ๊ตฌ๊ฐ€ ๋‹ค๋ฅธ ๋งฅ๋ฝ์—์„œ ๋‹ค๋ฅธ ์˜๋ฏธ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ดœ์ฐฎ์•„. ๋‚ด๊ฐ€ ๊ฐ€์ง„ ์˜ต์…˜์„ ์•„๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๊ทธ๊ฒƒ์„ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€ DSL์„ ๋ฐŸ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

@pinxue ๋ฐ @robsonrosa์— ๋Œ€ํ•œ ๋‹ต๋ณ€์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
๋ฒ”์œ„ ๋‹จ๊ณ„ ์ •์˜์— ๋Œ€ํ•œ ๋‚ด ์ถ”๋ก ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. _์ „์—ญ ๋ณ€์ˆ˜๋Š” ๋‚˜์˜๊ณ  ํ™•์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค_:
    ๊ฐ๊ฐ 10๊ฐœ์˜ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์žˆ๋Š” ์•ฝ 15๊ฐœ์˜ ๊ธฐ๋Šฅ ํŒŒ์ผ ํŒŒ์ผ์ด ์žˆ์œผ๋ฉฐ ๋ชจ๋“  ๋‹จ๊ณ„ ์ •์˜์™€ ๊ธฐ๋Šฅ ํŒŒ์ผ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์€ ์ด๋ฏธ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ํฐ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ(์˜ˆ: ํ‰๊ท  5๋‹จ๊ณ„์˜ 10๊ฐœ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์žˆ๋Š” 100๊ฐœ์˜ ๊ธฐ๋Šฅ ํŒŒ์ผ)์˜ ๊ฒฝ์šฐ ๋ชจ๋“  ๋‹จ๊ณ„๋ฅผ ์ „์—ญ์ ์œผ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ๋ฏธ์นœ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ๊ธฐ๋Šฅ ํŒŒ์ผ์ด ์–ด๋–ค ๋‹จ๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์ถ”์ ํ•˜๊ธฐ๊ฐ€ ์ •๋ง ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
  2. _๊ฐœ๋ฐœ์ž๋Š” ๊ธฐ๋Šฅ ํŒŒ์ผ์˜ ๋ฌธ๊ตฌ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค_:
    ์šฐ๋ฆฌ์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ "๊ด€๋ฆฌ"๊ฐ€ ๊ธฐ๋Šฅ ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๊ณ  ํŒ๋งคํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ฉ‹์ง„ BDD๋ฅผ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ ์–ด์ƒ‰ํ•œ ์‚ฌ์šฉ์ž ์ง€์ • DSL๋กœ ์ž์‹ ์„ ์ œํ•œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  3. _์˜ค์ด-jvm์— ์˜ต์…˜์ด ์žˆ๋‹ค๋ฉด ์™œ ์˜ค์ด-js๋Š” ์—†๋‚˜์š”?_
    ์ด๊ฒƒ์€ ์ž˜๋ชป๋œ ์ฃผ์žฅ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ’ƒ

๋‚˜๋Š” ์šฐ๋ฆฌ๋ฅผ ์œ„ํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋ด…๋‹ˆ๋‹ค.

  1. ๋‹จ๊ณ„ ์ •์˜์— ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ง€์ • DSL ๋งŒ๋“ค๊ธฐ
    ๋‹จ์ : ์ž‘์—…ํ•˜๊ธฐ์— ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    ์žฅ์ : cucumber.js๋ฅผ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  2. ์˜ค์ด.js์šฉ glue ์ƒ์„ฑ
    ๋‹จ์ : "Cucumber Book"์˜ ๊ฐœ๋…์— ์–ด๊ธ‹๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์žฅ์ : cucumber.js ์˜ ๊ธฐ๋Šฅ ํŒจ๋ฆฌํ‹ฐ
  3. ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๋ฐฉ๋ฒ• ๋ณ€๊ฒฝ
    ๋‹จ์ : ์ด ๊ธฐ๋Šฅ์€ ๋” ์ ์€ ์‚ฌ๋žŒ๋“ค์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์žฅ์ : cucumber.js๋ฅผ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ฆ‰, ์˜ค์ด.js์˜ ์œ ์ง€ ๊ด€๋ฆฌ์ž๊ฐ€ ๋ฒ”์œ„๊ฐ€ ์ง€์ •๋œ ๋‹จ๊ณ„ ์ •์˜๊ฐ€ ์ด ํ”„๋กœ์ ํŠธ์˜ ๋ฒ”์œ„(๋ง์žฅ๋‚œ ์˜๋„)๋ฅผ ๋ฒ—์–ด๋‚ฌ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค๋ฉด ์•„๋งˆ๋„ 3.์œผ๋กœ ๊ฐˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@robsonrosa ์†”๋ฃจ์…˜์ด ์žˆ์œผ๋ฉด ์†”๋ฃจ์…˜์— ๊ด€์‹ฌ์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

IMO ๋ฒ”์œ„ ์ง€์ •์ด ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์„ฑ์žฅํ•จ์— ๋”ฐ๋ผ ๊ธฐ๋Šฅ์˜ ์ˆ˜๊ฐ€ ํ™•์žฅ๋˜๊ณ  ๋‹ค๋ฅธ ์ปจํ…์ŠคํŠธ์—์„œ ์„ค๋ช…์ด ์ถฉ๋Œํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ ํšŒ์‚ฌ์—์„œ ์šฐ๋ฆฌ ์ œํ’ˆ์—๋Š” ์ˆ˜๋ฐฑ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์ด ์žˆ๊ณ  QA์—๋Š” 10๋งŒ ๊ฐœ ๋ฒ”์œ„์˜ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
cucumber ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ถ„๋ช…ํžˆ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ๋ฒ”์œ„ ๋Œ€์‹  ์ปจํ…์ŠคํŠธ๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
์ „์ฒด๋Š” ์•„๋‹ˆ์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๋‹จ๊ณ„ ์ •์˜๋ฅผ ๊ธฐ๋ณธ ์ปจํ…์ŠคํŠธ(๋˜๋Š” ์ปจํ…์ŠคํŠธ ์—†์Œ)์— ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ ์‚ฌ์šฉ์ž ์ง€์ • DSL ์—†์ด ์ปจํ…์ŠคํŠธ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ BA ๋ฐ QA์ด๋ฉฐ ๋ชจ๋“  ์‚ฌ์šฉ์ž ์ง€์ • DSL์€ ํ˜ผ๋ž€๊ณผ ์ €ํ•ญ์„ ์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋Šฅ/์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ์ด๋ฏธ ์ •์˜์— ๋”ฐ๋ผ ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๋ฏ€๋กœ Gherkin ๊ตฌ๋ฌธ์— ๋“ค์—ฌ์“ฐ๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํƒœ๊ทธ ๋ฐ ์‚ฌ์šฉ์ž ์ •์˜ DSL์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์†”๋ฃจ์…˜ ๋Œ€์‹  ๊ตฌํ˜„ ์ œํ•œ(์˜ˆ: ํ•ดํ‚น, IMO)์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

https://github.com/cucumber/cucumber-js/issues/745 ๋ฅผ ๊ณ ๋ คํ•˜๋ฉด์„œ ์ด๊ฒƒ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

defineStep Scenario ๋ฅผ ํ™•์žฅํ•˜๊ณ  {Given, When, Then} ๋ฅผ ์ฝœ๋ฐฑ์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์ฆ‰:

import {defineSupportCode} from 'cucumber'

defineSupportCode(({ Scenario, Given, When, Then }) => {
  Given(...)
  When(...)
  Then(...)
  Scenario('<match scenario description>', ({ Given, When, Then}) => {
    Given('<take precedent of non-contexted>', ...)
    ...
  })
})

์ €๋Š” http://fitness.org/ ์—์„œ BDD๋ฅผ ๋ฐฐ์šฐ๋ฏ€๋กœ ์˜ค์ด ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ์™€ ๋‹ค๋ฅด๊ฒŒ BDD๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŽ˜์ด์ง• @richardlawrence

์ด๊ฒƒ์€ ์˜ค์ด๊ฐ€ ํŠนํžˆ ๋…๋‹จ์ ์ธ ์˜์—ญ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํŒ€์ด ์œ ๋น„์ฟผํ„ฐ์Šค ์–ธ์–ด๋ฅผ ์„ฑ์žฅ์‹œ์ผœ์•ผ ํ•œ๋‹ค๋Š” ๋ฏฟ์Œ์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋‹จ์–ด์™€ ๊ตฌ๋ฌธ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋งฅ๋ฝ์—์„œ ์ •ํ™•ํžˆ ํ•œ ๊ฐ€์ง€๋ฅผ ์˜๋ฏธํ•˜๊ณ  ์ผ๊ด€๋˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. defs global์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์€ ๋ชจํ˜ธ์„ฑ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๊ธ์ •์ ์ธ ์••๋ ฅ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ณ ์œ ํ•œ ๊ฒฝ๊ณ„ ์ปจํ…์ŠคํŠธ๊ฐ€ ์žˆ๋Š” ๋“œ๋ฌธ ๊ฒฝ์šฐ(DDD ์šฉ์–ด๋กœ), ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ํ•ด๋‹น ๊ฒฝ๊ณ„๋ฅผ ๋ฐ˜์˜ํ•˜๋„๋ก ๋ถ„ํ• ๋œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋ผ์ธ์„ ๋”ฐ๋ผ Cucumber ์ œํ’ˆ๊ตฐ์„ ๋‚˜๋ˆ„๋ฉด ๊ฐ ๊ฒฝ๊ณ„ ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ๋‹จ๊ณ„ ์ •์˜๊ฐ€ ์ „์—ญ์ ์œผ๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

Cucumber๋กœ ์ž‘์—…ํ•˜๊ณ  ๊ฒฝ๊ณ„๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ธฐ์‚ฌ์ž…๋‹ˆ๋‹ค. ์ด ํŽ˜์ด์ง€์˜ ์•„์ด๋””์–ด ์ค‘ ์ผ๋ถ€๋ฅผ ๊ตฌํ˜„ํ•˜์ง€๋งŒ @richardlawrence ๊ฐ€ ๋‹จ๊ณ„ ์ •์˜๋ฅผ ์œ„ํ•ด ํ•˜๋‚˜์˜ ํŠน์ • ํด๋ž˜์Šค์— ์ง‘์ค‘ํ•˜๋„๋ก Cucumber๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ํ›Œ๋ฅญํ•œ ์†”๋ฃจ์…˜์„ ์ œ์‹œํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. http://confessionsofanagilecoach.blogspot.com/2017/05/teaching-cucumbers-about-boundaries.html

@leipert ๊ฐ€ ๋งํ–ˆ๋“ฏ์ด ์ „์—ญ ๋ณ€์ˆ˜๋Š” ๋‚˜์ฉ๋‹ˆ๋‹ค. CucumberJVM ์„ธ๊ณ„์— ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์€ ์ด์•ผ๊ธฐ์˜ ์ ˆ๋ฐ˜๋งŒ ์ดํ•ดํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. Cucumber (non JVM)๋Š” Scenario ๊ธฐ๊ฐ„ ๋™์•ˆ ์ „์—ญ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์ธ ๊น”๋”ํ•œ World ๊ฐœ๋…์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์‹คํ–‰๋œ ํ›„ ํŒŒ๊ดด๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ข‹์€ ํ•ด๊ฒฐ์ฑ…์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ... CucumberJVM์—์„œ ์ด ํŒจํ„ด์˜ ์ข‹์€ ๊ตฌํ˜„์„ ๋ณด์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Cucumber๊ฐ€ ๋‹จ๊ณ„ ์ •์˜๋ฅผ ์œ„ํ•œ ํ”Œ๋žซ/๊ธ€๋กœ๋ฒŒ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๊ฐ–๋„๋ก ํ•˜๊ณ  CucumberJVM์ด World ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋ช…ํ™•ํ•œ ๋””์ž์ธ ํŒจํ„ด์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ์ €๋Š” ์กฐ๊ธˆ ๋” ํ–‰๋ณตํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๊นŒ์ง€๋Š” CucumberJVM + World pattern == ์ง€๋‚˜์น˜๊ฒŒ ๋ณต์žกํ•œ ์†”๋ฃจ์…˜์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๋‚ด๊ฐ€ ๋ณธ ๋ชจ๋“  ๊ฒƒ์€ ๋‹จ์ˆœํžˆ ์–ด๋–ค ๋‹จ๊ณ„ ๊ธฐ๋Šฅ์ด ์–ด๋–ค ๊ธฐ๋Šฅ ํŒŒ์ผ๊ณผ ํ•จ๊ป˜ ๊ฐˆ์ง€ ์ œ์–ดํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๋‚ด๊ฐ€ ๋ณธ ๋Œ€์•ˆ์€ ๋ชจ๋“  ๋…ธ๋ ฅ/๋ณต์žก์„ฑ์— ๋Œ€ํ•ด ์ด๋ณด๋‹ค ๋” ๊ฐ€์น˜ ์žˆ๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์œ ํ˜•์˜ ์˜ค์ด์—๋Š” ๋” ๋‚˜์€ ์„ธ๊ณ„ ์†”๋ฃจ์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ถ๊ทน์ ์œผ๋กœ World ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๊ธฐ๋Šฅ ํŒŒ์ผ์—์„œ ๋‹จ๊ณ„๋กœ ์ด๋™ํ•  ๋•Œ ์ •๋ณด ์†์‹ค์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ ๋ถˆํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ๊ธฐ๋Šฅ ํŒŒ์ผ์„ ์ข‹์€ ์กฐ์ง์— ๋ฐฐ์น˜ํ•˜๊ณ , ๊ธฐ๋Šฅ ํŒŒ์ผ ์ด๋ฆ„์„ ์ž˜ ๋งŒ๋“ค๊ณ , ๊ธฐ๋Šฅ์„ ํ˜„๋ช…ํ•˜๊ฒŒ ์„ ์–ธํ•˜๊ณ , ์‹œ๋‚˜๋ฆฌ์˜ค ์ด๋ฆ„์„ ํ˜„๋ช…ํ•˜๊ฒŒ ์ง€์ •ํ•˜๋ฉด ๋ชจ๋“  ์ปจํ…์ŠคํŠธ๊ฐ€ ์ฐฝ ๋ฐ–์œผ๋กœ ๋˜์ ธ์ง€๊ณ  ๊ฐ•์ œ๋กœ ์ „์—ญ ๋‹จ๊ณ„ ์ •์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์‹œ์Šคํ…œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์—์„œ ๊ด€๊ณ„๋ฅผ ์œ ์ง€ํ•˜๊ณ  ํ…Œ์ŠคํŠธ ๊ฒฝ๋กœ์— ์™€์ผ๋“œ์นด๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ผ๋ถ€ ์˜คํ”ˆ ์†Œ์Šค ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ๋งŒ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๊ฐ€ ์„ฑ์žฅํ•จ์— ๋”ฐ๋ผ ๊ธฐํšŒ๋ฅผ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ท€ํ•˜์˜ ๋ชฉํ‘œ๋Š” ์ดํ•ดํ•˜์ง€๋งŒ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ๋ฐฐ๊ฒฝ ์„ค๋ช…์ด๋‚˜ ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋งŒ๋“œ๋Š” ์ถ”๊ฐ€ Given ๋‹จ๊ณ„์™€ ํ•จ๊ป˜ ๋ช…์‹œ์  .feature ํŒŒ์ผ์„ ๊ฐ–๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋˜๋Š” ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ํŒŒ์ผ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜๋‚˜๋Š” ์ƒ˜ํ”Œ ์šฉ์ด๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์˜ˆ์ œ์šฉ์ž…๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค๋ฅธ ๋‹จ๊ณ„ ํด๋”๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@robsonrosa @leipert ๋‹น์‹ ์˜ ์˜๊ฒฌ์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค
์›๋ž˜ ๊ฒŒ์‹œ๋ฌผ ์ดํ›„ ๊ฑฐ์˜ 2 ๋…„ ...
๊ทธ๋กœ ์ธํ•ด ์ง„์ „์ด ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ? ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@cristianmercado19 ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์•„๋‹™๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋” ์ด์ƒ ์˜ค์ด js๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Up... ์ €๋Š” ๋‹จ๊ณ„์˜ ๊ตฌํ˜„๊ณผ ์™„์ „ํžˆ ๋ถ„๋ฆฌ๋œ ๊ธฐ๋Šฅ ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.
_mocha_๋กœ ๊ฐ™์€ ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ์ง€๋งŒ ๋งŒ์กฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋‚ด ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑํ•˜๋Š” ๋‹ค๋ฅธ ๋Œ€์•ˆ์ด ์žˆ๋‹ค๋ฉด ๊ธฐ๊บผ์ด ์‹œ๋„ํ•ด๋ณด์‹ญ์‹œ์˜ค.
๋„์›€์„ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @leipert .

์ด ์Šค๋ ˆ๋“œ๋Š” ๋‹ซํžŒ ํ›„ ์ตœ๊ทผ ํ™œ๋™์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™์œผ๋กœ ์ž ๊ฒผ์Šต๋‹ˆ๋‹ค. ๊ด€๋ จ ๋ฒ„๊ทธ์— ๋Œ€ํ•œ ์ƒˆ ๋ฌธ์ œ๋ฅผ ์—ฌ์‹ญ์‹œ์˜ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰