Skip to content

Latest commit

 

History

History
182 lines (146 loc) · 8.05 KB

index.adoc

File metadata and controls

182 lines (146 loc) · 8.05 KB

Master programming.
Лекция №5 (Тестирование)

1. Основные понятия тестирования

1.1. Типы тестирования

  • Тестирование — это та же программа со своим кодом

  • Unit-тесты

  • Тестирование белого, серого, чёрного ящика

  • Нагрузочное тестирование

  • Стресс-тестирование

  • Интеграционное тестирование

  • TDD, BDD

1.2. Терминология

  • Feature — предлагаемая функциональность

  • Bug — неправильная реализация функциональности

  • Спецификация — набор функциональностей, которым обладает система

  • Unit test — модульный тест

  • Framework — движок (библиотека) для реализации конкретной функциональности

    • тестовый движок (gtest, catch2)

    • движок пользовательского интерфейса (Qt, Gtk)

    • Boost — это не движок, это набор библиотек

    • НО! boost::async — это движок для сетевого взаимодействия

  • Fixture, Suite, Case — способы иерархического представления тестов

2. Модульное тестирование

2.1. Особенности модульного тестирования

  • Тестирование одного модуля без каких-либо зависимостей от других модулей

  • Разновидность серого/чёрного ящика

  • Уже готовый пример использования кода

  • Возможнность регрессионного тестирования

  • CUnit, Boost test, GTest, Catch, …​

2.2. Пример юнит-теста

#include <gtest/gtest.h>

class DwtTest: public ::testing::Test
{
protected:
    DwtTest() : img(kWidth * kHeight) {
        std::fill(img.begin(), img.end(), 0);

        auto it = img.begin() + kHeight/2 * kWidth;
        for (auto i = 0; i < kHeight/5; ++i)
            std::fill_n(it + i * kWidth + kWidth/4, kWidth/2, 255);
    }

    void SetUp() {}
    void TearDown() {}

protected:
    std::vector<float> img;
};

TEST_F(DwtTest, DwtIDwt)
{
    std::vector<float> subbands(img);
    ASSERT_EQ(wt2d_cdf97_fwd(subbands.data(), kHeight, kWidth, 3), 0);

    std::vector<float> restored(subbands);
    ASSERT_EQ(wt2d_cdf97_inv(restored.data(), kHeight, kWidth, 3), 0);
    ASSERT_EQ(restored.size(), img.size());
    for (int i = 0; i < img.size(); ++i)
        EXPECT_NEAR(restored[i], img[i], 1) << "Index " << i;
}

2.3. Состав модульного теста

  • ASSERT, EXPECT — примитивы сравнения (ядро теста)

  • WARN, ERROR — уровни остановки теста

  • Иерархии тестов: TestSuite (Fixture), TestCase — зависит от тестового движка

  • TearUp/Down, FixtureSetup/Cleanup — ин(де)ициализация уровня теста

  • Механизм добавления теста

  • Система оповещения пользователя об ошибках

  • Разные уровни тестов необходимы для организации генерации тестируемых данных

2.4. Схема иерархии модульных тестов

TestSuite(S0)
    constructor
    TestCase(S0::C0)
        constructor
            actions
            asserts, expects
        destructor
    TestCase(S0::C1)
        constructor
            actions
            asserts, expects
        destructor
    destructor
TestSuite(S1)
    constructor
    TestCase(S1::C0)
    TestCase(S1::C1)
    TestCase(S1::C2)
    destructor
...

3. Пример фреймворка модульного тестирования

3.1. Движок тестирования Catch

  • https://github.com/catchorg/Catch2

  • Автоматическое добавление тестов

  • Изменённая иерархия тестов:

    • нулевой уровень — глобальное пространство имён

    • первый уровень — TEST_CASE

    • второй уровень — SECTION

  • Поддержка BDD-стиля тестирования

  • Привычные методы сравнения

4. Подходы разработки через тестирование

4.1. Test Driven Development

  • Разработка через тестирование

  • Каждая функционально сначала обретает тест, а потом непосредственный код

  • Согласование интерфейса происходит раньше согласования реализации функциональности

  • Является идеалогией, а не типом тестирования

  • Тесты всегда свежие, так как сначала пишутся именно они

4.2. Интеграционное тестирование

  • Тестирование целиком

  • Тестирование взаимодействия библиотек, систем или компонентов одной системы

  • Подходят сторонние инструменты (expect)

  • Неустойчиво к ошибкам компонент системы: ошибки могут интерферировать

  • Найденная уязвимость должна приводить к возникновению дополнительных модульных тестов

4.3. Mock & stubs

  • Имитаторы и заглушки

  • Ограничения:

    • компоненты должны находится в разных библиотеках

    • невозможно имитировать внутренние объкты классов или функций

    • имитируемые объкты должны иметь абстрактный интерфейс или быть шаблонным параметром

    • решение возможно на уровне системы (LD_PRELOAD)

  • Заглушки — константы, частный случай имитаторов

  • Имитаторы — способны имитировать действия

  • Плохо автоматизируется

  • Подходит для нереализованных или недоделанных компонентов системы

4.4. Тесты на устойчивость

  • Стресс-тесты

  • Абсолютно произвольные данные

  • Показывает насколько система устройчива, а не степень её отладки

  • В большинстве случаев ошибки являются архитектурными

4.5. Нагрузочное тестирование

  • Бенчмарки (benchmark)

  • Тестирование скорости всей системы или отдельных компонент

  • Тестирование устройчивости системы под нагрузкой

  • Определение параметров системы: максимальное количество пользователей, время ожидания и т.д.

  • Самая простая утилита — time

  • Метод понижения нагрузки:

    • для определения максимальной нагрузки

    • понижать нагрузку в 2 раза и фиксировать параметры системы

    • построить кривую параметров от объёма нагрузки

    • эстраполировать результаты