Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
190 / 51 / 19
Регистрация: 18.02.2013
Сообщений: 490
Записей в блоге: 9
1

Модульное тестирование c++

25.02.2017, 13:46. Просмотров 2390. Ответов 18
Метки нет (Все метки)

Здравствуйте.
Подскажите, пожалуйста, документацию или пример по написанию таких тестов.
Сам нагуглил только сторонние библиотеки для этого :
Раз
Два
Тут что-то совсем непонятное происходит
Как пример, нужно протестить вычисление площади и периметра прямоугольника:
C++
1
2
3
4
5
6
7
8
9
double Rectangle::calculateArea() const
{
    return a * b;
}
 
double Rectangle::calculatePerimeter() const
{
    return 2 * (a + b);
}
Тема с реализацией класса

Буду очень признателен за помощь.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.02.2017, 13:46
Ответы с готовыми решениями:

Модульное тестирование
недавно понял, что сложно делать программу без тестирования её модулей. При изменении кода через...

Модульное программирование в с++
Привет всем. Проблема такая.. Есть модуль данных. Так вот надо мне использовать эти переменные...

Модульное программирование
Прошу помощи в решении моей задачи.Заранее благодарен. "Модульное программирование" ...

Модульное программирование
Привет форумчане! В общем, решил сделать модуль с 3-мя ф-циями: mod.h void...

18
Эксперт С++
8190 / 3786 / 817
Регистрация: 15.11.2014
Сообщений: 8,598
25.02.2017, 14:19 2
Цитата Сообщение от Gdasar Посмотреть сообщение
Сам нагуглил только сторонние библиотеки для этого
вы определитесь, чего вы хотите?
завелосипедить собственный фреймворк для тестирования.
или покрывать тестами собственные юниты.

первое вы не осилите.
второе - лучше чем gmock ничего пока ещё не придумали.
в этом случае ищите доки по нему, примеры использования.
будет что не понятно - спрашивайте.
1
190 / 51 / 19
Регистрация: 18.02.2013
Сообщений: 490
Записей в блоге: 9
25.02.2017, 19:54  [ТС] 3
Базовый класс
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class GeometryFigures
{
private:
    string Name;
public:
    void setName(string Name_new);
    string getName() const;
    virtual double calculateArea() const = 0;
    virtual double calculatePerimeter() const = 0;
    virtual void Show() const = 0;
};
 
void GeometryFigures::setName(string Name_new)
{
    Name = Name_new;
}
 
string GeometryFigures::getName() const
{
    return Name;
}
Дочерний класс
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// прямоугольник
class Rectangle : public GeometryFigures
{
private:
    double a, b;
public:
    Rectangle();
    Rectangle(double a_new, double b_new);
    void setA(double a_new);
    void setB(double b_new);
    virtual double calculateArea() const;
    virtual double calculatePerimeter() const;
    virtual void Show() const;
};
 
Rectangle::Rectangle()
{
    setName("Rectangle");
    a = 0;
    b = 0;
}
 
Rectangle::Rectangle(double a_new, double b_new)
{
    setName("Rectangle");
    a = a_new;
    b = b_new;
}
 
void Rectangle::setA(double a_new)
{
    a = a_new;
}
 
void Rectangle::setB(double b_new)
{
    b = b_new;
}
 
double Rectangle::calculateArea() const
{
    return a * b;
}
 
double Rectangle::calculatePerimeter() const
{
    return 2 * (a + b);
}
 
void Rectangle::Show() const
{
    cout << getName() << " : A = " << a << "; B = " << b
        << "; Area = " << calculateArea() << " ; Perimeter = " << calculatePerimeter() << endl;
}
Далее по порядку:
подрубаем
C++
1
2
#include "gtest/gtest.h"
#include "gmock/gmock.h"
далее делаем определение mock-класса.
Так вот вопросы:
1) делать определение mock-класса как базового так и производного? Или только виртуальных методов базового класса?
C++
1
2
3
4
5
6
7
class MockGeometryFigures : public GeometryFigures 
{
 public:
  MOCK_CONST_METHOD0(calculateArea, double());
  MOCK_CONST_METHOD0(calculatePerimeter, double());
  MOCK_CONST_METHOD0(Show, void());
};
2) нужно ли в базовом классе создавать виртуальный деструктор?
C++
1
virtual ~GeometryFigures();
Добавлено через 7 минут
Или mock-класс нужно создавать только для класса, который мы тестируем, то есть для Rectangle?

