Mocha: - opção de pedido para pedido de teste aleatório?

Criado em 18 jun. 2013  ·  66Comentários  ·  Fonte: mochajs/mocha

Uma opção --order permitiria às pessoas descobrir as dependências do pedido. As três opções seriam --order random , --order random:seed e --order default . Cada suíte randomizada produz a semente que usou.

RSpec implementa isso, mas sua ordem padrão é aleatória. Mocha não precisa fazer isso. Alguns detalhes sobre o parâmetro --order estão aqui: http://blog.davidchelimsky.net/2012/01/04/rspec-28-is-released/

O que você acha?

feature help wanted

Comentários muito úteis

Embora seja fácil to avoid cross-test dependencies without help of tooling , também é fácil adicionar tal dependência em um conjunto de testes sem perceber. Um bug no conjunto de testes geralmente se traduz em um bug em um sistema testado. Esses bugs são difíceis de rastrear, pois o código é supostamente coberto por testes.

O teste de ausência de dependências de teste cruzado é impossível sem ferramentas.

@visionmedia , por favor reconsidere.

Todos 66 comentários

meh, muito fácil evitar dependências de teste cruzado sem ajuda de ferramentas

Embora seja fácil to avoid cross-test dependencies without help of tooling , também é fácil adicionar tal dependência em um conjunto de testes sem perceber. Um bug no conjunto de testes geralmente se traduz em um bug em um sistema testado. Esses bugs são difíceis de rastrear, pois o código é supostamente coberto por testes.

O teste de ausência de dependências de teste cruzado é impossível sem ferramentas.

@visionmedia , por favor reconsidere.

+1 @yanovich. Eu usaria uma opção de ordem aleatória que gera um número de semente. Isso seria muito útil em um ambiente de CI.

@visionmedia , os modelos mongoose fornecem um exemplo fácil de dependências de teste cruzado. mongoose.model 'User', UserSchema adiciona um modelo ao array mongoose.models . Portanto, é possível criar um arquivo que depende do modelo do usuário que está sendo carregado em mongoose.models. Tome Comment.find().populate('_user').exec(cb) como exemplo. Se o teste do usuário for executado antes do teste do comentário, ele será executado corretamente, porque presumivelmente require('./models/user') (ou algo assim) carregou o modelo do usuário em mongoose.models. Mas se o teste de comentário for executado antes do teste do usuário, você obterá este erro Schema hasn't been registered for model "User" . Isso poderia acontecer na produção quando a API de comentário é executada antes da API do usuário e o arquivo de comentário não sabia que tinha uma dependência de arquivo cruzado.

É possível ainda ter o problema de produção com o teste funcionando se o arquivo de teste tiver require ('./ models / user') (ou qualquer outro) e que carregue o usuário em mongoose.models. No entanto, ter uma ordem aleatória seria mais uma ferramenta útil para descobrir problemas potenciais como este.

Espero que tenha sido bem articulado. Estou ansioso para ouvir seus pensamentos.

desculpe, eu acho que é um grande exagero, mocha é inchado o suficiente como está. Se houvesse muito mais interesse, talvez valesse a pena o encargo de manutenção.

Obrigado por pensar sobre isso.

Como a maioria das coisas em código, é fácil para quem sabe evitar fazer isso intencionalmente. É mais difícil evitar fazer isso sem querer. E se você não sabe que é um problema (ou seja, equipes de experiência mista), é muito provável que aconteça

Parece que algumas pessoas estão interessadas nele (e muitos acham que é uma das melhores características do miniteste). Se for mesclado, estou feliz em implementar.

1 interessado.

Seria bom ter! Descobri que meus testes falharam ao renomear nomes de arquivo, ugh.

+1 isso é importante

: +1:

: +1:

+1 Esta é uma deficiência muito grande.

A semântica do rspec é bastante sólida: você pode passar uma semente de pedido ou ele pode selecioná-la aleatoriamente. Se ele pegar a semente ao acaso, ele a imprime, então é fácil de reproduzir.

Geralmente não é tão fácil evitar dependências de teste cruzado. Às vezes devido a interações globais imprevistas, às vezes por conveniência. Suspeito que mais de 50% dos projetos que usam mocha veriam falhas de teste se o pedido fosse aleatório. Aqui estão alguns exemplos que parecem depender da ordem de execução do teste:

https://github.com/visionmedia/mocha/blob/master/test/hook.async.js#L95
https://github.com/visionmedia/superagent/blob/master/test/node/not-modified.js#L31

Esses dois estão listados como suítes de teste exemplares em http://visionmedia.github.io/mocha/ e eu não gastei muito tempo procurando por problemas.

Vou reabrir isso. Acho que seria útil. Embora existam maneiras de determinar as dependências do teste cruzado sem ferramentas, se pudermos automatizar isso, economizará tempo das pessoas.

