Как проверить порядок вызова функций - PullRequest
3 голосов
/ 17 сентября 2008

Учитывая такой код:

class ToBeTested {
public:
  void doForEach() {
    for (vector<Contained>::iterator it = m_contained.begin(); it != m_contained.end(); it++) {
       doOnce(*it);
       doTwice(*it);
       doTwice(*it);
    }
  }
  void doOnce(Contained & c) {
    // do something
  }
  void doTwice(Contained & c) {
    // do something
  }

  // other methods
private:
  vector<Contained> m_contained;
}

Я хочу проверить, что если я заполню вектор 3 значениями, мои функции будут вызываться в правильном порядке и количестве. Например, мой тест может выглядеть примерно так:

tobeTested.AddContained(one);
tobeTested.AddContained(two);
tobeTested.AddContained(three);

BEGIN_PROC_TEST()
SHOULD_BE_CALLED(doOnce, 1)
SHOULD_BE_CALLED(doTwice, 2)
SHOULD_BE_CALLED(doOnce, 1)
SHOULD_BE_CALLED(doTwice, 2)
SHOULD_BE_CALLED(doOnce, 1)
SHOULD_BE_CALLED(doTwice, 2)

tobeTested.doForEach()
END_PROC_TEST()

Как вы рекомендуете проверить это? Есть ли способы сделать это с помощью CppUnit или GoogleTest? Может быть, какие-то другие модульные тестовые среды позволяют выполнять такие тесты?

Я понимаю, что, вероятно, это невозможно без вызова каких-либо функций отладки из этих функций, но, по крайней мере, это можно сделать автоматически в некоторой тестовой среде. Я не люблю сканировать журналы трассировки и проверять их правильность.

UPD : я пытаюсь проверить не только состояние объектов, но также порядок выполнения , чтобы избежать проблем с производительностью при первой возможности Этап (и вообще я хочу знать, что мой код выполняется точно так, как я ожидал).

Ответы [ 7 ]

1 голос
/ 17 сентября 2008

Вместо того, чтобы пытаться выяснить, сколько функций было вызвано и в каком порядке, найдите набор входных данных, которые могут давать ожидаемый результат, только если вы вызываете вещи в правильном порядке.

1 голос
/ 17 сентября 2008

Если вы заинтересованы в производительности, я рекомендую вам написать тест, который измеряет производительность.

Проверьте текущее время, запустите метод, который вас интересует, затем проверьте время снова. Утверждают, что общее время, которое уходит, меньше некоторого значения.

Проблема с проверкой того, что методы вызываются в определенном порядке, состоит в том, что ваш код должен будет измениться, и вам не нужно обновлять свои тесты, когда это произойдет. Вам следует сосредоточиться на тестировании фактического требования вместо того, чтобы тестировать детали реализации, отвечающие этому требованию.

Тем не менее, если вы действительно хотите проверить, что ваши методы вызываются в определенном порядке, вам нужно сделать следующее:

  1. Переместите их в другой класс, назовите его Collaborator
  2. Добавить экземпляр этого другого класса в класс ToBeTested
  3. Использование фиктивной структуры для установки переменной экземпляра в ToBeTested как макет класса Collborator
  4. Вызовите тестируемый метод
  5. Используйте ваш макет, чтобы утверждать, что методы были вызваны на вашем макете в правильном порядке.

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

1 голос
/ 17 сентября 2008

Вы должны быть в состоянии использовать любую хорошую среду для насмешки, чтобы убедиться, что вызовы взаимодействующего объекта выполняются в определенном порядке.

Однако вы обычно не проверяете, чтобы один метод вызывал другие методы в том же классе ... с чего бы вы?

Как правило, когда вы тестируете класс, вы заботитесь только о тестировании его публично видимого состояния. Если вы тестируете что-нибудь еще, ваши тесты не позволят вам выполнить рефакторинг позже.

Я мог бы предоставить больше помощи, но я не думаю, что ваш пример непротиворечив (Где реализация метода AddContained?).

1 голос
/ 17 сентября 2008

Вы можете проверить mockpp .

0 голосов
/ 17 сентября 2008

Вы можете использовать ACE (или аналогичные) среды отладки и в своем тесте настроить объект отладки для потоковой передачи в файл. Тогда вам просто нужно проверить файл.

0 голосов
/ 17 сентября 2008

http://msdn.microsoft.com/en-au/magazine/cc301356.aspx

Это хорошая статья о связанных с контекстом объектах. Он содержит такие продвинутые вещи, но если вы не ленивы и действительно хотите понять такие вещи, это будет действительно полезно.

В конце вы сможете написать что-то вроде: [CallTracingAttribute ()] открытый класс TraceMe: ContextBoundObject {...}

0 голосов
/ 17 сентября 2008

Некоторые фальшивые фреймворки позволяют вам устанавливать упорядоченные ожидания, которые позволяют точно сказать, какие вызовы функций вы ожидаете в определенном порядке. Например, RhinoMocks для C # позволяет это.

Я не программист на C ++, поэтому я не знаю, что доступно для C ++, но это один из типов инструментов, который может разрешить то, что вы пытаетесь сделать.

...