Pergunta

Como você teste de unidade um grande aplicativo MFC UI?

Nós temos alguns aplicativos MFC grandes que têm estado em desenvolvimento há muitos anos, nós usamos algumas ferramentas de controle de qualidade padrão automatizado para executar scripts básicos para verificar fundamentos, arquivo aberto etc. Estes são executados pelo grupo QA postar a compilação diária.

Mas nós gostaríamos de introduzir procedimentos de tal forma que os desenvolvedores individuais pode construir e executar testes contra diálogos, menus e outros elementos visuais do aplicativo antes de enviar o código para a compilação diária.

Já ouvi falar de técnicas tais como botões de teste escondidas em caixas de diálogo que só aparecem em compilações de depuração, existem kits de ferramentas padrão para isso.

Ambiente é C ++ / C / Fortran, MSVC 2005, a Intel Fortran 9.1, Windows XP / Vista x86 e x64.

Foi útil?

Solução

Depende de como a App está estruturado. Se a lógica e GUI código é separada (MVC), em seguida, testando a lógica é fácil. Dê uma olhada em Michael Feathers "Box Humble Dialog" (PDF).

EDIT: Se você pensar sobre isso: Você deve muito cuidado refatorar se o App não está estruturado dessa maneira. Não há outra técnica para testar a lógica. Scripts que simulam cliques são apenas arranhando a superfície.

É realmente muito fácil:

Suponha que seu controle / janela / whatever altera o conteúdo de uma caixa de listagem quando o usuário clica em um botão e você quer certificar-se a caixa de listagem contém o material logo após o clique.

  1. Refactor para que haja uma lista separada com os itens para a caixa de listagem ao show. Os itens são armazenados na lista e não são extraídos de onde quer que seus dados vem. O código que faz parte da lista listbox coisas só sabe sobre a nova lista.
  2. Em seguida, você cria um novo objeto controlador que irá conter o código da lógica. O método que manipula o clique de botão só chama mycontroller-> ButtonWasClicked (). Ele não sabe sobre a caixa de listagem ou anythings else.
  3. MyController :: ButtonWasClicked () faz o que é preciso ser feito para a lógica destina-se, prepara a lista item e informa o controle para atualização. Para que isso funcione você precisa separar o controlador e o controle através da criação de uma interface (classe virtual pura) para o controle. O controlador só conhece um objeto desse tipo, não o controle.

É isso. O controlador contém o código da lógica e sabe o controle apenas através da interface. Agora você pode escrever teste de unidade regular para MyController :: ButtonWasClicked () zombando de controle. Se você não tem idéia do que estou falando, leia o artigo Michaels. Duas vezes. E novamente depois disso.
(Nota to self: deve aprender a não tagarelar que muito)

Outras dicas

Uma vez que você mencionou MFC, eu achei que você tiver um aplicativo que seria difícil de obter sob um equipamento de teste automatizado. Você vai observar melhores benefícios de estruturas unidade de teste quando você construir testes como você escrever o código .. Mas tentando adicionar um novo recurso de forma orientado a testes para uma aplicação que não é projetado para ser testada .. pode ser trabalho duro e bem frustrante.

Agora o que vou propor é definitivamente trabalho duro .. mas com um pouco de disciplina e perseverança você vai ver o benefício em breve.

  • Primeiro você vai precisar de algum apoio de gestão para novas correções para demorar um pouco mais. Certifique-se de que todos entendem o porquê.
  • Em seguida comprar uma cópia do welc livro . Lê-lo de capa a capa, se você tem o tempo ou se você está muito pressionado, digitalizar o índice para encontrar o sintoma seu aplicativo está exibindo. Este livro contém uma grande quantidade de bons conselhos e é apenas o que você precisa quando se tenta obter testável código existente. text alt
  • Em seguida, para cada nova correção / mudança, passar algum tempo e entender a área que você está indo para trabalhar. Escrever alguns testes em uma variante xUnit de sua escolha (disponível gratuitamente) para o exercício atual comportamento.
  • Certifique-se todos os testes passam. Escrever um novo teste que exerce o comportamento necessário ou o bug.
  • Escrever código para fazer esta última passagem de teste.
  • Refactor impiedosamente dentro da área sob testes para melhorar o projeto.
  • Repita para cada nova mudança que você tem que fazer para o sistema a partir daqui. Não há exceções a esta regra.
  • Agora a terra prometida : ilhas Logo crescentes de código bem testado vai começar a superfície. Mais e mais código cairia sob a suite de testes automatizados e as mudanças tornam-se progressivamente mais fácil de fazer. E isso é porque lenta e seguramente o desenho subjacente torna-se mais testável.

A saída fácil era a minha resposta anterior. Esta é a difícil, mas a direita para fora caminho.

Sei que esta é uma questão datados, mas para aqueles de nós que ainda trabalho com MFC, o Microsoft C ++ Unit Testing Framework no VS2012 funciona bem.