Depois de brincar um pouco com isso, parece não trivial devido à natureza hierárquica das suítes. Os testes são executados recorrendo às suítes. Para executar _Testes_ aleatoriamente, teríamos que enumerá-los, randomizá-los e então trabalhar de trás para frente.

Isso faria com que before() e after() Hooks fossem algo sem sentido, pois seriam executados _n_ vezes por _n_ testes em um Suite (ou melhor, no _pior caso_, mas apenas se formos cuidadosos ), conforme mudamos continuamente os contextos. Parece que haverá uma penalidade de desempenho.

Usar sementes aleatórias e relatar sementes geradas automaticamente parece trivial; no entanto, os repórteres podem precisar saber sobre essas informações, de modo que isso requer implementação (ões) nos repórteres.

Claro, estou supondo que o que descrevi aqui é o que está sendo solicitado. Um recurso como esse precisa de uma especificação.

Outras opções incluem "randomize Suites" ou "randomize tests within Suites" ou alguma combinação dos dois. Praticamente falando, isso significa que uma vez que você está em um describe() bloco _A_, você não pode executar testes em qualquer pai ou irmão describe() bloco _B_ até que todos os testes em _A_ tenham sido executados (que parece ser uma implementação muito mais direta e não causará problemas com before() / after() ).

O que estou (e acho que os outros estão) pedindo é a mais simples das opções:

  • randomizar os testes no nível mais baixo: dentro de um único bloco de descrição; embaralhe as declarações "isso".
  • randomize a ordem dos suítes de nível superior (ou randomize a ordem dos arquivos que são carregados)

Não acho que haja muito valor em embaralhar as coisas nos níveis intermediários.

Certamente um hack, mas funciona para o nível mais baixo https://github.com/syrnick/mocha/compare/random_order?expand=1&w=0

mocha - fail
connect - pass
superagent - fail
express - pass** 
websocket.io - pass (can't tell for sure)

** Tive 2 falhas intermitentes em 100 execuções de todo o conjunto de testes de qualquer maneira.

OK, isso certamente é mais fácil de implementar!

Eu estava olhando para a biblioteca aleatória de sementes para isso; use a opção pass .

Aceitaria PR.

Provavelmente limparei esse código e ajustarei o conjunto de testes nos próximos dias. O sublinhado é uma dependência muito pesada para isso? Eu provavelmente poderia usar algo leve como este: http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript.

@boneskull Apoio sua decisão de reabrir isto. : +1:

Outras opções incluem "randomize Suites" ou "randomize tests within Suites" ou alguma combinação dos dois.

Parece mais do que bom para mim. Não há necessidade de repetir todo o caminho, enumerar e embaralhar.

Ótimo saber que isso está acontecendo.

Eu me pergunto se o rspec lidou com o embaralhamento recursivo? Pode valer a pena olhar
em seu código?

Na terça-feira, 26 de agosto de 2014, Joshua Appelman [email protected]
escrevi:

@boneskull https://github.com/boneskull Eu apoio sua decisão de
reabra isso. [imagem:: +1:]

Outras opções incluem "randomize Suites" ou "randomize testes dentro
Suites "ou alguma combinação dos dois.

Parece mais do que bom para mim. Não há necessidade de percorrer todo o caminho,
enumerar e embaralhar.

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/visionmedia/mocha/issues/902#issuecomment -53482124.

@syrnick Eu não gostaria de aceitar um PR com uma dependência tão grande e, em vez disso, usar seedrandom . Sem ele, não tenho certeza de como você apoiará a propagação. seedrandom permite que você especifique uma semente ou não, e se você não o fizer, ela retornará uma semente para você. Então, poderíamos exibi-lo para o usuário e permitir que ele especificasse, a la RSpec.

@syrnick Lembre-se de que se você gerar sementes, elas podem não ser "exibíveis" sem que sejam repassadas aos repórteres. Não estou muito familiarizado com a arquitetura de relatórios, então não posso te dizer com certeza ou o que fazer ...

+1

Eu não olhei para a implementação, mas +1 para a execução de teste ordenada aleatoriamente por padrão é super importante.

@syrnick Por favor, deixe-me saber se você pretende fazer isso, obrigado.

Estou feliz em fazer isso, mas não tenho um HEC imediato.

: +1 :, vocês ainda precisam de ajuda com um PR?

Na verdade, ninguém parece ter começado a trabalhar nisso.

Primeiro, parece que um shuffle Fisher-Yates faria o trabalho aqui.

Em segundo lugar, eu preferiria ter --order random , --order random-suites e --order default como os três argumentos, com um opcional :<seed> .

+1. Acabei de encontrar um bug que teria aparecido há muito tempo se os testes fossem randomizados. Semelhante ao modo como RSpec o suporta.

Aqui está um código que ilustra a utilidade da ordem de teste aleatório. Embora existam exemplos mais simples, este é um que acabei de encontrar durante uma demonstração de TDD. Se você inverter a ordem dos testes, o primeiro teste sempre falha.

game.js:

var express = require('express');
app = exports.app = express();

var sum = 0;

app.post('/bowl/:pins', function(req,res) {
    var score = parseInt(req.params.pins);
    console.log('Bowled ' + score);
    sum += parseInt(req.params.pins);
});

app.get('/score', function(req,res) {
    console.log('Sum: ' + sum);
    res.send(sum + '');
});

app.listen(process.env.PORT || 3000);

test \ gameTest.js:

var request = require('supertest'),
    should = require('should'),
    game = require('../game.js').app;

describe('a game of bowling', function() {
    describe('a gutter game', function() {
        it('should score 0', function(done){
            request(game).get('/score').expect(200, '0', done);
        });
    });

    describe('a single pin game', function() {
        it('should score 20', function(done){
            for(var i = 0; i < 20; i++) {
                request(game).post('/bowl/1').expect(200, done);
            }
            request(game).get('/score').expect(200, '20', done); 
        });
    });
});

Eu adoraria ter isso.

: +1:

Depois de envolver alguns globais (isso é Javascript, lembre-se), começar a eliminar chamadas de servidor e inserir / remover coisas do DOM em seus testes, é _muito_ fácil adicionar dependência de ordem. A randomização da ordem do teste ajudaria a descobri-los mais cedo ou mais tarde.
: +1:

: +1:

: +1:

+1

A ordem aleatória por padrão, com semente opcional para recriar a ordem, seria um ótimo recurso.

+1 para tê-lo, meus testes às vezes falham quando executados em ordem aleatória ...

Nesse meio tempo, unix para o resgate (infelizmente, semente aleatória não é suportada):

mocha `ls -1 test/*.js | sort --random-sort `

Estava pesquisando em que ordem o mocha executa os testes e encontrei isso. Na ausência de randomização, qual é a ordem de execução padrão? É sempre a ordem em que os testes aparecem fisicamente no arquivo?

: +1:

@danielabar sim, eles estarão na ordem em que aparecem no arquivo.

@NicolasJacob bem, a semente aleatória é realmente possível até certo ponto, aliás. :)

