Shoulder.dev Logo Shoulder.dev

How do I add Tests to this codebase? - stefanprodan/timoni

How do I add Tests to this codebase?

Timoni is built on top of Go, so you can use the standard Go testing framework to write tests. Timoni is composed of many packages, which can be tested individually.

Testing Strategy

Timoni’s test suite follows a pattern of unit testing and integration testing. Unit tests focus on individual functions and components, ensuring they behave correctly in isolation. Integration tests verify the interactions between different components and confirm that Timoni works as intended.

Unit Testing

To test an individual function, you can create a test file named <function_name>_test.go within the same directory as the function being tested. For example, to test the Validate function in the config package, create a file named config_test.go with the following code:

package config

import (
    "testing"
)

func TestValidate(t *testing.T) {
    // Create a valid config struct
    config := &Config{
        // ...
    }

    // Validate the config
    err := config.Validate()

    // Assert that the validation was successful
    if err != nil {
        t.Errorf("Validation failed: %v", err)
    }
}

Integration Testing

Timoni’s integration tests are stored in the integration directory. These tests use a test server to simulate real-world scenarios and interact with Timoni’s various components. For example, the integration/test_server.go file defines a test server that can be used to test Timoni’s REST API:

package integration

import (
    "context"
    "fmt"
    "net/http"
    "net/http/httptest"
    "testing"
    "time"

    "github.com/stefanprodan/timoni/pkg/api"
    "github.com/stefanprodan/timoni/pkg/config"
)

type TestServer struct {
    server *httptest.Server
    cfg    *config.Config
}

func NewTestServer(t *testing.T, cfg *config.Config) *TestServer {
    // Create a new test server
    ts := &TestServer{
        cfg: cfg,
    }

    // Create a new API server
    server := api.NewServer(cfg)

    // Start the test server
    ts.server = httptest.NewUnstartedServer(server)
    ts.server.StartTLS()

    // ...

    return ts
}

func (ts *TestServer) Close(t *testing.T) {
    // ...

    // Close the test server
    if ts.server != nil {
        ts.server.Close()
    }
}

Running Tests

To run all tests, you can use the go test command in the root directory of the repository. To run tests for a specific package, use the go test command with the package name as an argument. For example, to run tests for the config package, use the following command:

go test ./pkg/config

Test Coverage

Timoni uses the go test command with the -cover flag to generate test coverage reports. This helps identify areas of the code that are not adequately covered by tests. You can use the go tool cover command to analyze the coverage reports.

Example Test

The integration/cluster_test.go file contains a test that checks if Timoni can successfully create a cluster resource:

package integration

import (
    "context"
    "fmt"
    "net/http"
    "testing"

    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
    corev1 "k8s.io/api/core/v1"
    v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/runtime"
    "k8s.io/apimachinery/pkg/watch"
    "k8s.io/client-go/kubernetes/fake"
    "k8s.io/client-go/testing"
)

func TestClusterCreate(t *testing.T) {
    // Create a new fake Kubernetes clientset
    clientset := fake.NewSimpleClientset()

    // ...

    // Create a new cluster resource
    cluster := &corev1.Namespace{
        ObjectMeta: v1.ObjectMeta{
            Name: "test-cluster",
        },
    }

    // Create the cluster resource
    created, err := clientset.CoreV1().Namespaces().Create(context.Background(), cluster, v1.CreateOptions{})
    require.NoError(t, err)
    assert.Equal(t, cluster.Name, created.Name)

    // ...
}

Contributing Tests

When contributing to Timoni, please ensure that your code is well-tested. This helps maintain the quality of the codebase and ensures that changes don’t break existing functionality. You can find more information about contributing to Timoni in the CONTRIBUTING.md file.