Добавлено через 45 минут
Ещё получаю ошибку в этом коде:
C++
1
2
3
4
5
6
int _tmain(int argc, _TCHAR* argv[])
{
    ::testing::InitGoogleMock(&argc, argv);
    _getch();
    return 0;
}
Ошибка 1 error LNK2001: неразрешенный внешний символ ""void __cdecl testing::InitGoogleMock(int *,wchar_t * *)" (?InitGoogleMock@testing@@YAXPAHPAPA_W@Z)" C:\Users\GdasaR\Desktop\TestTask1\ConsoleApplication1\Consol eApplication1\ConsoleApplication1.obj ConsoleApplication1

Ошибка 2 error LNK1120: неразрешенных внешних элементов: 1 C:\Users\GdasaR\Desktop\TestTask1\ConsoleApplication1\Releas e\ConsoleApplication1.exe 1 1 ConsoleApplication1
Добавлено через 1 минуту
Так тоже не работает:
C++
1
int _tmain(int argc, wchar_t** argv)
0
Эксперт С++
8190 / 3786 / 817
Регистрация: 15.11.2014
Сообщений: 8,598
25.02.2017, 22:42 4
Цитата Сообщение от Gdasar Посмотреть сообщение
далее делаем определение mock-класса.
Цитата Сообщение от Gdasar Посмотреть сообщение
нужно протестить вычисление площади и периметра прямоугольника:
mock для этого нафиг не нужен.

Цитата Сообщение от Gdasar Посмотреть сообщение
Ошибка 1 error LNK2001: неразрешенный внешний символ ""void __cdecl testing::InitGoogleMock(int *,wchar_t * *)" (?InitGoogleMock@testing@@YAXPAHPAPA_W@Z)" C:\Users\GdasaR\Desktop\TestTask1\ConsoleApplication1\Consol eApplication1\ConsoleApplication1.obj ConsoleApplication1
Ошибка 2 error LNK1120: неразрешенных внешних элементов: 1 C:\Users\GdasaR\Desktop\TestTask1\ConsoleApplication1\Releas e\ConsoleApplication1.exe 1 1 ConsoleApplication1
тестовое приложение не слинковалось с библиотекой
необходимо указать пути,
где искать lib файлы,
и их имена.
0
190 / 51 / 19
Регистрация: 18.02.2013
Сообщений: 490
Записей в блоге: 9
26.02.2017, 11:17  [ТС] 5
Цитата Сообщение от hoggy Посмотреть сообщение
mock для этого нафиг не нужен.
а что тогда нужно? только googletest ?

Добавлено через 11 минут
Использовал вот этот перевод.

Так как тогда протестить?

Добавлено через 54 секунды
Цитата Сообщение от hoggy Посмотреть сообщение
где искать lib файлы
Не вижу где тут лежат либы.
0
2533 / 1193 / 357
Регистрация: 30.11.2013
Сообщений: 3,817
26.02.2017, 11:17 6
hoggy, подскажите хак с доступом к приват полям через шаблоны используется в тестировании?
0
Игогошка!
1798 / 705 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
26.02.2017, 11:52 7
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
подскажите хак с доступом к приват полям через шаблоны используется в тестировании?
Смысл в доступе к приватному содержимому?
0
2533 / 1193 / 357
Регистрация: 30.11.2013
Сообщений: 3,817
26.02.2017, 11:57 8
ct0r, тестирование private/protected методовов? Или чёрный ящик не тестируется?
0
Игогошка!
1798 / 705 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
26.02.2017, 12:55 9
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
тестирование private/protected методовов? Или чёрный ящик не тестируется?
Нужно тестировать не отдельные методы, а фичи, которые предоставляет компонент. Модульные тесты должны читаться как спецификация, а не фигня, которая проверяет, что blabla == ogogo после выполнения ololo.
Если для этого внезапно должны отдельно тестироваться приватные вещи, то это признак проблем в дизайне.
1
2533 / 1193 / 357
Регистрация: 30.11.2013
Сообщений: 3,817
26.02.2017, 13:43 10
Цитата Сообщение от ct0r Посмотреть сообщение
что blabla == ogogo после выполнения ololo
но ведь unit тесты все такие))))
0
Эксперт С++
8190 / 3786 / 817
Регистрация: 15.11.2014
Сообщений: 8,598
26.02.2017, 14:05 11
Я с планшета, выделять цитаты не умею.
Если в кратце - доступ к привату не нужен.
Тестируем чёрный ящик.
Что он там делает внутри - его сложности.

А тс нужно отложить в сторону тестирование,
И сначала научиться собирать/ линковаться с библиотеками.
1
2533 / 1193 / 357
Регистрация: 30.11.2013
Сообщений: 3,817
26.02.2017, 14:29 12
Тогда я не понял просто сарказма уважаемого Убежденный Что на собеседовании показалось самым сложным
0
Эксперт С++
8190 / 3786 / 817
Регистрация: 15.11.2014
Сообщений: 8,598
26.02.2017, 14:38 13
rikimaru2013,
Да это же шутка такая)
Доступ к приватам через шаблон - ни разу не востребованная багофича)
Такое даже ревью никогда не пройдёт

