Skip to content

Latest commit

 

History

History
162 lines (134 loc) · 5.87 KB

yamlJestScenario.md

File metadata and controls

162 lines (134 loc) · 5.87 KB

How to Write Jest Scenarios in YAML

You can write tests in YAML, and Echoed will convert them into Jest tests.

Compile

Executing npx echoed compile converts YAML files into Jest tests.

Compilation flow

Note that, because each YAML file is transformed into a Jest test file, Jest runs tests serially.

Scenario

Tests converted from YAML is called scenario.

You can create a scenario like below:

variable:
  productId: OLJCESPC7Z
scenarios:
  - name: Get product detail
    steps:
      - description: fetch /products/{id}
        act:
          runner: fetch
          argument:
            endpoint: /products/${productId}
        assert:
          - expect(_.jsonBody.id).toBe(productId)

For more complex scenario, you can include additional options:

retry: 3 # <- You can retry failed tests.
variable:
  productId: OLJCESPC7Z # <- You can define variables for corresponding scope.
  db: ${connectDB()} # <- You can call plugin with ${...}.
runners:
  - runner: fetch # <- You can override option of runners.
    option:
      baseEndpoint: ${_env.BASE_ENDPOINT}/api
      headers:
        content-type: application/json
hook:
  beforeEach: # <- You can run a function before each scenario. (beforeAll, afterEach, afterAll are available too.)
    - bind:
        productName: ${db.insertProduct()} # <- You can use `bind` in hook
  afterEach:
    - db.cleanup()
scenarios:
  - name: Adding item to cart
    variable:
      session: ${createSession()} # <- You can use the returned value of function or variable with ${...}.
    steps:
      - description: Add a product to cart
        arrange:
          - db.createUser(session.userId) # <- You can establish preconditions in `arrange`.
        act:
          runner: fetch # <- You can use built-in runner or create custom one. This `fetch` executes HTTP request to `/cart` with query.
          argument:
            endpoint: /cart?currencyCode=${session.currencyCode}
            method: POST
            jsonBody:
              item:
                productId: ${productId}
                quantity: 1
              userId: ${session.userId}
          option:
            baseEndpoint: ${_env.BASE_ENDPOINT}/api # <- You can reference environment variables defined in config with `_env`.
            headers:
              content-type: application/json
        assert:
          - assertStatus: # <- You can use built-in asserter or create custom one. This `assertStatus` checks the status code of the response.
            - ${_.response} # <- You can reference the result of `act` with `_` variable.
            - 200
          - expect(_.jsonBody.items.length).toBe(1)  # <- You can write Jest's assertion directly too.
          - |
            expect(_.jsonBody).toEqual({
              items: [ { productId, quantity: 1 } ],
              userId: session.userId,
            })
        bind:
          itemQuantity: ${_.jsonBody.items[0].quantity} # <- You can reference value outside step's scope with `bind`.
      - description: Check Span
        act:
          runner: waitForSpan # <- This built-in `waitForSpan` waits for the OpenTelemetry's span that matches the condition.
          argument:
            response: ${_steps[-1].response} # <- You can reference the result of previous step's act with `_steps` variable.
            filter:
              name: oteldemo.CartService/AddItem
              resource:
                attributes:
                  service.name: cartservice
              attributes:
                rpc.method: AddItem
        assert:
          - expect(_.getAttribute("app.product.quantity").value.intValue).toBe(itemQuantity)

For more examples, refer to example/scenario directory.

Syntax

The essential elements of YAML include the following:

variable

variable can be defined at various places in YAML, serving the same purpose: "define variables and use them in corresponding scope".
For instance, the following snippet defines foo variable with 123(number):

variable:
  foo: 123

Once variables are defined, you can use them as ordinal variables or in the middle of string by surrounding it with ${}:

argument:
  endpoint: /products/${foo} # <- string ("/products/123")
  myArg: ${foo} # <- number (123)

When you use ${} within a string, it gets replaced with the value of the variable.

hook

hook is used to define functions that are called before or after each scenario or whole scenarios in YAML.

scenarios

scenarios represent a collection of scenarios that define what tests are to be executed.

Each scenarios comprises the following elements:

scenarios.name

scenarios.name specifies the name of the scenario.

scenarios.steps

scenarios.steps are used to define a collection of steps that specify the actions to be taken.

Each scenarios.steps in a scenarios consists of the following elements:

scenarios.steps.arrange

scenarios.steps.arrange is used to establish preconditions before scenarios.steps.act.

scenarios.steps.act

scenarios.steps.act defines the action the test performs, such as an HTTP request.

scenarios.steps.assert

scenarios.steps.assert is to compare the result of scenarios.steps.act with an expected value.
You can use predefined asserter or write Jest's assertions directly.

scenarios.steps.bind

scenarios.steps.bind defines variables that can be used in subsequent steps.
For example, you can store the result of scenarios.steps.act.

These are the primary elements of YAML, and this overview does not cover all elements.
For a full list, refer to jestScenarioYamlSchema.ts.

Common Features

Refer to scenario.md for common features.