A maioria dos desenvolvedores que adicionaram recursos à plataforma edx estão familiarizados com MóduloStoreTestCase. Se seus testes exercitarem qualquer coisa relacionada ao conteúdo do curso (mesmo que seja apenas criar um curso vazio), a herança dessa classe garantirá que os dados sejam limpos adequadamente entre os testes individuais. Isso é extremamente valioso, mas também pode ser um desperdício em muitas situações. Durante o hackathon da semana passada, criei uma alternativa mais rápida chamado SharedModuleStoreTestCase.
Diferentemente dos MóduloStoreTestCase, SharedModuleStoreTestCase só faz Loja de módulos limpeza no tearDownClass() nível. Ele deve ser empregado em situações em que um ou um pequeno punhado de cursos pode ser inicializado antecipadamente e, em seguida, compartilhado de maneira somente leitura em muitos testes. Esse padrão de uso é comumente encontrado em testes LMS, que muitas vezes simplesmente recriam o mesmo curso repetidamente em seus configurar() métodos.
Impacto no desempenho
Para ter uma ideia do efeito que poderia ter, troquei alguns módulos de teste como parte do meu trabalho de hackathon. Esses são apenas números aproximados, pois são baseados em um número relativamente pequeno de execuções de teste do Jenkins. Dito isto, os resultados são promissores:
| Envie o | # Testes | Antes | Depois de | Delta |
| lms/djangoapps/ccx/tests/test_ccx_modulestore.py | 5 | 38s | 4s | -89% |
| lms/djangoapps/discussion_api/tests/test_api.py | 409 | 2m 45s | 51s | -69% |
| lms/djangoapps/teams/tests/test_views.py | 152 | 1m 17s | 33s | -57% |
Então, como você converte seus próprios testes?
Fazendo a troca
A maioria das classes que herdam de MóduloStoreTestCase comece algo assim:

Se você estiver modificando auto.curso em suas funções de teste individuais, então isso é perfeito, e você deve continuar a usar MóduloStoreTestCase. No entanto, se você estiver configurando o curso apenas uma vez e tratando-o como somente leitura em seus testes, agora você pode fazer isso:

É importante que as operações do Django ORM permaneçam em configurar(). Quaisquer modelos que você criar em setUpClass() deve ser excluído manualmente em seu tearDownClass() método — SharedModuleStoreTestCase não irá limpá-los adequadamente. Mesmo se você for cuidadoso, ainda poderá quebrar outros testes no sistema de maneiras imprevisíveis porque eles fazem suposições erradas sobre sequências e quais IDs serão criados quando configurarem seus dados. Isso pode ser extremamente tedioso para depurar.
Quando atualizarmos para o Django 1.8, você poderá usar setUpTestData() para fazer a inicialização em nível de classe de modelos Django com segurança com limpeza automática. Por favor, espere por essa atualização e coloque as manipulações de modelo em configurar() por enquanto, mesmo que seja um pouco mais lento.
Quais testes devo converter?
O lugar mais fácil para procurar alvos de otimização de teste é o Relatório de compilação de teste Jenkins. Clique em “Duração” para classificar por essa coluna.

Queremos principalmente focar em testes caros que criam dados de curso complexos (por exemplo, CCX) ou têm dados de curso simples, mas muitos, muitos testes (por exemplo, discussões). Criar até mesmo o curso mais simples leva cerca de 250-300ms ou mais, o que realmente aumenta ao usar ferramentas como ddt que efetivamente multiplicam o número de testes em uma classe.
Takeaway geral
O acesso ao banco de dados é uma parte cara da execução de testes, e o Loja de módulos é um excelente exemplo disso. eu espero que SharedModuleStoreTestCase pode ser uma ferramenta útil para reduzir os tempos de execução de teste. Mas, além disso, espero que entender por que funciona nos permita projetar conjuntos de testes mais rápidos em geral.
Dave Ormsbee é arquiteto sênior da edX. Este post foi publicado originalmente em seu blog, Castelo do Pântano.
![]()