В реальности могут быть ситуации,
Когда нужно тестить не просто функциональность,
Но и взаимодействие между различными компонентами,
С которыми механизм работает где-то у себя в потрохах
Но вот для таких ситуаций и был придуман mock
1
190 / 51 / 19
Регистрация: 18.02.2013
Сообщений: 490
Записей в блоге: 9
26.02.2017, 22:07  [ТС] 14
Цитата Сообщение от hoggy Посмотреть сообщение
mock для этого нафиг не нужен.
Что Вы имели ввиду?
Что для такой тривиальной задачи можно заюзать что-то другое?

Добавлено через 2 часа 56 минут
Ну, в общем, слинковалось.
Но как протестить функцию без создания mock-класса?
0
190 / 51 / 19
Регистрация: 18.02.2013
Сообщений: 490
Записей в блоге: 9
26.02.2017, 23:30  [ТС] 15
Написал вот таким образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MockRectangleTest : public ::testing::Test 
{
};
 
TEST(RectangleTest, calculatePerimeterTest)
{
    Rectangle rect;
    rect.setA(5);
    rect.setB(6);
    ASSERT_TRUE(rect.calculatePerimeter() == 22);
}
 
int _tmain(int argc, char** argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
Так ли я сделал? Заранее спасибо за Ваши замечания и подсказки.
0
Миниатюры
Модульное тестирование c++  
Эксперт С++
8190 / 3786 / 817
Регистрация: 15.11.2014
Сообщений: 8,598
27.02.2017, 00:05 16
Gdasar,
Нафига вы сделали класс-пустышку?
1
190 / 51 / 19
Регистрация: 18.02.2013
Сообщений: 490
Записей в блоге: 9
27.02.2017, 12:10  [ТС] 17
Всё, я дропнул пустышку.
И функцию теста переписал иначе
C++
1
2
3
4
5
6
7
TEST(RectangleTest0, calculatePerimeter)
{
    Rectangle rect;
    rect.setA(5);
    rect.setB(6);
    ASSERT_EQ(21, rect.calculatePerimeter());
}
Больше замечаний нет?

Добавлено через 51 минуту
Кстати, а как протестировать вот такие реализации функций при отрицательных параметрах?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
double Rectangle::calculateArea() const
{
    if(a < 0.0 || b < 0.0)
    {
        throw - 1;
    }
    return a * b;
}
 
double Rectangle::calculatePerimeter() const
{
    if(a < 0.0 || b < 0.0)
    {
        throw - 1;
    }
    return 2 * (a + b);
}
Как поймать исключение, которое означает, что такой фигуры не существует?

Добавлено через 13 минут
Во, нагуглилось:
C++
1
ASSERT_THROW(rect.calculatePerimeter(), int);
0
3895 / 2117 / 366
Регистрация: 05.10.2013
Сообщений: 6,144
Записей в блоге: 167
25.05.2017, 00:39 18
В этой статье два примера по GMock: Using a Mock Library to make Unit Testing Easier in C++ Пока что лучше этих примеров не находил.

В них есть кое-какие опечатки. Я их исправил. Использую VS 2015. Включил в проект GTest и GMock. Подключил по относительному пути (относительно $(SolutionDir)), поэтому можете скачать проекты и попробовать сразу запустить тесты. Если не запустятся, то опишите ошибки.
Я решил, что лучше GTest и GMock включать исходниками в проект, а не либами, как во многих туторах советуют, так как места занимает меньше и мороки меньше. Мне так удобнее. Для визуального отображения в Test Explorer'e можно поставить бесплатное дополнение для VS: Google Test Adapter

Приятной разработки через тестирование!
2
Форумчанин
Эксперт CЭксперт С++
8159 / 5007 / 1436
Регистрация: 29.11.2010
Сообщений: 13,458
25.05.2017, 11:36 19
А мне для юнит тестов нравится Catch. Простенькая, легковесная, подключается как хедер, осваивается за пару часов.
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.05.2017, 11:36

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

модульное программирование
Народ я тут прилягу написал по своей лабе но у меня проблема она не запускаеться вот кидает эти...

Модульное программировапние на С++ (консоль)
Помогите пожалуйста подкорректировать код. Задание было таким: Разместить определение данных в...

Модульное програмирование, ошибка C2228
Нужно сделать функцию заполняющую вектор вывод: 1&gt;------ Build started: Project:...

Модульное деление на степень двойки
Раньше я всегда использовал примерной такой подход : int mod = 8; int a = 90412488; char b =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.