elasticsteps

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2022 License: MIT Imports: 8 Imported by: 0

README

Cucumber ElasticSearch steps for Golang

GitHub Releases Build Status codecov Go Report Card GoDevDoc

elasticsteps provides steps for cucumber/godog and makes it easy to run tests with ElasticSearch.

Prerequisites

  • Go >= 1.17

Usage

Setup

Initiate an elasticsteps.Manager and register it to the scenario using one of the supported drivers:

Driver Constructor
elastic/go-elasticsearch/v7 driver/go-elasticsearch/v7
olivere/elastic
package mypackage

import (
	"bytes"
	"math/rand"
	"testing"

	"github.com/cucumber/godog"
	elasticsearch "github.com/elastic/go-elasticsearch/v7"
	"github.com/stretchr/testify/require"

	elasticsearch7 "github.com/godogx/elasticsteps/driver/go-elasticsearch/v7"
)

func TestIntegration(t *testing.T) {
	out := bytes.NewBuffer(nil)

	es, err := elasticsearch.NewClient(elasticsearch.Config{
		Addresses: []string{"127.0.0.1:9200"},
	})
	require.NoError(t, err)

	// Create a new grpc client.
	manager := elasticsearch7.NewManager(es,
		// If you have another server, you could register it as well, for example:
		// elasticsearch7.WithInstance("another_instance", es),
	)

	suite := godog.TestSuite{
		Name:                 "Integration",
		TestSuiteInitializer: nil,
		ScenarioInitializer: func(ctx *godog.ScenarioContext) {
			// Register the client.
			manager.RegisterContext(ctx)
		},
		Options: &godog.Options{
			Strict:    true,
			Output:    out,
			Randomize: rand.Int63(),
		},
	}

	// Run the suite.
	if status := suite.Run(); status != 0 {
		t.Fatal(out.String())
	}
}
Steps
Create a new index

