Масштабируем тестирование на Go: интеграция с Allure TestOps без боли

Полное руководство по интеграции Allure в Go-тесты: от установки до CI/CD [2024]

TL;DR: Это руководство содержит полную информацию по интеграции Allure в Go-проекты, включая настройку окружения, примеры тестов и CI/CD интеграцию.

Содержание

  1. Предварительные требования
  2. Установка и базовая настройка
  3. Настройка Allure TestOps
  4. Базовый пример интеграции
  5. Продвинутое использование
  6. CI/CD интеграция
  7. Решение проблем
  8. FAQ

Перед прочтением рекомендую подписаться на мой телеграмм канал, где вы сможете найти актуальные новости, примеры и хаки в мире разработки: @asanov_tech

1. Предварительные требования

1.1 Необходимые инструменты

  • Go 1.16 или выше
  • Git
  • Доступ к Allure TestOps

1.2 Установка зависимостей

# Основная библиотека для работы с Allure
go get github.com/ozontech/allure-go

# Дополнительные зависимости
go get github.com/stretchr/testify
go get github.com/pkg/errors

Обязательно проверьте версии в go.mod:

module your-project

go 1.21

require (
    github.com/ozontech/allure-go v0.6.32
    github.com/stretchr/testify v1.9.0
)

2. Установка и базовая настройка

2.1 Установка allurectl

# Для MacOS Intel
curl -Lo ./allurectl https://github.com/allure-framework/allurectl/releases/latest/download/allurectl_darwin_amd64

# Для MacOS M1/M2
curl -Lo ./allurectl https://github.com/allure-framework/allurectl/releases/latest/download/allurectl_darwin_arm64

# Для Linux
curl -Lo ./allurectl https://github.com/allure-framework/allurectl/releases/latest/download/allurectl_linux_amd64

chmod +x ./allurectl
sudo mv ./allurectl /usr/local/bin/allurectl

2.2 Настройка переменных окружения

# Обязательные переменные
export ALLURE_ENDPOINT="https://your-allure-server/api"
export ALLURE_TOKEN="your-token"
export ALLURE_PROJECT_ID="your-project-id"

# Опциональные переменные
export ALLURE_RESULTS_PATH="./allure-results"
export ALLURE_OUTPUT_FOLDER="./allure-report"
Важно: Никогда не храните токен напрямую в репозитории. Используйте переменные окружения или секреты CI/CD.

3. Настройка Allure TestOps

3.1 Создание проекта в Allure TestOps


Шаги настройки:

  1. Создайте новый проект
  2. Получите Project ID (понадобится для конфигурации)
  3. Создайте API token в настройках пользователя

3.2 Структура тест-кейсов

Рекомендуемая организация тестов:

  • Создавайте эпики для крупных функциональных блоков
  • Группируйте тест-кейсы по фичам
  • Используйте теги для удобной фильтрации

4. Базовый пример интеграции

4.1 Минимальная структура теста

package tests

import (
    "testing"
    "github.com/ozontech/allure-go/pkg/framework/provider"
    "github.com/ozontech/allure-go/pkg/framework/runner"
    "github.com/stretchr/testify/require"
)

// Базовая структура теста с Allure
func Test_BasicExample(t *testing.T) {
    // Создаем новый runner
    r := runner.NewRunner(t, "Basic Test Suite")

    // Определяем тест-кейс
    r.NewTest("simple test", func(t provider.T) {
        // Привязка к тест-кейсу в Allure TestOps
        t.ID("12345")
        
        // Добавляем метаданные для группировки в отчетах
        t.Epic("API Tests")
        t.Feature("Basic Operations")
        t.Story("Simple Functionality")
        
        // Описываем шаги теста
        t.Step("Initialize test data", func() {
            // Код инициализации
        })
        
        t.Step("Perform operation", func() {
            // Основной код теста
        })
        
        t.Step("Verify results", func() {
            require.True(t, true)
        })
    })

    // Запускаем все тесты
    r.RunTests()
}

4.2 Пример интеграционного теста

func Test_Integration(t *testing.T) {
    r := runner.NewRunner(t, "Integration Test Suite")

    // Определяем тестовые случаи
    testCases := []struct {
        name      string
        allureID  string      // ID тест-кейса в Allure TestOps
        input     string
        expected  string
        expectErr bool
    }{
        {
            name:     "successful operation",
            allureID: "TEST-1",
            input:    "valid_input",
            expected: "expected_result",
        },
        {
            name:      "validation error",
            allureID:  "TEST-2",
            input:     "invalid_input",
            expectErr: true,
        },
    }

    for _, tc := range testCases {
        tc := tc // create local copy for parallel tests

        r.NewTest(tc.name, func(t provider.T) {
            t.ID(tc.allureID)
            t.Epic("Integration Tests")
            
            t.Step("Setup test environment", func() {
                // Настройка окружения
            })

            t.Step("Execute test scenario", func() {
                result, err := executeOperation(tc.input)
                
                if tc.expectErr {
                    require.Error(t, err)
                    return
                }
                
                require.NoError(t, err)
                require.Equal(t, tc.expected, result)
            })
        })
    }

    r.RunTests()
}
Важно о ID тест-кейсов:

