Cucumber + python = behave?

cucumber를 python에서 사용하는게 있지 않을 까 해서 찾아봤는데..있었다. behave를 사용하면 되었다.

설치는

pip install behave

사용법은 cucumber와 비슷하다. 일단 디렉토리 구성이 아래와 같아야 한다.

└── features
    └── steps

*.feature파일들은 features 디렉토리에 위치하며, 실행 python파일은 steps디렉토리에 위치하게 된다.

시작은 *.feature파일의 작성으로 시작한다.

믹서기(blender)의 기능을 예로 들어 본다면 1

# filename : behaveTest.feature
Feature : Testing Blender

   Scenario : put apple into blender
      Given I put "apples" in a blender
      When I switch the blender on
      Then It should transform into "apple juice"

Given, When, Then을 apples를 넣으면 apple juice가 나온다는 시나리오이다.

테스트 하려는 Blender 모델이다.

# filename : blender.py
class Blender:
    TRANSFORMATION_MAP = {
        "Red Tree Frog": "mush",
        "apples": "apple juice",
        "iPhone": "toxic waste",
        "Galaxy Nexus": "toxic waste",
    }
    def __init__(self):
        self.thing  = None
        self.result = None

    def add(self, thing):
        self.thing = thing

    def switch_on(self):
        self.result = self.TRANSFORMATION_MAP.get(self.thing, "DIRT")

TRANSFORMATION_MAP은 이 블렌더의 기능을 정의한다. apples를 넣으면 apple juice, iPhone을 넣으면 toxic waste가 나오는 것으로 되어 있다.

feature와 물려 실행되는 테스트 코드는 아래와 같다.

# filename : tutorial.py

from behave   import given, when, then
from hamcrest import assert_that, equal_to
from blender import Blender

@given('I put "{things}" in a blender')
def step_given_things_into_blender(context, things):
    context.blender = Blender()
    context.blender.add(things)


@when('I switch the blender on')
def step_when_switch_blender_on(context):
    context.blender.switch_on()

@then('it should be transfer into "{other_thing}"')
def sten_then_should_transfer_into(context,other_thing):
    assert_that(context.blender.result, equal_to(other_thing))
    


여기서는 Pyhancrest를 설치하여 assert를 사용하였다.

@given단계 에서는 Blender 객체를 불러 여기에 전달받은 ‘things’ 를 add() 한다.

@when단계 에서는 Blender 객체의 switch_on() 를 실행한다.

@then단계 에서는 Blender객체의 result값과 조건에서 받은 {other_thing}을 비교하여 pass, fail을 판정한다.

이제 테스트를 수행해 보면

$ behave behaveTest.feature
Feature: Step Parameters (tutorial.py) # behaveTest.feature:1

  Scenario: Apple                                 # behaveTest.feature:2
    Given I put "apples" in a blender             # steps/tutorial.py:5 0.000s
    When I switch the blender on                  # steps/tutorial.py:11 0.000s
    Then it should be transfer into "apple juice" # steps/tutorial.py:15 0.000s

1 feature passed, 0 failed, 0 skipped
1 scenario passed, 0 failed, 0 skipped
3 steps passed, 0 failed, 0 skipped, 0 undefined
Took 0m0.001s

테스트로 시나리오를 하나 더 붙여보자.

# filename : behaveTest.feature

Feature: Step Parameters (tutorial.py)
    Scenario: Apple 
        Given I put "apples" in a blender 
        When I switch the blender on
        Then it should be transfer into "apple juice"


    Scenario: iPhone
        Given I put "iPhone" in a blender 
        When I switch the blender on
        Then it should be transfer into "toxic waste"

iPhone 시나리오에서 iPhone을 넣으면 “toxic waste” 가 나온다.

$ behave behaveTest.feature
Feature: Step Parameters (tutorial.py) # behaveTest.feature:1

  Scenario: Apple                                 # behaveTest.feature:2
    Given I put "apples" in a blender             # steps/tutorial.py:5 0.000s
    When I switch the blender on                  # steps/tutorial.py:11 0.000s
    Then it should be transfer into "apple juice" # steps/tutorial.py:15 0.000s

  Scenario: iPhone                                # behaveTest.feature:8
    Given I put "iPhone" in a blender             # steps/tutorial.py:5 0.000s
    When I switch the blender on                  # steps/tutorial.py:11 0.000s
    Then it should be transfer into "toxic waste" # steps/tutorial.py:15 0.001s

1 feature passed, 0 failed, 0 skipped
2 scenarios passed, 0 failed, 0 skipped
6 steps passed, 0 failed, 0 skipped, 0 undefined
Took 0m0.002s

QA업무의 방향은 점점 자동화로 넘어가는 추세이다. 테스트 케이스를 엑셀이나 텍스트로 작성하는 것은 이제 제3자 테스터들의 업무로 넘어가고 있다. 이 글을 읽는 분들은 개발의 경험이 있을거라 생각되기 때문에 테스트 케이스는 이런 Cucumber의 형식을 사용하여 정리하는게 테스트 케이스도 정리하고 자동화까지 한번에 커버하는 방법이 아닐 까 한다.

  1. https://jenisys.github.io/behave.example/tutorials/tutorial03.html