Create a new index in the instance. If the index exists, the manager will throw an error.

  • index "([^"]*)" is created$
  • index "([^"]*)" is created in es "([^"]*)"$ (if you want to create in the other instance)

For example:

Given index "products" is created

You could create a new index with a custom config by running:

  • index "([^"]*)" is created with config[:]?$
  • index "([^"]*)" is created in es "([^"]*)" with config[:]?$
  • index "([^"]*)" is created with config from file[:]?$
  • index "([^"]*)" is created in es "([^"]*)" with config from file[:]?$

For example:

Given index "products" is created with config:
"""
{
    "mappings": {
        "properties": {
            "size": {
                "type": "integer"
            },
            "name": {
                "type": "keyword"
            },
            "description": {
                "type": "text"
            }
        }
    }
}
"""

or

Given index "products" is created with config from file:
"""
../../resources/fixtures/mapping.json
"""
Recreate an index

Create a new index in the instance if it does not exist, otherwise the index will be deleted and recreated.

  • index "([^"]*)" is recreated$
  • there is (?:an )?index "([^"]*)"$
  • index "([^"]*)" is recreated in es "([^"]*)"$ (if you want to recreate in the other instance)
  • there is (?:an )?index "([^"]*)" in es "([^"]*)"$ (if you want to recreate in the other instance)

For example:

Given index "products" is recreated

or

Given there is index "products"

Same as [#Create a new index](#Create a new index), you could recreate an index with a custom config:

  • Inline
    • index "([^"]*)" is recreated with config[:]?$
    • there is (?:an )?index "([^"]*)" with config[:]?$
  • From a file
    • index "([^"]*)" is recreated with config from file[:]?$
    • there is (?:an )?index "([^"]*)" with config from file[:]?$
  • Inline (for other instances)
    • index "([^"]*)" is recreated in es "([^"]*)" with config[:]?$
    • there is (?:an )?index "([^"]*)" in es "([^"]*)" with config[:]?$
  • From a file (for other instances)
    • index "([^"]*)" is recreated in es "([^"]*)" with config from file[:]?$
    • there is (?:an )?index "([^"]*)" in es "([^"]*)" with config from file[:]?$
Delete an index

Delete an index in the instance. If the index does not exist, the manager will throw an error.

  • no index "([^"]*)"$
  • no index "([^"]*)" in es "([^"]*)"$ (if you want to delete in the other instance)

For example:

Given no index "products"
Index Documents
  • these docs are stored in index "([^"]*)"[:]?$
  • these docs are stored in index "([^"]*)" of es "([^"]*)"[:]?$ (if you want to index in the other instance)

For example:

Given these docs are stored in index "products":
"""
[
    {
        "_id": "41",
        "_source": {
            "handle": "item-41",
            "name": "Item 41",
            "locale": "en_US"
        }
    }
]
"""

You can also send the docs from a file by using:

  • docs (?:in|from) this file are stored in index "([^"]*)"[:]?$
  • docs (?:in|from) this file are stored in index "([^"]*)" of es "([^"]*)"[:]?$ (if you want to index in the other instance)

For example:

Given docs in this file are stored in index "products":
"""
../../resources/fixtures/products.json
"""
Check whether an index exists
  • index "([^"]*)" exists$
  • index "([^"]*)" exists in es "([^"]*)"$ (if you want to check the other instance)

For example:

Then index "products" exists
Check whether an index does not exist
  • index "([^"]*)" does not exist$
  • index "([^"]*)" does not exist in es "([^"]*)"$ (if you want to check the other instance)

For example:

Then index "products" does not exist
Check there is no document in the index
  • no docs are available in index "([^"]*)"$
  • no docs are available in index "([^"]*)" of es "([^"]*)"$ (if you want to check the other instance)

For example:

Then no docs are available in index "products"
Check whether index contains the exact documents
  • only these docs are available in index "([^"]*)"[:]?$
  • only these docs are available in index "([^"]*)" of es "([^"]*)"[:]?$ (if you want to check the other instance)

For example:

Then only these docs are available in index "products":
"""
[
    {
        "_id": "41",
        "_source": {
            "handle": "item-41",
            "name": "Item 41",
            "locale": "en_US"
        },
        "_score": 1,
        "_type": "_doc"
    },
    {
        "_id": "42",
        "_source": {
            "handle": "item-42",
            "name": "Item 42",
            "locale": "en_US"
        },
        "_score": 1,
        "_type": "_doc"
    }
]
"""

You can also get the expected docs from a file by using:

  • only docs (?:in|from) this file are available in index "([^"]*)"[:]?$
  • only docs (?:in|from) this file are available in index "([^"]*)" of es "([^"]*)"[:]?$ (if you want to index in the other instance)

For example:

Given only docs in this file are available in index "products":
"""
../../resources/fixtures/result.json
"""
Query documents
  • First step: Setup the query
    I search in index "([^"]*)" with query[:]?$
    I search in index "([^"]*)" of es "([^"]*)" with query[:]?$
  • Second step: Check the result
    these docs are found in index "([^"]*)"[:]?$
    these docs are found in index "([^"]*)" of es "([^"]*)"[:]?$

For example:

When I search in index "products" with query:
"""
{
    "query": {
        "match": {
            "locale": "en_US"
        }
    }
}
"""

Then these docs are found in index "products":
"""
[
    {
        "_id": "41",
        "_source": {
            "handle": "item-41",
            "name": "Item 41",
            "locale": "en_US"
        },
        "_score": "<ignore-diff>",
        "_type": "_doc"
    },
    {
        "_id": "42",
        "_source": {
            "handle": "item-42",
            "name": "Item 42",
            "locale": "en_US"
        },
        "_score": "<ignore-diff>",
        "_type": "_doc"
    }
]
"""

You can also get the expected docs from a file by using:

  • docs (?:in|from) this file are found in index "([^"]*)"[:]?$
  • docs (?:in|from) this file are found in index "([^"]*)" of es "([^"]*)"[:]?$ (if you want to index in the other instance)

For example:

Given docs in this file are found in index "products":
"""
../../resources/fixtures/result.json
"""

Documentation

Overview

Package elasticsteps provides steps for testing with elasticsearch using godog.

Index

Constants

This section is empty.

Variables

View Source
var ErrIndexNotFound = errors.New("index not found")

ErrIndexNotFound indicates that the index is not found.

Functions

This section is empty.

Types

type Client

Client is an interface for interacting with Elasticsearch.

type Document

type Document struct {
	ID     string          `json:"_id"`
	Source json.RawMessage `json:"_source"`
}

Document represents an Elasticsearch doc. nolint: tagliatelle

func (*Document) UnmarshalJSON

func (d *Document) UnmarshalJSON(data []byte) error

UnmarshalJSON compacts document body while marshaling.

type DocumentDeleter added in v0.3.0

type DocumentDeleter interface {
	DeleteAllDocuments(ctx context.Context, index string) error
}

DocumentDeleter deletes documents.

type DocumentFinder

type DocumentFinder interface {
	FindDocuments(ctx context.Context, index string, query *string) ([]json.RawMessage, error)
}

DocumentFinder gets documents.

type DocumentIndexer

type DocumentIndexer interface {
	IndexDocuments(ctx context.Context, index string, documents ...Document) error
}

DocumentIndexer indexes documents.

type IndexCreator

type IndexCreator interface {
	CreateIndex(ctx context.Context, index string, config *string) error
	RecreateIndex(ctx context.Context, index string, config *string) error
}

IndexCreator creates indices.

type IndexDeleter

type IndexDeleter interface {
	DeleteIndex(ctx context.Context, indices ...string) error
}

IndexDeleter deletes indices.

type IndexGetter

type IndexGetter interface {
	GetIndex(ctx context.Context, index string) (json.RawMessage, error)
}

IndexGetter gets index.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager manages the elasticsearch data.

func NewManager

func NewManager(client Client, opts ...ManagerOption) *Manager

NewManager initiates a new data manager.

func (*Manager) RegisterContext

func (m *Manager) RegisterContext(sc *godog.ScenarioContext)

RegisterContext registers the manager to the test suite.

type ManagerOption

type ManagerOption func(m *Manager)

ManagerOption sets up the manager.

func WithInstance

func WithInstance(name string, client Client) ManagerOption

WithInstance adds a new es instance.

type SearchResult

type SearchResult struct {
	Hits SearchResultHits
}

SearchResult represents the search result.

type SearchResultHits

type SearchResultHits struct {
	Total    SearchResultHitsTotal `json:"total"`
	MaxScore *float64              `json:"max_score"`
	Hits     SearchResultHitsHits  `json:"hits"`
}

SearchResultHits represents the hits. nolint: tagliatelle

type SearchResultHitsHits

type SearchResultHitsHits []json.RawMessage

SearchResultHitsHits represents the hits.hits.

func (*SearchResultHitsHits) UnmarshalJSON

func (h *SearchResultHitsHits) UnmarshalJSON(data []byte) error

UnmarshalJSON removes unwanted fields.

type SearchResultHitsTotal

type SearchResultHitsTotal struct {
	Value    int    `json:"value"`
	Relation string `json:"relation"`
}

SearchResultHitsTotal represents the hits.total.

Directories

Path Synopsis
driver
go-elasticsearch/v7
Package elasticsearch7 provides the client using go-elasticsearch driver.
Package elasticsearch7 provides the client using go-elasticsearch driver.
features
bootstrap
Package bootstrap provides integration tests.
Package bootstrap provides integration tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL