componenttest

package module
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Mar 14, 2024 License: MIT Imports: 23 Imported by: 27

README

dp-component-test

Library to help write feature-level tests against a REST api / microservice or web application

The steps available to use from this library are described in STEP_DEFINITIONS.md.

For help and examples of using this library please see USAGE.md.

Background

The intention of this library is to help when writing component tests for a new or existing component (microservice or web application). The library contains a set of useful helper steps to make writing new gherkin tests easy.

The steps in api_feature have been written as to be easily reusable when setting up tests against a REST API, and there are other additional parts of this library which can be plugged in to help test outputs of the tests e.g. setting up an in memory mongo to assert against changes to the database.

Similarly, the steps in ui_feature have been written as to be easily reusable when setting up tests against a web application.

Installation

To install this package in your project simply run:

go get github.com/ONSdigital/dp-component-test

Running tests

go test -component

This package uses the Godog BDD framework. For instructions on writing Godog tests it is best to follow the instructions found here

Testing a REST API

To integrate your REST API component tests with this library all you need to do is update your root level test file to pass the http handler of your application to our NewAPIFeature, register the steps and add the reset function to the BeforeScenario function.

package main

import (
	componenttest "github.com/ONSdigital/dp-component-test"
)

var componentFlag = flag.Bool("component", false, "perform component tests")

func InitializeScenario(ctx *godog.ScenarioContext) {
	myAppComponent := NewMyAppComponent() // This is the part that YOU will implement
	apiFeature := componenttest.NewAPIFeature(myAppComponent.Handler)

	ctx.BeforeScenario(func(*godog.Scenario) {
		apiFeature.Reset()
	})
	ctx.AfterScenario(func(*godog.Scenario, error) {
	})

	apiFeature.RegisterSteps(ctx)
}

func InitializeTestSuite(ctx *godog.TestSuiteContext) {
	ctx.BeforeSuite(func() {
	})
}

func TestComponent(t *testing.T) {
	if *componentFlag {
		var opts = godog.Options{
			Output: colors.Colored(os.Stdout),
			Format: "pretty",
			Paths:  flag.Args(),
		}
		
		status := godog.TestSuite{
			Name:                 "component_tests",
			ScenarioInitializer:  InitializeScenario,
			TestSuiteInitializer: InitializeTestSuite,
			Options:              &opts,
		}.Run()

		if status > 0 {
			t.Fail()
        }
	} else {
		t.Skip("component flag required to run component tests")
	}
}

Testing a web application

To integrate your web application component tests with this library all you need to do is update your root level test file to pass the base URL of your application to our NewUIFeature, register the steps, add the reset function to the BeforeScenario function and add the close function to the AfterScenario function.

package main

import (
	componenttest "github.com/ONSdigital/dp-component-test"
)

var componentFlag = flag.Bool("component", false, "perform component tests")

func InitializeScenario(ctx *godog.ScenarioContext) {
	myAppComponent := NewMyAppComponent() // This is the part that YOU will implement
	uiFeature := componenttest.NewUIFeature("http://" + myAppComponent.Config.SiteDomain + myAppComponent.Config.BindAddr)

	ctx.BeforeScenario(func(*godog.Scenario) {
		uiFeature.Reset()
	})
	ctx.AfterScenario(func(*godog.Scenario, error) {
		uiFeature.Close()
	})

	uiFeature.RegisterSteps(ctx)
}

func InitializeTestSuite(ctx *godog.TestSuiteContext) {
	ctx.BeforeSuite(func() {
	})
}

func TestComponent(t *testing.T) {
	if *componentFlag {
		var opts = godog.Options{
			Output: colors.Colored(os.Stdout),
			Format: "pretty",
			Paths:  flag.Args(),
		}

		status := godog.TestSuite{
			Name:                 "component_tests",
			ScenarioInitializer:  InitializeScenario,
			TestSuiteInitializer: InitializeTestSuite,
			Options:              &opts,
		}.Run()

		if status > 0 {
			t.Fail()
		}
	} else {
		t.Skip("component flag required to run component tests")
	}
}

Repository structure

The features that can be used all exist on the root level of the project.

The examples folder contains four different examples of how to use this library, each using different features and having a slightly different way of setting up.

Adding new component test features

If you feel like there are handy common steps missing from this library which you would like to add, please do!

The mechanism by which the tests and steps are validated (testing the test library) is through feature tests in the examples which get exercised in the CI pipeline. If you add any new steps, make sure you also add sufficient feature tests to exercise them in appropriate examples in the examples folder.

If you are adding a new testing feature entirely, it might be worth adding a new example service which exercises the steps of any new feature you add.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIFeature

type APIFeature struct {
	ErrorFeature
	Initialiser       ServiceInitialiser
	HTTPResponse      *http.Response
	BeforeRequestHook func() error
	// contains filtered or unexported fields
}

APIFeature contains the information needed to test REST API requests

func NewAPIFeature

func NewAPIFeature(initialiser ServiceInitialiser) *APIFeature

NewAPIFeature returns a new APIFeature, takes a function to retrieve the bound handler just before a request is made

func NewAPIFeatureWithHandler

func NewAPIFeatureWithHandler(handler http.Handler) *APIFeature

NewAPIFeatureWithHandler create a new APIFeature with a handler already bound with your endpoints

func (*APIFeature) IAmAuthorised

func (f *APIFeature) IAmAuthorised() error

IAmAuthorised sets the Authorization header to a bogus token

func (*APIFeature) IAmNotAuthorised

func (f *APIFeature) IAmNotAuthorised() error

IAmNotAuthorised removes any Authorization header set in the request headers

func (*APIFeature) IDelete added in v0.4.0

func (f *APIFeature) IDelete(path string) error

IDelete makes a DELETE request to the provided path with the current headers

func (*APIFeature) IGet

func (f *APIFeature) IGet(path string) error

IGet makes a get request to the provided path with the current headers

func (*APIFeature) IPatch added in v0.4.1

func (f *APIFeature) IPatch(path string, body *godog.DocString) error

IPatch makes a PATCH request to the provided path with the current headers and the body provided

func (*APIFeature) IPostToWithBody

func (f *APIFeature) IPostToWithBody(path string, body *godog.DocString) error

IPostToWithBody makes a POST request to the provided path with the current headers and the body provided

func (*APIFeature) IPut added in v0.4.0

func (f *APIFeature) IPut(path string, body *godog.DocString) error

IPut makes a PUT request to the provided path with the current headers and the body provided

func (*APIFeature) ISetTheHeaderTo

func (f *APIFeature) ISetTheHeaderTo(header, value string) error

ISetTheHeaderTo is a default step used to set a header and associated value for the next request

func (*APIFeature) IShouldReceiveTheFollowingJSONResponse

func (f *APIFeature) IShouldReceiveTheFollowingJSONResponse(expectedAPIResponse *godog.DocString) error

IShouldReceiveTheFollowingJSONResponse asserts that the response body and expected response body are equal

func (*APIFeature) IShouldReceiveTheFollowingJSONResponseWithStatus

func (f *APIFeature) IShouldReceiveTheFollowingJSONResponseWithStatus(expectedCodeStr string, expectedBody *godog.DocString) error

IShouldReceiveTheFollowingJSONResponseWithStatus asserts the response code and body match the expectation

func (*APIFeature) IShouldReceiveTheFollowingResponse

func (f *APIFeature) IShouldReceiveTheFollowingResponse(expectedAPIResponse *godog.DocString) error

IShouldReceiveTheFollowingResponse asserts the response body and expected response body are equal

func (*APIFeature) IUseAServiceAuthToken added in v0.6.0

func (f *APIFeature) IUseAServiceAuthToken(serviceAuthToken string) error

func (*APIFeature) IUseAnXFlorenceUserToken added in v0.6.0

func (f *APIFeature) IUseAnXFlorenceUserToken(xFlorenceToken string) error

func (*APIFeature) RegisterSteps

func (f *APIFeature) RegisterSteps(ctx *godog.ScenarioContext)

RegisterSteps binds the APIFeature steps to the godog context to enable usage in the component tests

func (*APIFeature) Reset

func (f *APIFeature) Reset()

Reset the request headers

func (*APIFeature) TheHTTPStatusCodeShouldBe

func (f *APIFeature) TheHTTPStatusCodeShouldBe(expectedCodeStr string) error

TheHTTPStatusCodeShouldBe asserts that the status code of the response matches the expected code

func (*APIFeature) TheResponseHeaderShouldBe

func (f *APIFeature) TheResponseHeaderShouldBe(headerName, expectedValue string) error

TheResponseHeaderShouldBe asserts the response header matches the expectation

type AuthorizationFeature

type AuthorizationFeature struct {
	ErrorFeature
	FakeAuthService *httpfake.HTTPFake
}

func NewAuthorizationFeature

func NewAuthorizationFeature() *AuthorizationFeature

func (*AuthorizationFeature) Close

func (f *AuthorizationFeature) Close()

func (*AuthorizationFeature) RegisterSteps

func (f *AuthorizationFeature) RegisterSteps(ctx *godog.ScenarioContext)

func (*AuthorizationFeature) Reset

func (f *AuthorizationFeature) Reset()

type Chrome added in v0.6.5

type Chrome struct {
	ExecAllocatorCanceller context.CancelFunc
	CtxCanceller           context.CancelFunc
	Ctx                    context.Context
}