ID тест-кейса (allureID) должен соответствовать идентификатору в Allure TestOps. Создайте тест-кейс в Allure TestOps перед написанием теста.

4.3 Работа с вложениями и параметрами

func Test_WithAttachments(t *testing.T) {
    r := runner.NewRunner(t, "Test With Attachments")

    r.NewTest("test with data", func(t provider.T) {
        t.ID("TEST-3")

        // Добавление параметров теста
        t.Parameter("Environment", "staging")
        t.Parameter("Version", "1.0.0")

        t.Step("Prepare test data", func() {
            // Прикрепление JSON данных
            jsonData := []byte(`{"key": "value"}`)
            t.Attachment("test_data.json", "application/json", jsonData)
        })

        t.Step("Execute and verify", func() {
            // Прикрепление текстового лога
            t.Attachment("execution.log", "text/plain", 
                []byte("Operation executed successfully"))
        })
    })

    r.RunTests()
}

4.4 Параллельное выполнение тестов

func Test_Parallel(t *testing.T) {
    r := runner.NewRunner(t, "Parallel Test Suite")

    for i := 0; i < 3; i++ {
        i := i // local copy
        
        r.NewTest(fmt.Sprintf("parallel_test_%d", i), func(t provider.T) {
            t.Parallel() // Enable parallel execution
            t.ID(fmt.Sprintf("TEST-P%d", i))

            t.Step("Parallel operation", func() {
                // Параллельное выполнение
            })
        })
    }

    r.RunTests()
}
Внимание при параллельном выполнении:
  • Убедитесь, что тесты не имеют общего изменяемого состояния
  • Используйте уникальные идентификаторы для каждого теста
  • Правильно организуйте очистку ресурсов

4.5 Использование переменных окружения

func Test_WithEnvironment(t *testing.T) {
    r := runner.NewRunner(t, "Environment Test Suite")

    r.NewTest("environment test", func(t provider.T) {
        t.ID(os.Getenv("TEST_ID"))
        
        // Добавление информации об окружении в отчет
        t.Parameter("ALLURE_RESULTS_PATH", os.Getenv("ALLURE_RESULTS_PATH"))
        t.Parameter("ALLURE_PROJECT_ID", os.Getenv("ALLURE_PROJECT_ID"))

        // Тестовая логика
    })

    r.RunTests()
}

5. CI/CD интеграция

5.1 Типовые конфигурации

Создайте следующие файлы для переиспользования в CI/CD пайплайнах:

.allure-install

# Установка allurectl
.allure-install: &allure-install
    - wget https://github.com/allure-framework/allurectl/releases/download/${ALLURE_VERSION}/allurectl_linux_386 -O ./allurectl
    - chmod +x ./allurectl
    - mv allurectl /usr/local/bin/allurectl

.allure-launch-create

# Создание launch в Allure TestOps
.allure-launch-create: &allure-launch-create
    - rm -rf .allure
    - mkdir -p ${ALLURE_RESULTS_PATH}/allure-results
    - mkdir .allure
    - allurectl launch create --no-header --format ID --launch-name "${ALLURE_LAUNCH_NAME}" > ${ALLURE_RESULTS_PATH}/launch_id

.allure-upload-results

# Загрузка результатов в Allure TestOps
.allure-upload-results: &allure-upload-results
    - export ALLURE_LAUNCH_ID=$(cat ${ALLURE_RESULTS_PATH}/launch_id)
    - ls -l $ALLURE_RESULTS_PATH/allure-results
    - allurectl upload $ALLURE_RESULTS_PATH
    - rm -r $ALLURE_RESULTS_PATH/allure-results
    - rm -rf .allure

5.2 GitLab CI интеграция

# .gitlab-ci.yml
variables:
  ALLURE_VERSION: "2.15.0"
  ALLURE_RESULTS_PATH: "./allure-results"
  ALLURE_LAUNCH_NAME: "Integration Tests - $CI_COMMIT_REF_NAME"

.base_test_template:
  image: golang:1.21
  before_script:
    - !reference [.allure-install]
  after_script:
    - !reference [.allure-upload-results]

