allure-go

repository·master·Indexed 19 days ago

https://github.com/ozontech/allure-go

A Go testing framework and provider that integrates with Allure reporting. It enables developers to create tests with rich metadata, nested steps, attachments, and labels. The library provides the `allure` package for managing results, containers, and attachments, as well as a `pkg/framework` package featuring `provider.T` and `provider.StepCtx` interfaces for test lifecycle control and structured reporting.

Tokens
19.9K
Snippets
66
Records
89
Agent score
64%

What's inside allure-go

  1. Overview of pkg/framework interfaces

    master

    The pkg/framework package provides a high-level abstraction for integrating Allure reporting into your test suites. It is built around two primary interfaces that define how you interact with the Allure lifecycle:

    1. provider.T: The main interface for managing the test lifecycle. It includes methods for creating steps, adding attachments, handling assertions, managing suite-level metadata, and manipulating test behavior.
    2. provider.StepCtx: A context-aware interface used within the scope of a specific test step. It allows you to add nested steps, attach data, log information, and perform assertions that are specifically scoped to that step.

    Understanding these interfaces is key to using the framework to generate rich, structured Allure reports.

  2. Perform assertions with Assert and Require

    master

    Allure-go provides a powerful assertion system inspired by testify. You can access these through two patterns:

    1. Via the Test/Step Context: Call t.Assert() or t.Require() (or sCtx.Assert()/sCtx.Require()) to get an Asserts struct. This automatically creates a step in the Allure report describing the assertion.

      • Assert(): Fails the test but does NOT stop execution.
      • Require(): Fails the test and STOPS execution.
    2. Directly via package functions: Use the standalone assertion functions which require a ProviderT (an interface compatible with provider.T).

    Supported assertions include Equal, NotEqual, NoError, ErrorIs, Contains, JSONEq, True, False, and many more.

    Warning: Do not use Require assertions inside asynchronous steps (WithNewAsyncStep). Because Require uses FailNow() (which calls go.Exit()), it can prevent the test from cleaning up or properly saving step data.

    // Using Assert/Require via the context
    t.Assert().Equal("expected", actual) // Continues execution
    t.Require().NoError(err)             // Stops execution if err != nil
  3. Prevent losing Allure ID during suite setup failures

    master

    If a suite fails during the BeforeAll stage, the resulting report might lack the ALLURE_ID field. To ensure every test (even those in failing suites) maintains its identity, you can use one of two methods:

    1. GetAllureID(testName string) string: Implement this method on your suite struct. It allows you to map specific test names to hardcoded or calculated Allure IDs.
    2. InitializeTestsParams(): For parametrized tests, implement this method to pre-calculate and assign allureID and allureTitle to your parameter objects before the suite starts running.
    // Method 1: GetAllureID
    type AllureIDSuite struct {
      suite.Suite
    }
    func (testSuit *AllureIDSuite) GetAllureID(testName string) string {
      if testName == "TestWithAllureIDFirst" {
        return "9001"
      }
      return ""
    }
    
    // Method 2: InitializeTestsParams for parametrized tests
    type CitiesParam struct {
      allureID string
      title    string
      value    string
    }
    func (p CitiesParam) GetAllureID() string { return p.allureID }
    func (p CitiesParam) GetAllureTitle() string { return p.title }
    
    type ParametrizedSuite struct {
      suite.Suite
      ParamCities []CitiesParam
    }
    func (s *ParametrizedSuite) InitializeTestsParams() {
      s.ParamCities = []CitiesParam{{allureID: "101", title: "City 1", value: "London"}}
    }
  4. Use Cute for HTTP testing with Allure

    master
    For developers looking to perform HTTP testing in Go with built-in Allure support, the cute library is recommended. It provides expressive syntax, JSON support, custom asserts, and BDD capabilities designed to work seamlessly with allure-go.
  5. Implement parametrized tests in a suite

    master

    Since v0.6.16, pkg/framework supports parametrized tests using a specific naming convention within your suite struct.

    Requirements

    1. Parameter Field: Add an array/slice to your suite struct. The name MUST follow the pattern Param + TestNameWithoutPrefix.
      • Example: If your test is TableTestCities, the parameter field must be named ParamCities.
    2. Test Method: The test method name MUST start with the prefix TableTest instead of Test.
    3. Method Signature: The test method must accept provider.T as the first argument and the parameter type as the second argument.
    package suite_demo
    
    import (
    	"testing"
    
    	"github.com/jackc/fake"
    	"github.com/ozontech/allure-go/pkg/framework/provider"
    	"github.com/ozontech/allure-go/pkg/framework/suite"
    )
    
    type ParametrizedSuite struct {
    	suite.Suite
    	// ParamCities param has name as expected test but has prefix Param instead of TableTest
    	ParamCities []string
    }
    
    func (s *ParametrizedSuite) BeforeAll(t provider.T) {
    	for i := 0; i < 10; i++ {
    		s.ParamCities = append(s.ParamCities, fake.City())
    	}
    }
    
    // TableTestCities is parametrized test has name prefix TableTest instead of Test
    func (s *ParametrizedSuite) TableTestCities(t provider.T, city string) {
    	t.Parallel()
    	t.Require().NotEmpty(city)
    }
    
    func TestNewParametrizedDemo(t *testing.T) {
    	suite.RunSuite(t, new(ParametrizedSuite))
    }
  6. Use the Container type to manage TestSetup and TestTeardown hooks

    master

    The allure.Container struct is used to handle Allure TestSetup and TestTeardown hooks. It manages a hierarchy of steps, results, and attachments.

    Key behaviors:

    • Hierarchy: The Children array contains UUIDs of reports referring to the container. For Before/After Test hooks, Children contains one element. For Before/After Suite hooks, it contains the UUIDs of all tests for which the hook was executed.
    • Lifecycle: Use Begin() to set the start time and Finish() to set the stop time. The Done() method is a convenience function that calls both Finish() and Print().
    • Steps: It holds Befores (setup steps) and Afters (teardown steps) as arrays of *allure.Step pointers.
    container := allure.NewContainer()
    container.Begin()
    // ... perform setup/teardown steps ...
    err := container.Done()
  7. Configure Allure report output paths

    master

    Allure report output locations are determined by combining two global environment variables: ${ALLURE_OUTPUT_FOLDER}/${ALLURE_OUTPUT_PATH}.

    • ALLURE_OUTPUT_FOLDER: The name of the folder where the allure reports will be stored. Default is allure-results.
    • ALLURE_OUTPUT_PATH: The directory path where the ALLURE_OUTPUT_FOLDER will be created. Default is the root folder of the test launcher.
  8. Access current test status in hooks

    master

    The allure.CurrentResult struct is designed for use in lifecycle hooks (like AfterEach). It provides a lightweight view of the test's outcome:

    • Status: The current allure.Status.
    • StatusDetails: Contains the error message and trace.

    It includes helper methods GetStatusMessage() and GetStatusTrace() to access the details.

  9. Configure Allure global environment variables

    master

    You can control the behavior of the allure package using several global environment variables. These settings affect where results are stored and how URLs are formatted in the report.

    # Example configuration
    export ALLURE_OUTPUT_PATH="./test-results"
    export ALLURE_OUTPUT_FOLDER="my-results"
    export ALLURE_ISSUE_PATTERN="https://jira.com/browse/%s"
    export ALLURE_LAUNCH_TAGS="regression,api"
  10. Configure global test tags and test plans

    master

    Use the following environment variables to apply metadata to your test runs:

    • ALLURE_LAUNCH_TAGS: A list of tags applied to every test by default. This is useful for CI/CD integration (e.g., tagging tests by CI job name or branch name).
    • ALLURE_TESTPLAN_PATH: The path to your test plan JSON file. This feature is intended for use with Allure TestOps.
  11. Use setup and teardown hooks in suites

    master

    The suite.Suite provides several lifecycle hooks that you can implement to manage test environment state:

    • BeforeAll(t provider.T): Runs once before any tests in the suite.
    • AfterAll(t provider.T): Runs once after all tests in the suite.
    • BeforeEach(t provider.T): Runs before every individual test.
    • AfterEach(t provider.T): Runs after every individual test.

    You can use these hooks to create Allure steps (e.g., t.NewStep("Setup")) so the lifecycle actions appear in the report.

    type BeforeAfterDemoSuite struct {
    	suite.Suite
    }
    
    func (s *BeforeAfterDemoSuite) BeforeEach(t provider.T) {
      t.NewStep("Before Test Step")
    }
    
    func (s *BeforeAfterDemoSuite) AfterEach(t provider.T) {
      t.NewStep("After Test Step")
    }