Chrome contains Chrome session-related resources

type ErrorFeature

type ErrorFeature struct {
	testing.TB
	// contains filtered or unexported fields
}

func (*ErrorFeature) Errorf

func (t *ErrorFeature) Errorf(format string, args ...interface{})

func (*ErrorFeature) Helper added in v0.3.0

func (t *ErrorFeature) Helper()

func (*ErrorFeature) Log added in v0.3.0

func (t *ErrorFeature) Log(_ ...interface{})

func (*ErrorFeature) Logf added in v0.3.0

func (t *ErrorFeature) Logf(format string, args ...interface{})

func (*ErrorFeature) Name added in v0.3.0

func (t *ErrorFeature) Name() string

func (*ErrorFeature) Reset added in v0.8.0

func (t *ErrorFeature) Reset()

func (*ErrorFeature) StepError

func (t *ErrorFeature) StepError() error

type MongoCollectionDeletedDocs added in v0.8.0

type MongoCollectionDeletedDocs struct {
	Name  string
	Count int64
}

MongoCollectionDeletedDocs contains the number of document deleted from collection

type MongoDeletedDocs added in v0.8.0

type MongoDeletedDocs struct {
	Database    string
	Count       int64
	Collections []MongoCollectionDeletedDocs
}

MongoDeletedDocs contains a list of counts for all deleted documents against a given collection of a mongo database

type MongoFeature

type MongoFeature struct {
	Server   *mim.Server
	Client   mongo.Client
	Database *mongo.Database
}

MongoFeature is a struct containing an in-memory mongo database

func NewMongoFeature

func NewMongoFeature(mongoOptions MongoOptions) *MongoFeature

NewMongoFeature creates a new in-memory mongo database using the supplied options

func (*MongoFeature) Close

func (m *MongoFeature) Close() error

Close stops the in-memory mongo database

func (*MongoFeature) RegisterSteps

func (m *MongoFeature) RegisterSteps(ctx *godog.ScenarioContext)

func (*MongoFeature) RemoveAllDataFromCollections added in v0.8.0

func (m *MongoFeature) RemoveAllDataFromCollections(collectionNames string) error

func (*MongoFeature) RemoveAllDataFromDatabase added in v0.8.0

func (m *MongoFeature) RemoveAllDataFromDatabase() error

func (*MongoFeature) Reset

func (m *MongoFeature) Reset() error

Reset is currently not implemented

func (*MongoFeature) ResetCollections added in v0.8.0

func (m *MongoFeature) ResetCollections(ctx context.Context, databaseName string, collectionNames []string) (*MongoDeletedDocs, error)

ResetCollections removes all data in all collections specified within database

func (*MongoFeature) ResetDatabase added in v0.8.0

func (m *MongoFeature) ResetDatabase(ctx context.Context, databaseName string) (*MongoDeletedDocs, error)

ResetDatabase removes all data in all collections within database

func (*MongoFeature) TheFollowingDocumentExistsInTheCollection

func (m *MongoFeature) TheFollowingDocumentExistsInTheCollection(collectionName string, document *godog.DocString) error

type MongoOptions

type MongoOptions struct {
	MongoVersion   string
	DatabaseName   string
	ReplicaSetName string
}

MongoOptions contains a set of options required to create a new MongoFeature

type ServiceInitialiser

type ServiceInitialiser func() (http.Handler, error)

func StaticHandler

func StaticHandler(handler http.Handler) ServiceInitialiser

type UIFeature added in v0.6.5

type UIFeature struct {
	ErrorFeature
	BaseURL     string
	Chrome      Chrome
	WaitTimeOut time.Duration
}

UIFeature contains the information needed to test UI interactions

func NewUIFeature added in v0.6.5

func NewUIFeature(baseURL string) *UIFeature

NewUIFeature returns a new UIFeature configured with baseURL

func (*UIFeature) Close added in v0.6.5

func (f *UIFeature) Close()

Close Chrome

func (*UIFeature) ElementShouldBeVisible added in v0.7.0

func (f *UIFeature) ElementShouldBeVisible(elementSelector string) error

func (*UIFeature) RegisterSteps added in v0.6.5

func (f *UIFeature) RegisterSteps(ctx *godog.ScenarioContext)

RegisterSteps binds the APIFeature steps to the godog context to enable usage in the component tests

func (*UIFeature) Reset added in v0.6.5

func (f *UIFeature) Reset()

Reset the chrome context

func (*UIFeature) RunWithTimeOut added in v0.7.0

func (f *UIFeature) RunWithTimeOut(timeout time.Duration, tasks chromedp.Tasks) chromedp.ActionFunc

Directories

Path Synopsis
examples
api
ui

Jump to

Keyboard shortcuts

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