Pergunta

Considerando esse código:

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

Quero testar se eu preencher o vetor com 3 valores, minhas funções serão chamadas na ordem e quantidade adequadas.Por exemplo, meu teste pode ser mais ou menos assim:

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()

Como você recomenda testar isso?Existe algum meio de fazer isso com as estruturas CppUnit ou GoogleTest?Talvez alguma outra estrutura de teste unitário permita realizar tais testes?

Eu entendo que provavelmente isso é impossível sem chamar nenhuma função de depuração dessas funções, mas pelo menos isso pode ser feito automaticamente em alguma estrutura de teste.Não gosto de verificar os logs de rastreamento e verificar se estão corretos.

Atualização:Estou tentando verificar não apenas o estado de um objeto, mas também o ordem de execução para evitar problemas de desempenho o mais cedo possível (e em geral quero saber se meu código é executado exatamente como eu esperava).

Foi útil?

Solução

Se você estiver interessado em desempenho, recomendo que você escreva um teste que meça o desempenho.

Verifique a hora atual, execute o método que o preocupa e verifique a hora novamente.Afirme que o tempo total gasto é menor que algum valor.

O problema de verificar se os métodos são chamados em uma determinada ordem é que seu código terá que ser alterado e você não deseja atualizar seus testes quando isso acontecer.Você deve se concentrar em testar o exigência real em vez de testar os detalhes de implementação que atendem a esse requisito.

Dito isto, se você realmente quiser testar se seus métodos são chamados em uma determinada ordem, você precisará fazer o seguinte:

  1. Mova-os para outra turma, chame-a de Colaborador
  2. Adicione uma instância desta outra classe à classe ToBeTested
  3. Use uma estrutura de simulação para definir a variável de instância em ToBeTested para ser uma simulação da classe Collaborator
  4. Chame o método em teste
  5. Use sua estrutura de simulação para afirmar que os métodos foram chamados em sua simulação na ordem correta.

Não sou um falante nativo de cpp, então não posso comentar sobre qual estrutura de simulação você deve usar, mas vejo que alguns outros comentaristas adicionaram sugestões nesse sentido.

Outras dicas

Você poderia conferir mockpp.

Você deve ser capaz de usar qualquer boa estrutura de simulação para verificar se as chamadas para um objeto colaborador são feitas em uma ordem específica.

No entanto, geralmente você não testa se um método faz algumas chamadas para outros métodos na mesma classe...por que você?

Geralmente, quando você está testando uma classe, você só se preocupa em testar seu estado publicamente visível.Se você testar mais alguma coisa, seus testes o impedirão de refatorar mais tarde.

Eu poderia fornecer mais ajuda, mas não acho que seu exemplo seja consistente (onde está a implementação do método AddContained?).

Em vez de tentar descobrir quantas funções foram chamadas e em que ordem, encontre um conjunto de entradas que só possa produzir uma saída esperada se você chamar as coisas na ordem correta.

Algumas estruturas de simulação permitem configurar expectativas ordenadas, o que permite dizer exatamente quais chamadas de função você espera em uma determinada ordem.Por exemplo, Rinocerontes para C# permite isso.

Não sou um codificador C++, portanto não sei o que está disponível para C++, mas esse é um tipo de ferramenta que pode permitir o que você está tentando fazer.

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

Este é um bom artigo sobre objetos vinculados ao contexto.Ele contém algumas coisas muito avançadas, mas se você não é preguiçoso e realmente quer entender esse tipo de coisa, será muito útil.

No final você poderá escrever algo como:CalltraCingAttribute ()] Public Class Traceme:ContextBoundObject {...}

Você pode usar estruturas de depuração ACE (ou similares) e, em seu teste, configurar o objeto de depuração para transmitir para um arquivo.Então você só precisa verificar o arquivo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top