Skip to content
This repository was archived by the owner on Dec 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/clang++",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "macos-clang-x64"
}
],
"version": 4
}
Comment thread
a-osovets marked this conversation as resolved.
Comment thread
a-osovets marked this conversation as resolved.
15 changes: 10 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ cmake_minimum_required (VERSION 3.5)
project (TMAU)

# Search for directories simular to "trunk/as0xxyy/task_0x/src/"
file(GLOB V_GLOB RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "trunk/as0*/*/src/")
foreach(item ${V_GLOB})
message( "Find \"${item}\"" )
add_subdirectory(${item})
endforeach()
# Uncomment to build all projects (for CI/CD)
# file(GLOB V_GLOB RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "trunk/as0*/*/src/")
# foreach(item ${V_GLOB})
# message( "Find \"${item}\"" )
# add_subdirectory(${item})
# endforeach()

# Build only specific student project (local development)
# add_subdirectory(trunk/as06617/task_01/src)
add_subdirectory(trunk/as06617/task_02/src)
Comment thread
a-osovets marked this conversation as resolved.
10 changes: 10 additions & 0 deletions trunk/as06617/task_02/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [


Comment thread
a-osovets marked this conversation as resolved.
Comment thread
a-osovets marked this conversation as resolved.
Comment thread
a-osovets marked this conversation as resolved.
]
}
Comment thread
a-osovets marked this conversation as resolved.
67 changes: 67 additions & 0 deletions trunk/as06617/task_02/doc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<p align="center"><strong>Министерство образования Республики Беларусь</strong></p>
<p align="center">Учреждение образования</p>
<p align="center">Брестский государственный технический университет</p>
<p align="center">Кафедра ИИТ</p>

<br><br><br><br>

<p align="center"><strong>Лабораторная работа №2</strong></p>
<p align="center">
Дисциплина: «Теория и методы автоматического управления»
</p>
<p align="center">
Тема: тестирование программного модуля и анализ покрытия кода
</p>

<br><br><br>

<p align="right">
Выполнил: студент 3 курса<br>
Группа АС-66<br>
Осовец А.О.
</p>

<p align="right">
Проверил:<br>
Иванюк Д.С.
</p>

<br><br><br><br>

<p align="center">Брест, 2025</p>

---

## Цель работы

Целью лабораторной работы является освоение базовых принципов модульного тестирования программ на языке C++ с использованием фреймворка Google Test, а также получение навыков анализа покрытия кода тестами.

---

## Постановка задачи

В рамках выполнения работы необходимо:

- разработать набор модульных тестов для функций, реализованных в лабораторной работе №1;
- использовать библиотеку Google Test для автоматизации тестирования;
- организовать исходный код и тесты в соответствии со структурой репозитория;
- проанализировать процент покрытия пользовательского кода тестами.

---

## Реализация тестирования

Для проверки корректности вычислений были разработаны тесты для функций линейной и нелинейной динамики системы.

Тесты проверяют следующие случаи:
- нулевые входные данные;
- отсутствие управляющего воздействия;
- отсутствие состояния системы;
- типовые значения аргументов.

Пример теста для линейной модели:

```cpp
TEST(LinearModel, ZeroInput) {
EXPECT_DOUBLE_EQ(linear(0.0, 0.0), 0.0);
}
42 changes: 42 additions & 0 deletions trunk/as06617/task_02/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 3.16)
project(as06617_task_02)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Основное приложение
add_executable(as06617_task_02
main.cpp
func.cpp
)
target_include_directories(as06617_task_02 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

# GoogleTest
find_package(GTest QUIET)

if(NOT GTest_FOUND)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/release-1.12.1.zip
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
endif()

# Тесты
add_executable(as06617_task_02_tests
tests.cpp
func.cpp
)

target_include_directories(as06617_task_02_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(as06617_task_02_tests
GTest::gtest
GTest::gtest_main
)

enable_testing()
include(GoogleTest)
gtest_discover_tests(as06617_task_02_tests)
18 changes: 18 additions & 0 deletions trunk/as06617/task_02/src/func.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "func.h"
#include <cmath>

// Линейная модель
double linear(double y, double u) {
return model_params::A * y + model_params::B * u;
}

// Нелинейная модель
double nonlinear(double y,
double y_prev,
Comment thread
a-osovets marked this conversation as resolved.
double u,
double u_prev) {
return model_params::A * y
- model_params::B * (y_prev * y_prev)
+ model_params::C * u
Comment thread
a-osovets marked this conversation as resolved.
+ model_params::D * std::sin(u_prev);
}
22 changes: 22 additions & 0 deletions trunk/as06617/task_02/src/func.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <cmath>

namespace model_params {
// Параметры модели
constexpr int STEPS_COUNT = 10;
constexpr double A = 0.99;
constexpr double B = 0.01;
constexpr double C = 0.5;
constexpr double D = 0.1;
constexpr double INITIAL_Y = 18.0;
}

// Функции динамики системы
double linear(double y, double u);

double nonlinear(double current_y,
double previous_y,
double control_u,
double previous_u);

63 changes: 63 additions & 0 deletions trunk/as06617/task_02/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <iostream>
#include <vector>
#include "func.h"

#ifdef _WIN32
#include <windows.h>
#endif

using namespace std;
using namespace model_params; // 👈 ВАЖНО

static void simulateLinear(const vector<double>& input) {
double y = INITIAL_Y;
cout << "=== Линейная модель ===\n";
cout << "y0 = " << INITIAL_Y << '\n';

for (int i = 0; i < STEPS_COUNT; ++i) {
y = linear(y, input[i]);
cout << "Шаг " << i + 1 << ": y = " << y << '\n';
}
}

static void simulateNonlinear(const vector<double>& input) {
double y = INITIAL_Y;
double y_prev = INITIAL_Y;

cout << "\n=== Нелинейная модель ===\n";
cout << "y0 = " << INITIAL_Y << '\n';

for (int i = 0; i < STEPS_COUNT; ++i) {
double u_prev = (i == 0) ? input[0] : input[i - 1];
double y_old = y;

y = nonlinear(y, y_prev, input[i], u_prev);

cout << "Шаг " << i + 1 << ": y = " << y << '\n';
y_prev = y_old;
}
}

int main() {

#ifdef _WIN32
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
#endif

vector<double> input;
input.reserve(STEPS_COUNT);

for (int i = 0; i < STEPS_COUNT; ++i) {
switch (i % 3) {
case 0: input.push_back(5); break;
case 1: input.push_back(7); break;
default: input.push_back(0); break;
}
}

simulateLinear(input);
simulateNonlinear(input);

return 0;
}
60 changes: 60 additions & 0 deletions trunk/as06617/task_02/src/tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <gtest/gtest.h>
#include "func.h"
#include <cmath>

using namespace model_params;

// ===== Linear model tests =====

TEST(LinearModel, ZeroInput) {
EXPECT_DOUBLE_EQ(linear(0.0, 0.0), 0.0);
}

TEST(LinearModel, ZeroControl) {
const double y = INITIAL_Y;
EXPECT_DOUBLE_EQ(linear(y, 0.0), A * y);
}

TEST(LinearModel, ZeroState) {
const double u = 5.0;
EXPECT_DOUBLE_EQ(linear(0.0, u), B * u);
}

TEST(LinearModel, TypicalValues) {
const double y = INITIAL_Y;
const double u = 5.0;
EXPECT_DOUBLE_EQ(linear(y, u), A * y + B * u);
}

// ===== Nonlinear model tests =====

TEST(NonLinearModel, ZeroInput) {
EXPECT_DOUBLE_EQ(nonlinear(0.0, 0.0, 0.0, 0.0), 0.0);
}

TEST(NonLinearModel, ZeroControlSignal) {
const double y = INITIAL_Y;
EXPECT_DOUBLE_EQ(
nonlinear(y, y, 0.0, 0.0),
A * y - B * (y * y)
);
}

TEST(NonLinearModel, ZeroStateValue) {
const double u = 5.0;
EXPECT_DOUBLE_EQ(
nonlinear(0.0, 0.0, u, u),
C * u + D * std::sin(u)
);
}

TEST(NonLinearModel, TypicalValues) {
const double y = INITIAL_Y;
const double u = 5.0;

const double expected =
A * y - B * (y * y) +
C * u + D * std::sin(u);

EXPECT_DOUBLE_EQ(nonlinear(y, y, u, u), expected);
}
Loading