$ seq 10 | shuf --random-source=<(yes 2883)
1
7
3
4
6
2
10
5
9
8

https://github.com/bahmutov/rocha funciona para isso.

@boneskull embora este seja um problema antigo, o rótulo PR Please ainda é válido? Nesse caso, receberei alguma contribuição no dia seguinte ou depois.

Acho que na tentativa de eventualmente tentar manter o núcleo do mocha mínimo, a equipe pode hesitar em introduzir muitos novos recursos. O próximo grande lançamento do mocha tem como objetivo ter uma interface plugável.

Posso sugerir apenas usar https://github.com/bahmutov/rocha se funcionar?

Molho incrível

O que você quer dizer com interface plugável? Será possível introduzir um pedido de teste aleatório por meio desta interface?

+1 para a solicitação de recurso

@sulabhjain ,

Progresso neste ramo .

+1 para este recurso

Este é realmente um dos recursos mais críticos para uma estrutura de teste para ajudar a manter os testes independentes. Cada estrutura de teste JVM principal tem esse recurso básico.

1 para este recurso. Sim, é fácil evitar dependências de teste com experiência suficiente e / ou trabalhando sozinho, mas nem sempre é o caso.

Para os interessados ​​neste recurso, eles podem enviar PRs contra o ramo de randomização para ajudar a terminar o que resta.

1 para o recurso. Realmente aprecio que um ramo esteja em andamento para isso.

Ainda estou esperando por isso :))

Isso pode ser muito útil.
@tj Eu entendo que é fácil evitar dependências de teste quando você trabalha com pessoas com algumas habilidades básicas sobre testes, mas às vezes você precisa assumir uma equipe de desenvolvimento e pode esbarrar com pessoas que nem mesmo têm conhecimento básico sobre casos de teste.

Na verdade, isso também é útil quando você assume o controle de projetos existentes e deseja verificar facilmente se um teste está vinculado ao anterior.

@boneskull Bom trabalho! Qual é o status desta correção? Precisa de ajuda em alguma coisa?

Eu só queria compartilhar minha solução temporária que uso para executar testes de mocha em ordem aleatória. Talvez seja útil para alguém.

mocha $(find tests/ -name *.spec.js | shuf)

Infelizmente, isso não embaralha os exemplos de teste dentro do mesmo exemplo, mas ainda é muito inteligente e prático!

+1 em apoio a este recurso

Isso ainda está em cima da mesa, mas precisa da atenção de não-eu

Então, o que realmente resta aqui? Por onde posso começar?

Adoraria ver isso implementado ❤️

Acabei de encontrar o pacote choma , que fornece um plugin muito simples para o Mocha para randomizar a ordem dos casos e suítes de teste. Boa alternativa para rocha, que foi mencionada anteriormente. Simples e resolve o problema pra mim!

Uma alternativa seria executar testes em paralelo:

Esta página foi útil?
0 / 5 - 0 avaliações