Files
tasks/docs/development/testing.md
T
Stephan BehnkeandGitHub 0055aec702 Increase OTEL_BSP_SCHEDULE_DELAY (#7520)
## What changed?
<!-- Describe what has changed in this PR -->

Increased OTEL_BSP_SCHEDULE_DELAY from 0 to 100ms.

## Why?
<!-- Tell your future self why have you made these changes -->

Zero is too aggressive and leads to too much CPU usage.

## How did you test it?
<!-- How have you verified this change? Tested locally? Added a unit
test? Checked in staging env? -->

## Potential risks
<!-- Assuming the worst case, what can be broken when deploying this
change to production? -->

## Documentation
<!-- Have you made sure this change doesn't falsify anything currently
stated in `docs/`? If significant
new behavior is added, have you described that in `docs/`? -->

## Is hotfix candidate?
<!-- Is this PR a hotfix candidate or does it require a notification to
be sent to the broader community? (Yes/No) -->
2025-03-25 08:21:42 -07:00

3.9 KiB

Testing

This document describes the project's testing utilities and best practices.

Test helpers

Test helpers can be found in the common/testing package.

testvars package

Instead of creating identifiers like task queue name, namespace or worker identity by hand, use the testvars package.

Example:

func TestFoo(t *testing.T) {
    tv := testvars.New(t)

    req := &workflowservice.SignalWithStartWorkflowExecutionRequest{
        RequestId:    tv.Any().String(),
        Namespace:    tv.NamespaceName().String(),
        WorkflowId:   tv.WorkflowID(),
        WorkflowType: tv.WorkflowType(),
        TaskQueue:    tv.TaskQueue(),
        SignalName:   tv.SignalName(),
    }
}

Later you can assert on the generated values. testvars guarantees to provide the same value every time you call the same method.

assert.Equal(t, tv.WorkflowID(), startedWorkflow.WorkflowId)

If you need more than one value for the same entity in one test, you can use WithEntityNumber() method to get a new instance of testvars with a different value.

func TestFoo(t *testing.T) {

    tv := testvars.New(t)
    tv1 := tv.WithUpdateIDNumber(1)
    tv2 := tv.WithUpdateIDNumber(2)

    req1 := &workflowservice.UpdateWorkflowExecutionRequest{
        Namespace:         tv1.NamespaceName().String(),
        WorkflowExecution: tv1.WorkflowExecution(),
        Request: &updatepb.Request{
            Meta: &updatepb.Meta{UpdateId: tv1.UpdateID()},
            Input: &updatepb.Input{
                Name: tv1.HandlerName(),
                Args: payloads.EncodeString("args-value-of-" + tv1.UpdateID()),
            },
        },
    }

	req2 := &workflowservice.UpdateWorkflowExecutionRequest{
        Namespace:         tv2.NamespaceName().String(),
        WorkflowExecution: tv2.WorkflowExecution(),
        Request: &updatepb.Request{
            Meta: &updatepb.Meta{UpdateId: tv2.UpdateID()},
            Input: &updatepb.Input{
                Name: tv2.HandlerName(),
                Args: payloads.EncodeString("args-value-of-" + tv2.UpdateID()),
            },
        },
    }
}

If you don't care about specific value, you can use Any() method to generate a random value. It indicates that value doesn't matter for this test and will never be asserted on (but required for API, for example).

taskpoller package

For end-to-end testing, consider using taskpoller.TaskPoller to handle workflow tasks. This is useful when you need full control over the worker behavior in a way that the SDK cannot provide; or if there's no SDK support for that API available yet.

You'll find a fully initialized task poller in any functional test suite, look for s.TaskPoller.

NOTE: The previous testcore.TaskPoller has been deprecated and should not be used in new code.

softassert package

softassert.That is a "soft" assertion that logs an error if the given condition is false.

It is useful to highlight invariant violations in production code. It is not a substitute for regular error handling, validation, or control flow.

In functional tests, a failed soft assertion will not stop the test execution immediately, but it will ultimately fail the test.

OpenTelemetry (OTEL)

To debug your test by analysing observability traces, set the following environment variables:

export OTEL_BSP_SCHEDULE_DELAY=100
export OTEL_EXPORTER_OTLP_TRACES_INSECURE=true
export OTEL_TRACES_EXPORTER=otlp
export TEMPORAL_OTEL_DEBUG=true

And have an OTEL collector running, such as Grafana Tempo (make start-dependencies).

See tracing.md for more details.

Code coverage

You'll find the code coverage reporting in Codecov: https://app.codecov.io/gh/temporalio/temporal.

Consider installing the Codecov Browser Extension to see code coverage directly in GitHub PRs.