• Like
  • Save
Юнит-тестирование и Google Mock. Влад Лосев, Google
Upcoming SlideShare
Loading in...5
×
 

Юнит-тестирование и Google Mock. Влад Лосев, Google

on

  • 11,815 views

Владимир Лосев, Google...

Владимир Лосев, Google

Закончил математико-механический факультет Санкт-Петербургского государственного университета в 1995 году. Работал в компаниях Motоrola, Fair Isaac и Yahoo. С 2008 года работает в Google, в группе, занимающейся вопросами повышения производительности инженеров.

Тема доклада
Юнит-тестирование и Google Mock.

Тезисы
В модульных (юнит) тестах каждый элемент программы тестируется по отдельности, в изоляции от других. Такие тесты исполняются очень быстро, поэтому их можно запускать когда угодно, что позволяет отлавливать дефекты на самых ранних стадиях разработки. Однако для тестирования объекта в изоляции от других необходимо имитировать поведение связанных с ним объектов, что на C++ довольно утомительное занятие. Разработанная в Googlе библиотека для создания и использования mock-объектов — Google Mock — позволяет существенно упростить этот процесс и ускорить написание тестов. В докладе пойдет речь о принципах и возможностях библиотеки, примерах её использования и её внутреннем устройстве.

Statistics

Views

Total Views
11,815
Views on SlideShare
2,695
Embed Views
9,120

Actions

Likes
1
Downloads
19
Comments
0

17 Embeds 9,120

http://yac2011.yandex.ru 5917
http://yac2011.yandex.com 2087
http://ya-events.narod.ru 397
http://events.yandex.ru 311
http://tech.yandex.ru 263
https://tech.yandex.ru 110
http://events.indus.yandex.ru 8
http://yac.tadatuta.graymantle.yandex.ru 6
http://external.events.test.tools.yandex-team.ru 4
http://events.lynx.yandex.ru 4
http://web-chib.events.lacerta.yandex-team.ru 3
http://yaconf2011.narod.ru 3
http://target122g.load.yandex.net 2
http://test1e.tech.yandex.ru 2
http://events.yandex-team.ru 1
http://web-chib.events.pavo.yandex-team.ru 1
http://news.google.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Finding and fixing bugs takes significant portion of programmer's time, killing productivity.
  • 18 lines
  • * Copy Data is magic, explained later, we have more general action
  • * gmock takes care of the rest * checks for violation and outputs precise diagnostic messages * WILL MARK TEST AS FAILED * checks are done as soon as possible, so can drop into debugger at THAT MOMENT
  • Mention the matcher library and custom matchers.
  • * If called too many times, gmock will complain when amount is exceeded * if called too few times, gmock will complain when the mock is destroyed * Custom cardinalities possible but have never been requested
  • Can define any acyclic dependency graph with it
  • Type safe: performing incompatible operations on arguments or returning incompatible type will cause build error
  • * More advanced API for developing matchers is available
  • * First one will not compile if the method has less than 3 arguments * Can have even more advanced 
  • * Imagine a client that tries an operation and has to repeat it after 2 seconds if it fails
  • * Note: we never have defined actual socket class
  • * Google Mock doctor 

