Вопрос

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

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;
}

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

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?Может быть, какая-то другая среда модульного тестирования позволяет выполнять такие тесты?

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

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

Это было полезно?

Решение

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

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

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

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

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

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

Другие советы

Вы могли бы проверить макет.

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top