/func-test-demo

Demo how to use godog to write BDD tests

Primary LanguageGo

Demo functional test with Godog

This repository is an example of how to use cucumber/godog to write Behavior Driven Test with Gherkin Language.

Pre-requisites

Kubernetes cluster

You can install MicroK8s to quickly standup a kubernetes cluster.

sudo snap install microk8s --channel 1.24/stable
microk8s status --wait-ready

microk8s enable dns rbac

Postgres

Once the cluster is fully ready, install Postgres using the charts located here

Create the namespace

kubectl create ns func-test

Install Postgres

If your system do not have HugePages-2Mi enabled.

kubectl create ns func-test
helm upgrade --install --namespace func-test postgres -f hack/manifests/postgres/values-default.yaml hack/manifests/postgres/

But if your system has HugePages-2Mi enabled use the values-hugepages.yaml

helm upgrade --install --namespace func-test postgres -f hack/manifests/postgres/values-default.yaml -f hack/manifests/postgres/values-hugepages.yaml hack/manifests/postgres/

Check Postgres

After the helm install, wait for Postgres to be available

kubectl wait deployment -n func-test postgres --for condition=Available=True --timeout=90s

Setup the tables

We will be creating a table called ingredients_thresholds, which will contain how much an ingredient to add to make a perfect Hawaiian pizza.

First, the perfect ingredients of a pizza are stored in a database table called ingredients_threshold

Currently defined as something like this

CREATE TABLE IF NOT EXISTS ingredients_thresholds (
   id SERIAL PRIMARY KEY,
   ingredient_type VARCHAR(10) NOT NULL,
   min_value NUMERIC(4,2) NOT NULL,
   max_value NUMERIC(4,2) NOT null,
   for_crust_size NUMERIC(4,2) not NULL
)

The columns :

min_value : defines the minimum parts of an ingredient to add. max_value : defines the maximum parts of an ingredient to add. for_crust_size : indicates the ingredients for a particular size of a crust. ingredient_type : Defined as H for Ham, T for tomatoand P for pineapple

To determine whether the hawaiian pizza is perfect, is that the chef must only add the type of ingredient within the range of the min_value and max_value

Running the functional test

Install godog

We will be using the godog to run our functional test.

In order to use godog, first you need to install godog

go install github.com/cucumber/godog/cmd/godog@latest

Feature file

The feature is defined in the file

For this particular test, he system will tell whether the hawaiian pizza is created perfectly or not.

Populating the table

Before starting the test, the table ingredients_thresholds is truncated using the BeforeScenario.

Example:

	ctx.BeforeScenario(func(sc *godog.Scenario) {
		fmt.Println("do anything before starting the scenario")
		b.cleanup()
	})

The data is populated at every Given step.

Example in the feature file.

| min | max | ingredient_type | crust size |
| 10 | 30   | H | 12|
| 10 | 30   | P | 12|
| 0.5 | 1.0   | T | 12|
| 5 | 15   | H | 10|
| 10 | 15   | P | 10|
| 0.25 | 0.55   | T | 10|

The code inserts the data into the ingredients_thresholds table, via this piece of code.

func (b *basket) withIngredientsThresholds(ingredients *godog.Table) error

Parsing the functional Tests

	//Given
	ctx.Step(`^the following thresholds$`, b.withIngredientsThresholds)

	//When
	ctx.Step(`^the crust size is (\d+) inches$`, b.withCrustSize)
	ctx.Step(`^the ingredients "([^"]*)", "([^"]*)", "([^"]*)"$`, b.withIngredients)
	// Then
	ctx.Step(`^it should be a "([^"]*)" pizza$`, b.ofQuality)

Please refer to make_pizza_test.go

Business logic

Let us pretend that our business logic is stored in the code pizza.go, the method CookPizza is where it returns the value perfect or not perfect

Example scenarios

This functional test utilizes the Example feature of Gherkin language.

So we will assume that the chef will make several pizza with the following contents

| crust_size | tomato | pineapple | hams | status |
| 12 | 0.25   | 5 | 20 | not perfect|
| 10 | 0.50   | 10 | 10 | perfect|
| 18 | 0.50   | 10 | 80 | not perfect|

The table above also indicates whether the applied ingredients can result to a perfect or not perfect hawaiian pizza.

Godog in action

Finally we will be running the functional test. We will be using the godog command to run the test.

Sample output

$ godog run

Feature: Making a hawaiian pizza
  I want to make a pizza
do anything before starting the scenario

  Scenario: Make a perfect pizza                            # features/make_pizza.feature:4
    Given the following thresholds                          # <autogenerated>:1 -> *basket
      | min  | max  | ingredient_type | crust size |
      | 10   | 30   | H               | 12         |
      | 10   | 30   | P               | 12         |
      | 0.5  | 1.0  | T               | 12         |
      | 5    | 15   | H               | 10         |
      | 10   | 15   | P               | 10         |
      | 0.25 | 0.55 | T               | 10         |
    When the crust size is 12 inches                        # <autogenerated>:1 -> *basket
    And the ingredients "<tomato>", "<pineapple>", "<hams>" # <autogenerated>:1 -> *basket
    Then it should be a "<status>" pizza                    # <autogenerated>:1 -> *basket

    Examples:
      | crust_size | tomato | pineapple | hams | status      |
      | 12         | 0.25   | 5         | 20   | not perfect |
do anything before starting the scenario
      | 10         | 0.50   | 10        | 10   | perfect     |
do anything before starting the scenario
      | 18         | 0.50   | 10        | 80   | not perfect |

3 scenarios (3 passed)
12 steps (12 passed)
216.342527ms

Use go test

You can also use go test to run the test by adding the TestMain into the make_pizza_test.go

The repo contains how to "debug" the test, check out the launch.json using the "Test Current File"