Юнит-тестирование и Google Mock. Влад Лосев, Google Юнит-тестирование и Google Mock. Влад Лосев, Google Presentation Transcript

  •   Модульное тестирование и Google Mock Владимир Лосев Google [email_address] Yet Another Conference 2011 Москва, 19 сентября 1
  • Agenda
      • Почему Google Mock?
      • Как им пользоваться
      • Примеры
    2
  • Хочешь жить без багов? Спроси меня как!
      • Ошибки снижают производительность
      • ...Если не чинить их быстро
      • Нужны автоматизированные тесты
        • Быстрые
        • Надёжные
        • Точные
      • Тестируем по одному модулю за раз
    3
  • Изоляция модулей
      • В программах на C++ абстрагируем взаимодействия между объектами через интерфейсы
      • Используем тестовые двойники (stub-, mock-объекты, и т.д.) для имитации поведения соседей
      • Используем метод внедрения зависимостей для добавления двойников
    4
  • Внедрение зависимостей
    • class SocketInterface {  public:
    •   virtual int Read(void* buffer, int size) = 0;
    • };
    • class Server {
    •   public:
    •   Server(SocketInterface* socket) : socket_(socket) {}
    •   bool ReadRequest (string* result) {
    •     char buffer[BUFFER_SIZE];
    •     int bytes_read;
    •     while ((bytes_read = socket->Read (buffer,
    •                                       BUFFER_SIZE)) > 0)
    •       result->append(buffer, buffer + bytes_read);
    •     return result->size() > 0;
    •   }
    •   private:
    •   SocketInterface* const socket_;
    • };
    5
    • class MockSocket : public SocketInterface {
    •   public:
    •   MockSocket(const char* buffer_to_read, int buffer_size)
    •       : buffer_to_read_(buffer_to_read_), size_(buffer_size),
    •         bytes_read_(0) {
    •   }
    •   virtual int Read (void* buffer, int n) {
    •     int actual_read = std::min(n, size_ - bytes_read_);
    •     memcpy(buffer, buffer_to_read_ + bytes_read_, actual_read);
    •     bytes_read_ += actual_read;
    •     return actual_read;
    •   }
    •   int bytes_read() const { return bytes_read_; }
    • private:
    •   const char* buffer_to_read_;
    •   int size_;
    •   int bytes_read_;
    • };
    Mock-объект, написанный вручную 6
  • Тест с таким объектом
    • TEST(Server_ReadRequest, ReadsCompleteRequest) {
    •   string data("1234567890123456789012345");
    •   MockSocket mock_socket(data.data(), data.size());
    •   Server server(&mock_socket);
    •   string buffer;
    •   EXPECT_TRUE(server.ReadRequest(&buffer));
    •   EXPECT_EQ(data, buffer);
    • }
      • Проверяет только результат, а не взаимодействие
    7
  • Google Mock
      • Google C++ Mocking Framework/Google Mock/gMock
      • Написан в 2007 г. Жаньонгом Ваном (Zhanyong Wan)
      • Код открыт в 2008 г.
      • Лежит на  code.google.com/p/googlemock
      • Используется во многих проектах с открытым кодом (Chromium, LLVM)
    8
  • Нужна библиотека для написания тестов
      • Хорошо интегрирован с Google Test
      • Лежит на  http://code.google.com/p/googletest
      • Позволяет легко и быстро писать тесты:
    •   #include <gtest/gtest.h>
    •   TEST(MathTest, ArithmeticsStillWorks) {
    •     EXPECT_EQ(4, 2 * 2);
    •   }
    9
  • Mock-объект на Google Mock 
    • class MockSocket : public SocketInterface {
    •   public:
    •   MOCK_METHOD2(Read, int(void* buffer, int n));
    • };
    10
  • Определение ожиданий 
    • class MockSocket : public SocketInterface {
    •   public:
    •   MOCK_METHOD2(Read, int(void* buffer, int n));
    • };
    •   EXPECT_CALL(mock_socket, Read(…))
    11
  • Описние параметров
    • class MockSocket : public SocketInterface {
    •   public:
    •   MOCK_METHOD2(Read, int(void* buffer, int n));
    • };
    •   EXPECT_CALL(mock_socket, Read(_, Ge(25)))
    12
  • Описание количества вызовов 
    • class MockSocket : public SocketInterface {
    •   public:
    •   MOCK_METHOD2(Read, int(void* buffer, int n));
    • };
    •   EXPECT_CALL(mock_socket, Read(_, Ge(25)))
    •       .Times(2)
    13
  • Описание поведения
    • class MockSocket : public SocketInterface {
    •   public:
    •   MOCK_METHOD2(Read, int(void* buffer, int n));
    • };
    •   string data(&quot;1234567890123456789012345&quot;);
    •   EXPECT_CALL(mock_socket, Read(_, Ge(25)))
    •       .Times(2)
    •       .WillOnce(DoAll(CopyData(data),
    •                       Return(data.size())))
    •       .WillOnce(Return(0));
    14
  • Полный тест
    • class MockSocket : public SocketInterface {
    •   public:
    •   MOCK_METHOD2(Read, int(void* buffer, int n));
    • };
    • TEST(Server_ReadRequest, ReadsCompleteRequest) {
    •   MockSocket mock_socket;
    •   string data(&quot;1234567890123456789012345&quot;);
    •   EXPECT_CALL(mock_socket, Read(_, Ge(25)))
    •       .Times(2)
    •       .WillOnce(DoAll(CopyData(data),
    •                       Return(data.size())))
    •       .WillOnce(Return(0));
    •   Server server(&mock_socket);
    •   string result;
    •   EXPECT_TRUE(server.ReadRequest(&result));
    •   EXPECT_EQ(data, result);
    • }
    15
  • Предикаты
      • ...на стероидах
        • Проверяют условия
        • Описывают эти условия
        • Предоставляют объяснения
    • Примеры:
    • Простые: 42, _, Gt(32), NotNull()
    • Составные: AllOf(m1, ...), AnyOf(m1, ...), Not(matcher)
    • Для контейнеров:  Contains(matcher), Each(matcher)
    • ElementsAre(e1, ..., en), ElementsAreArray(arr)
      • Можно определять собственные
    16
  • Количество вызовов
      • Указывается в методе Times():
    •   EXPECT_CALL(mock, Foo()). Times(cardinality) ;
      • Можно указывать:
        • 2
        • Exactly(2)
        • AtLeast(3)
        • AtMost(5)
        • Between(3, 4)
    17
  • Порядок
      • По умолчанию порядок вызовов не задаётся
      • Можно указывать полный или частичный порядок
      • Отсутствие циклов гаранировано
    • {
    •   InSequence s;
    •   EXPECT_CALL(mock, A());
    •   EXPECT_CALL(mock, B());
    • }
    • Sequence s1, s2;
    • EXPECT_CALL(mock, A()).InSequence(s1, s2);
    • EXPECT_CALL(mock, B()).InSequence(s1);
    • EXPECT_CALL(mock, C()).InSequence(s2);
    18
  • Действия
      • Определяются в методах WillOnce() и WillRepeatedly() 
      • Определяют поведение mock-объекта
      • Статически типизированы (type-safe)
    • SetArrayArgument<>(), SetArg<>(), SaveArg<>(), Return(value), ReturnRef(object), Invoke(function), Invoke(object, method)
    • Составные: DoAll(action1, action2, ...)
      • Можно определять самому
      • ON_CALL() определяет действие по умолчанию чтобы можно было не указывать WillOnce или WillRepeatedly
    19
  • Расширяем Google Mock – предикаты
    • MATCHER(IsEven, &quot;&quot;) { return arg % 2 == 0; }
    • MATCHER_P(IsDivisibleBy, n, &quot;&quot;) {
    •   return arg % n == 0;
    • }
    • MATCHER_P2(IsSumOf, a, b, &quot;&quot;) {
    •   return arg == a + b;
    • }
    • EXPECT_CALL(mock, Foo(IsSumOf(x, 7)));
      • Не должны вызывать сторонних эффектов
      • Не должны содержать изменяемого состояния
      • Есть более продвинутое API для создания предикатов
    20
  • Расширяем Google Mock – действия
    • ACTION(ChooseCallee) {
    •   if (arg0)
    •     arg1->f();
    •   else
    •     arg2->g();
    • }
    • ACTION_P(CopyData, data) {
    •   std::copy(data.data(),
    •             data.data() + data.size(),
    •             arg0);
    • }
      • Доступ к аргументам метода: arg0, arg1, ...
      • Есть более продвинутое API для создания действий
    21
  • Пример: внедрение ошибок
    • TEST(FileReaderTest, HandlesConnectionClosed) {
    •   MockSocket mock_socket;
    •   MockServerManager mock_server_manager;
    •   EXPECT_CALL(mock_socket, Read(_, Ge(25))
    •       .WillOnce( SetErrnoAndReturn (EPIPE, -1));
    •   EXPECT_CALL(mock_server_manager, OnConnectionLost());
    •   Server server(&mock_socket, &mock_server_manager);
    •   EXPECT_FALSE(reader.ReadRequest(&result));
    • }
    22
  • Пример: быстрый сон
    • class WallClockInterface {
    •   public:
    •   virtual time_t GetWallTime() const = 0;
    •   virtual void SleepMilliseconds(time_t ms) = 0;
    • };
    • class MockWallClock : public WallClockInterface {
    •   public:
    •   MOCK_CONST_METHOD0(GetWallTime, time_t());
    •   MOCK_METHOD1(SleepMilliseconds, void());
    • };
    23
  • Пример: быстрый сон
    • TEST(NetworkClientTest, WaitsAndRetries) {
    •   MockWallClock mock_clock;
    •   MockSocket mock_socket;
    •   InSequence s;
    •   EXPECT_CALL(mock_socket, Connect(_))
    •       .WillOnce(Return(false));
    •   EXPECT_CALL(mock_clock, GetWallTime ())
    •       .WillOnce( Return(1000) );
    •   EXPECT_CALL(mock_clock, SleepMilliseconds(2000) );
    •   EXPECT_CALL(mock_clock, GetWallTime ())
    •       .WillOnce( Return(3000) );
    •   EXPECT_CALL(mock_socket,  Connect(_) )
    •       .WillOnce(Return(true));
    •   NetworkClient client(&mock_clock, &mock_socket);
    •   EXPECT_TRUE(client.AttemptConnectWithRetry());
    • }
    24
  • Преимущества
      • Проверяет взаимодействие между объектом и соседями
      • Позволяет писать быстрые тесты
      • Позволяет писать надёжные тесты
      • Упрощает тестирование кода обработки ошибок
      • Позволяет писать код, не имея соседей
    25
  • Недостатки
      • Mock-объекты компилируются медленно
      • Малопонятная диагностика
        • Написан Google Mock Doctor, скрипт для интерпретации диагностики (GCC и LLVM)
      • Mock-нужно писать вручную
        • Есть скрипт для генерации mock-классов из определений интерфейсов или классов
    26
  • Google Mock http://code.google.com/p/googlemock http://code.google.com/p/googlemock/wiki/Documentation googlemock@googlegroups.com (English) 27