O Procedimento Geral:

  1. Compilar o projeto MFC como uma biblioteca estática
  2. Adicionar um projeto de teste nova Unidade nativo para sua solução.
  3. No Test Project, adicione seu projeto MFC como uma referência.
  4. Em Propriedades de configuração do Projeto de Teste, adicione a diretórios para seus arquivos de cabeçalho Incluir.
  5. No Linker, opções de entrada adicionar seu MFC.lib; nafxcwd.lib; LIBCMTD.LIB;
  6. Em 'Ignorar específica bibliotecas padrão' add nafxcwd.lib; LIBCMTD.LIB;
  7. Em Geral adicionar a localização do seu MFC arquivo exportado lib.

O https: // stackoverflow. com / perguntas / 1146338 / error-LNK2005 nova-and-delete-já-definido-in-libcmtd-libnew-obj tem uma boa descrição de por que você precisa do nafxcwd.lib e LIBCMTD.LIB.

A outra coisa importante para verificar em projetos legados. Em geral Propriedades de configuração, certifique-se ambos os projetos estão usando o mesmo 'Conjunto de caracteres'. Se o seu MFC está usando um conjunto de caracteres Multi-Byte você vai precisar do teste MS para fazê-lo bem.

Apesar de não ser perfeito, o melhor que eu encontrei para isso é AutoIt http://www.autoitscript.com/ AutoIt3

"AutoIt v3 é um freeware BASIC-como linguagem de script concebido para automatizar a GUI do Windows e scripting geral. Ele usa uma combinação de teclas simulados, o movimento do mouse e janela / manipulação de controle, a fim de automatizar tarefas de uma forma não é possível ou fiável com outras línguas (por exemplo, VBScript e SendKeys). AutoIt também é muito pequena, auto-suficiente e será executado em todas as versões do Windows out-of-the-box sem "durações" irritantes necessários! "

Isso funciona bem quando você tem acesso ao código-fonte do aplicativo que está sendo conduzido, porque você pode usar o número de identificação de recursos dos controles que deseja dirigir. Desta forma, você não precisa se preocupar com cliques do mouse simulados sobre determinados pixels. Infelizmente, em um aplicativo de legado, você poderá descobrir que o ID do recurso não são exclusivos, o que pode causar problemas. Contudo. é muito simples para alterar os IDs de ser único e reconstruir.

A outra questão é que você vai encontrar problemas de tempo. Eu não tenho uma solução experimentada e verdadeira para estes. Tentativa e erro é o que eu usei, mas isso claramente não é escalável. O problema é que o script AutoIT deve aguardar a aplicação de teste para responder a um comando antes de os problemas de script o próximo comando ou de seleção para a resposta correta. Às vezes não é fácil encontrar um evento conveniente esperar e assistir.

Meu sentimento é que, no desenvolvimento de uma nova aplicação, gostaria de insistir em uma maneira consistente de sinal de "READY". Isso seria útil para os usuários humanos, bem como scripts de teste! Este pode ser um desafio para um aplicativo de legado, mas talvez você possa apresentá-lo em pontos problemáticos e lentamente se espalhar para todo o aplicativo como a manutenção continua.

Embora não pode lidar com o lado da UI, eu teste de unidade código MFC utilizando a biblioteca Teste Boost. Há um artigo Code Project sobre como começar:

projetar objetos robustos com impulso

Bem, temos um destes humongous Aplicativos MFC no local de trabalho. Seu uma dor gigantesca para manter ou aumentar ... é uma enorme bola de lama, mas agora ele ancinhos nos moolah.Anyways

  • Rational Robot para fazer testes de fumo e similares.
  • Outra abordagem que tem tido algum sucesso é criar uma pequena linguagem específica de produto e testes scripts que o uso de VBScript e um pouco de magia espionagem da alavanca de controle. Transformar acções comuns em comandos .. v.g. OpenDatabase seria um comando que por sua vez vai injetar os blocos de script necessários para clicar em Menu> Arquivo> "Open ...". Você, então, criar planilhas de Excel que são uma série de tais comandos. Estes comandos podem ter parâmetros também. Algo como um teste de ajuste .. mas mais trabalho. Depois de ter a maioria dos comandos comuns identificados e scripts prontos. É escolher e montar scripts (marcados por CommandIDs) para escrever novos testes. Um teste-runner analisa estas folhas de Excel, combina todos os pequenos blocos de script em um script de teste e executa-lo.

    1. OpenDatabase "C: \ testes \ MyDB"
    2. OpenDialog "Adicionar modelo"
    3. AddModel "M0001", "MyModel", 2,5, 100
    4. PressOK
    5. SaveDatabase

HTH

Na verdade, temos vindo a utilizar o Rational Team de teste, em seguida, Robot, mas nos últimos discussões com Rational descobrimos que não têm planos para suportar aplicações x64 nativos com foco mais em .NET, então decidimos mudar ferramentas automatizadas de controle de qualidade. Isso é ótimo, mas os custos de licenciamento não permitem-nos para habilitá-lo para todos os desenvolvedores.

Todas as nossas aplicações apoiar uma API COM para execução de scripts, que regressão teste via VB, mas este testes da API sem a aplicação como tal.

Idealmente, eu estaria interessado em como as pessoas integrar cppunit e estruturas de teste unidade semelhante para o aplicativo em um nível desenvolvedor.

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