integration_tests:
  extends: .base_test_template
  script:
    - !reference [.allure-launch-create]
    - go test ./... -v -tags=integration
  variables:
    ALLURE_TOKEN: ${ALLURE_TOKEN}
    ALLURE_ENDPOINT: ${ALLURE_ENDPOINT}
    ALLURE_PROJECT_ID: ${ALLURE_PROJECT_ID}

5.3 GitHub Actions интеграция

name: Integration Tests with Allure

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      ALLURE_VERSION: "2.15.0"
      ALLURE_RESULTS_PATH: "./allure-results"
      ALLURE_LAUNCH_NAME: "Integration Tests - ${{ github.ref_name }}"

    steps:
      - uses: actions/checkout@v3
      
      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.21'

      - name: Install Allure
        run: |
          wget https://github.com/allure-framework/allurectl/releases/download/${ALLURE_VERSION}/allurectl_linux_386 -O ./allurectl
          chmod +x ./allurectl
          sudo mv allurectl /usr/local/bin/allurectl

      - name: Create Allure Launch
        run: |
          mkdir -p ${ALLURE_RESULTS_PATH}/allure-results
          allurectl launch create --no-header --format ID --launch-name "${ALLURE_LAUNCH_NAME}" > ${ALLURE_RESULTS_PATH}/launch_id
        env:
          ALLURE_TOKEN: ${{ secrets.ALLURE_TOKEN }}
          ALLURE_ENDPOINT: ${{ secrets.ALLURE_ENDPOINT }}
          ALLURE_PROJECT_ID: ${{ secrets.ALLURE_PROJECT_ID }}

      - name: Run Tests
        run: go test ./... -v -tags=integration

      - name: Upload Results
        if: always()
        run: |
          export ALLURE_LAUNCH_ID=$(cat ${ALLURE_RESULTS_PATH}/launch_id)
          allurectl upload ${ALLURE_RESULTS_PATH}
        env:
          ALLURE_TOKEN: ${{ secrets.ALLURE_TOKEN }}
          ALLURE_ENDPOINT: ${{ secrets.ALLURE_ENDPOINT }}
          ALLURE_PROJECT_ID: ${{ secrets.ALLURE_PROJECT_ID }}

6. Решение проблем

6.1 Типичные проблемы и решения

Проблема Решение
Не создаются результаты тестов
  • Проверьте ALLURE_RESULTS_PATH
  • Убедитесь, что директория существует и доступна для записи
  • Проверьте права доступа
Ошибка при загрузке результатов
  • Проверьте ALLURE_TOKEN и ALLURE_ENDPOINT
  • Убедитесь в корректности Project ID
  • Проверьте сетевой доступ к серверу Allure
Тест-кейсы не связываются с Allure TestOps
  • Убедитесь, что ID в коде совпадает с ID в Allure TestOps
  • Проверьте, что тест-кейс создан в системе

6.2 Отладка

# Включение подробных логов allurectl
export ALLURE_DEBUG=1
export ALLURE_TRACE=1

# Проверка текущей конфигурации
allurectl config

# Тестовая загрузка результатов
allurectl upload ${ALLURE_RESULTS_PATH} --dry-run

7. Часто задаваемые вопросы

7.1 Общие вопросы

Q: Нужно ли создавать тест-кейсы в Allure TestOps перед написанием тестов?

A: Да, рекомендуется сначала создать тест-кейсы в Allure TestOps и затем использовать их ID в коде. Это обеспечит правильную связь между тестами и отчетами.

Q: Можно ли использовать Allure для unit-тестов?

A: Да, можно, но рекомендуется использовать Allure преимущественно для интеграционных и e2e тестов, так как они обычно требуют более подробной отчетности.

Q: Как организовать тесты в больших проектах?

A: Рекомендуется:

  • Группировать тесты по функциональности
  • Использовать теги для категоризации
  • Создавать иерархию с помощью Epic/Feature/Story
  • Разделять тесты по типам (unit, integration, e2e)

7.2 Лучшие практики

  • Используйте уникальные и понятные названия тестов
  • Добавляйте подробные описания шагов
  • Прикрепляйте полезные артефакты (логи, скриншоты)
  • Используйте параметризацию для похожих тест-кейсов
  • Регулярно очищайте временные файлы
Совет: Начните с интеграционных тестов и постепенно расширяйте использование Allure в проекте.

Спасибо за уделенное время и рекомендую подписаться на мой телеграмм канал, где вы сможете найти актуальные новости, примеры и хаки в мире разработки: @asanov_tech

Комментарии

Популярные сообщения из этого блога

Как преобразовать строку в массив в ClickHouse / How to transform string to array in ClickHouse

Как разложить массив на несколько строк в ClickHouse

Экспорт одной таблицы базы данных или mysqldump одной таблицы (MySQL)