Nunit: Execute métodos de teste em um dispositivo elétrico em paralelo

Criado em 5 ago. 2014  ·  76Comentários  ·  Fonte: nunit/nunit

Atualmente, implementamos apenas a execução paralela no nível de fixação. Deve ser possível executar métodos individuais de um dispositivo elétrico em paralelo, bem como casos de teste individuais para um método parametrizado.

Devemos ser capazes de especificar o nível exato de paralelismo no acessório ou método.

Este problema fazia parte do # 66

done hardfix feature high

Comentários muito úteis

Embora eu pudesse fingir que predizia o futuro, isso só o satisfaria até setembro. :-)

Deixe-me responder explicando como nós "programamos" os recursos.

No momento, estamos tentando (desde o início do ano) uma abordagem que tem lançamentos saindo uma vez por trimestre. À medida que melhoramos o lançamento, podemos aumentar o ritmo. Eventualmente, podemos fazer uma implantação contínua.

Em um projeto voluntário de código aberto, não há uma quantidade fixa de esforço disponível por mês. Podemos usar a abordagem do "clima de ontem", mas verifica-se que a quantidade de tempo que as pessoas passam no NUnit, bem como o número de pessoas que se oferecem como voluntárias, é bastante variável.

Como um meio-termo, selecionamos um pequeno número de problemas que são essenciais para um lançamento e os adicionamos ao marco antecipadamente. Minha preferência é adicionar não mais do que cerca de 25% do que esperamos realizar. A maioria dos problemas em uma versão só é adicionada a esse marco depois de concluídos ou, na melhor das hipóteses, quando alguém se compromete a trabalhar neles. Geralmente, você não encontrará problemas em aberto em nosso marco 3.5 sem alguém atribuído a eles, embora eu faça isso ocasionalmente se parecer que algo está bloqueando outro trabalho.

Portanto, o lado positivo do que fazemos é que podemos praticamente garantir que o lançamento será lançado no prazo. O lado negativo é que não podemos dizer o que estará nele. :-(

Para este problema em particular ... Eu dei alta prioridade para dizer aos nossos desenvolvedores que ele é importante. Alguém tem que ser livre para trabalhar nisso e ter experiência suficiente para um projeto desse escopo e dificuldade. Se alguém com o histórico certo perceber isso nas próximas semanas, acho que pode ser feito até o lançamento. Como diretriz, acho que levaria cerca de um mês, enquanto trabalhava em algumas outras coisas, para resolver isso.

Desculpe, não há resposta mais definitiva, mas tal resposta seria necessariamente uma mentira!

Todos 76 comentários

Atualização: este comentário e o seguinte foram em resposta a um indivíduo que aparentemente removeu seus próprios comentários. Estou deixando minhas respostas.

Bem, está nas especificações e programado para implementação pós-3.0. Se fosse tão fácil, provavelmente o teríamos feito. Não tenho certeza de qual conexão você vê com mbunit. O fato de eles terem não nos ajuda.

Isso está ficando um pouco cansativo. Alguns pontos, já declarados, mas aparentemente perdidos ...

  1. Existe um plano para implementar o que você está pedindo.
  2. Decidimos como uma equipe agendá-lo em um determinado momento.
  3. Quando é programado, tem a ver principalmente com nossa avaliação do valor do recurso em comparação com outros recursos.
  4. Existem várias pessoas na equipe NUnit que podem implementar o recurso.
  5. Eles seriam capazes de implementá-lo, dependendo das prioridades, de cabeça e não precisariam copiá-lo de qualquer lugar.

Acho sua conversa sobre "engenharia reversa" muito perturbadora. O código aberto só é possível em um contexto onde os direitos autorais são respeitados. Portanto, se você está sugerindo que podemos ignorar os termos de licenciamento mbunit, você está errado.

Embora eu tenha contribuído com muitos patches para MbUnit e o tenha usado por anos, eu estava
nunca um contribuidor importante. Eu não gostaria que meu status fosse deturpado :)

Quanto à engenharia reversa, não há realmente nenhuma utilidade aqui. NUnit funciona
totalmente diferente do MbUnit. Nós vamos resolver esse problema no devido tempo,
mas estão abordando isso com cautela porque outros problemas semelhantes podem mudar
a forma como precisamos implementar isso ou até mesmo o conflito.
Em 19 de abril de 2015, 2h45, "CharliePoole" [email protected] escreveu:

Isso está ficando um pouco cansativo. Alguns pontos, já afirmados, mas
aparentemente esquecido ...

1

Existe um plano para implementar o que você está pedindo.
2

Decidimos como uma equipe agendá-lo em um determinado momento.
3

Quando é programado tem a ver principalmente com nossa avaliação do
valor do recurso em comparação com outros recursos.
4

Existem várias pessoas na equipe NUnit que poderiam implementar o
recurso.
5

Eles seriam capazes de implementá-lo, dependendo das prioridades, a partir de
suas cabeças e não precisariam copiá-lo de nenhum lugar.

Acho sua conversa sobre "engenharia reversa" muito perturbadora. Código aberto é
só é possível em um contexto onde os direitos autorais são respeitados. Então se você é
sugerindo que podemos ignorar os termos de licenciamento mbunit, você está longe
base.

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/nunit/nunit/issues/164#issuecomment -94244650.

Um comentário muito mais delicado do que o meu!

Nossas prioridades atuais no mundo da execução paralela são:

  1. Execução de processo paralelo
  2. Grupos de exclusão
  3. Execução de método paralelo (em um dispositivo elétrico).

Isso parece representar a ordem de maior utilidade para os usuários.

Também mencionarei que marcar algo como pós-3.0 não significa necessariamente que o recurso será lançado em um momento posterior do que se o fizéssemos parte do 3.0. Em vez disso, pode significar que o 3.0 chega em um ponto anterior no tempo.

Quando fizermos isso, teremos que decidir como lidar com os comandos de configuração e desmontagem. A opção mais fácil provavelmente seria construir a classe de teste para cada teste de forma que não haja contenção de dados.

Eu preferiria tornar isso uma opção em algum momento, mas não tenho certeza se é uma opção de execução ou uma opção fixture-by-fixture (atribuída) ou ambas.

Oi!
A adição desse recurso à próxima versão do NUnit seria ótimo, pois é a única coisa que me impede de mudar para o NUnit. Este recurso ainda está planejado para o 3.4?

@julianhaslinger NUnit 3.4 sairá no final do mês, então não, esse recurso não será incluído.

Para sua informação, este problema está em nosso marco do Backlog (ou pseudo-marco) em vez de 3.4, porque estamos seguindo a prática de adicionar antecipadamente apenas um pequeno número de problemas de definição-chave a cada marco numerado.

O próximo marco, 3.6, está programado para cair em mais 3 meses, o que provavelmente soa desanimador para você. :-( No entanto, se você vir esse problema sendo mesclado ao mestre, poderá obter uma redução anterior de nosso feed MyGet.

@julianhaslinger isso não estará no 3.4, que provavelmente sairá em pouco mais de uma semana, mas é um que eu gostaria que fosse feito em breve, então seu voto ajuda: +1:

À parte, qual framework de teste você está usando que oferece suporte à execução de métodos paralelos? Eu pensei que o XUnit só permitia a execução de testes em paralelo até o nível de classe também. Estou enganado? Eu não uso muito o XUnit: smile:

@CharliePoole Obrigado pela resposta! Ok, isso soa um pouco desanimador, no entanto. No entanto, vou esperar pelos próximos lançamentos (ou lançamentos anteriores). Por favor (ainda) considere este recurso na próxima versão (3.6).

@rprouse Estou usando MbUnit / Gallio agora. O projeto praticamente morreu e agora vou mudar para o NUnit.

@julianhaslinger É uma questão de tempo de execução para você? Você tem alguns números sobre a distribuição de casos de teste dentro dos equipamentos? Eu pergunto porque minha suposição é que o recurso oferece pouco aos usuários além do que eles obtêm com acessórios paralelos. Se estiver errado, ele pode alterar sua prioridade relativa.

@CharliePoole Exatamente, nosso problema real é o tempo de execução dos casos de teste. Gostaríamos de usar o NUnit para nossos testes automatizados / de regressão (incluindo Selenium / WebDriver) e, uma vez que algumas de nossas classes de teste têm mais de 200 casos de teste, atualmente é muito difícil executar todo o conjunto de testes com o NUnit.

Comparações (dentro de um conjunto de teste menor de nossos testes de regressão) mostraram que uma possível solução NUnit será executada em cerca de 1,5 horas, enquanto a solução MBunit atual será executada em 0,5 horas (mesmo conjunto de teste).

No entanto, @CharliePoole , estou ciente do fato de que podemos reduzir o tempo de execução dividindo classes de teste maiores em menores, mas isso de alguma forma prejudicaria a ideia inicial de nossa hierarquia de classes de teste.

@julianhaslinger - Só para confirmar, você tem certeza de que o tempo de execução depende da CPU e não da memória?

Tivemos o mesmo problema quando tentamos mudar para o NUnit 3 pela primeira vez - o tempo de execução ficou significativamente mais longo. No entanto, isso ocorreu porque o NUnit atingiu o limite máximo da memória disponível - há um problema com a versão atual que se mantém em todos os objetos de teste até que a execução do teste seja concluída. No momento, estamos executando uma versão corrigida internamente - eu queria fazer um PR para o 3.4, mas não tenho certeza se terei tempo neste momento. :-(

Peço desculpas se não for isso, mas achei que valeria a pena mencionar, já que o Selenium pode usar seu quinhão de memória. :-)

@ChrisMaddock Obrigado pela contribuição! : +1: Vamos dar uma olhada nisso em breve e eu voltarei para você então.

@ChrisMaddock Eu adoraria ver sua correção de memória no 3.4. Se você deseja colocar um PR, podemos ajudá-lo a limpá-lo se ainda não estiver pronto para produção: +1:

@rprouse - Este commit inicial https://github.com/nunit/nunit/pull/1367/commits/5f98ae51025f7af8244abd4367d1f47260874dfc em PR # 1367 libera as coisas corretamente para nós, em uma v3.0.1 com patch.

Você verá no PR que ele foi movido para OneTimeTearDown antes da fusão - eu ainda não sei se essa mudança fez com que não funcionasse na v3.2.1, ou se havia outra mudança funcionando que reintroduziu o retenção - posso não ter testado novamente após a mudança.

Vou tentar testá-lo novamente e jogá-lo fora amanhã, seria ótimo para nós voltar aos lançamentos principais também. :-)

@ChrisMaddock Eu

apenas para acrescentar ao que @julianhaslinger disse, eu vi exatamente o mesmo problema ao usar NUnit com testes Selenium. Tive que escrever um wrapper personalizado que executa instâncias individuais de nunit-console.exe em um único teste, conforme extraído de um assembly aprovado, para que pudesse executar testes paralelos por enquanto. No entanto, isso não é ideal porque resulta na geração de muitos arquivos de saída .xml (um para cada execução de teste) em vez de uma única saída .xml e também significa que não posso usar os métodos _OneTimeSetUp_ e teardown e, em vez disso, devo confiar em semáforos externos e variáveis ​​de ambiente para controlar o fluxo de execução em que desejo executar as coisas apenas uma vez. Eu tenho seguido a promessa de ter execução paralela no NUnit por um longo tempo (anos) e fiquei muito desapontado com a forma como o recurso foi implementado no 3.0 (apenas parcialmente suportado e exigindo alguma escavação real nas questões e notas de lançamento para descobrir que nem tudo era realmente compatível). Eu mesmo fui mais longe a ponto de investigar o que estaria envolvido em avançar com isso, mas infelizmente parece que o design do NUnit está trabalhando contra a implementação da execução paralela no nível do método de teste, não tenho ideia de como você realmente gostaria para lidar com o potencial de código não threadsafe (ou seja, deve ser deixado para a pessoa que usa o NUnit em paralelo para garantir que todos os métodos de teste referenciem adequadamente quaisquer externos de uma maneira threadsafe ou o próprio NUnit deve lidar com a execução de cada método em seu próprio domínio enquanto de alguma forma tentando ainda executar os métodos do tipo configuração e desmontagem única apenas uma vez) e como eu já tenho uma solução alternativa no lugar, não poderia justificar o tempo de implementação desse recurso sozinho (o que é provavelmente o melhor porque já fui queimado antes, quando trabalhar com equipes no GitHub para ajudá-los a implementar a execução paralela). Enfim ... desculpe por divagar ... Eu entendo que a prioridade para Teste de Unidade de código C # provavelmente não depende tanto do paralelismo de nível de método, mas saiba que para aqueles de nós que usam NUnit para testes baseados em Selenium seria uma melhoria ENORME. Desde já, obrigado! :sorriso:

Obrigado por seus comentários. Acho que vou divagar um pouco sozinho aqui ...

Ajuda a entender o que as pessoas precisam e por que precisam. Não sendo um desenvolvedor web, tentei ouvir os usuários do Selenium e focar no que eles queriam. O que parecia ser acessórios paralelos com ordenação entre os casos de teste. Compreendo perfeitamente que pessoas diferentes desejam coisas diferentes, mas quando os dois grupos se apresentam como expressando "o que os usuários do Selenium precisam", fica um pouco confuso. Você pode descrever para mim quais tipos de testes da web podem desejar o paralelismo no nível do método, em oposição àquelas pessoas que desejam executar métodos em uma ordem predefinida? Acho que posso adivinhar, mas prefiro receber de um usuário.

Com relação à sua solução alternativa ... você considerou usar assemblies de teste separados? NUnit ficaria feliz em executar cada um em paralelo em um processo separado. Claro que isso não elimina a necessidade de sincronizar o acesso a coisas como arquivos.

Com relação à segurança de thread - nunca planejamos nossa implementação paralela para assumir a responsabilidade pela segurança de thread. A única coisa que eu esperava garantir é que o NUnit não criará nenhum problema de segurança de thread se seus métodos já forem seguros para thread. Isso por si só não é trivial.

Obrigado pela resposta. Eu entendo completamente seus comentários sobre
ordenação da execução do teste em um dispositivo elétrico e divisão dos testes em
assembléias.

Já sou um usuário NUnit há anos (e JUnit antes disso)
então a ideia de confiar na solicitação de testes em um dispositivo elétrico não era nem mesmo um
consideração em meu design de teste. Cada teste tenta ser um totalmente encapsulado
ação ou conjunto de ações dentro do site sem expectativa na ordem de
execução. O design do site que estou testando também significa que muitos testes
pode levar até 20 minutos para ser executado (muito desse tempo é gasto em espera
para que algo aconteça no site) e o tipo de teste está cobrindo
vários cenários semelhantes para que as classes de teste de base sejam utilizadas para reduzir o código
duplicação e aumento da capacidade de manutenção por meio do uso de classe base comum
métodos. Os testes são organizados em projetos separados com base no dev
propriedade da equipe dessa área (então usamos montagens separadas, mas lá
são muitos testes por montagem e meu wrapper de teste irá lidar com a execução de
todos os testes em todos passaram em assemblies em paralelo, uma vez que foi criado antes
o primeiro lançamento oficial do NUnit 3 e eu queria garantir que todos os testes
o potencial para ser executado simultaneamente com threads suficientes
acessível).

Essencialmente, você pode imaginar que um conjunto pode ter 10 testes e
outros 100 testes, mas a montagem com 10 tem testes que levam 10 minutos
cada um, enquanto a montagem com 100 tem testes que levam 1 minuto cada. Se eu
tem uma máquina capaz de executar 110 threads paralelos (que é na verdade
parte do nosso design de infraestrutura), então eu esperaria que os testes terminassem
em 10 minutos, não em 100 minutos.

Espero que isso ajude a explicar ... desculpe se as coisas ainda não estão totalmente claras,
mas o ponto geral é que o paralelismo de nível de método é algo que eu
visto em falta em outras bibliotecas de teste (prspec em ruby, por exemplo) e quando
fazendo análise das melhorias de desempenho a serem obtidas, adicionando-o i
descobriu que pode ser uma grande mudança positiva. Veja o seguinte como exemplo:
https://github.com/bicarbon8/rspec-parallel/wiki/Examples
Em 1 de julho de 2016, 00:45, "CharliePoole" [email protected] escreveu:

Obrigado por seus comentários. Acho que vou divagar um pouco sozinho aqui ...

Ajuda a entender o que as pessoas precisam e por que precisam. Não ser um
desenvolvedor web, tentei ouvir os usuários do Selenium e focar no que
eles queriam. O que parecia ser acessórios paralelos com o pedido
entre os casos de teste. Eu entendo perfeitamente que pessoas diferentes vão querer
coisas diferentes, mas quando ambos os grupos se apresentam como expressando
"o que os usuários do Selenium precisam" é um pouco confuso. Você pode delinear para mim
que tipos de testes da web podem querer paralelismo em nível de método ao invés de
aquelas pessoas que desejam executar métodos em uma ordem predefinida? Acho que poderia
acho, mas prefiro receber de um usuário.

Em relação à sua solução alternativa ... você considerou usar um teste separado
assembleias? NUnit ficaria feliz em executar cada um em paralelo em um separado
processo. Claro que isso não elimina a necessidade de sincronizar o acesso a
coisas como arquivos.

Com relação à segurança de thread - nunca planejamos nossa implementação paralela
para assumir a responsabilidade pela segurança do segmento. A única coisa que eu esperava
garantia é que o NUnit não _criará_ quaisquer problemas de thread-safety se o seu
métodos já são thread-safe. Isso por si só não é trivial.

-
Você está recebendo isto porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/nunit/nunit/issues/164#issuecomment -229819324 ou mudo
o segmento
https://github.com/notifications/unsubscribe/ACNsyoczCUV9L7kbF2SHB7lLsyBKlrv9ks5qRFUJgaJpZM4CUZ8r
.

Obrigado pela informação ... é útil ver uma variedade de perspectivas.

Meus 5 centavos.

Em nosso projeto, temos aproximadamente 25 montagens de teste e a execução de teste paralela de testes por montagem e por fixação já reduz bastante o tempo de execução. A execução paralela de testes dentro do aparelho irá melhorá-lo ainda mais. Agora até dividimos os aparelhos que consomem muito tempo em vários aparelhos para acelerar a execução, mas será muito melhor se o nunit executar testes de aparelhos em paralelo.

O que eu realmente quero ver no nunit é uma paralelização de teste no nível de caso de teste, porque dividir esses testes em acessórios nem sempre é conveniente e leva à duplicação de código. Temos vários testes que podem levar vários milhares de casos de teste (cada execução de caso é rápida, mas no total leva minutos) ou apenas dezenas de casos (mas cada caso é lento) e, por enquanto, tais testes são os principais obstáculos para nós.

Obrigado pela contribuição ... é uma área que iremos abordar no próximo lançamento, juntamente com a questão concorrente, mas complementar, de garantir que alguns testes não sejam executados em paralelo um com o outro!

Minha pergunta anterior era mais sobre como as pessoas estão escrevendo testes, especialmente ao dirigir um aplicativo da web. Algumas pessoas insistem que querem que cada método seja uma etapa sequenciada e o acessório para representar uma série dessas etapas. É claro que isso não é paralelo por definição. Outras pessoas parecem escrever testes muito semelhantes sem sequenciá-los. Meu palpite é que o último grupo escreve métodos de teste maiores, com uma série de ações e afirmações em cada um.

@CharliePoole Boas notícias! Muito obrigado!

Na minha opinião os casos de teste devem ser isolados e não depender de outros casos de teste ou da ordem de execução. Se as pessoas ainda quiserem executar alguns testes de thread único, ainda poderão usar [Parallelizable (ParallelScope.None)] e / ou OrderAttribute.

Este problema que está sendo implementado permitirá a execução de suítes de teste mais rapidamente em comparação com uma grade de webdriver local ou um provedor Saas, como BrowserStack ou SauceLabs. Atualmente, tento limitar a quantidade de métodos de teste em uma classe de teste ao número de nós do webdriver ou sessões do navegador disponíveis, para que a grade seja totalmente utilizada. Caso contrário, se um teste tiver 8 métodos de teste e minha grade tiver 8 sessões de navegador disponíveis, apenas uma será usada porque todos os métodos de teste da classe serão executados um de cada vez.

@pablomxnl Concordo absolutamente. Como coach ou líder de projeto, sempre forcei muito essa ideia. No entanto, não estou usando nenhum desses chapéus aqui. Sou um provedor de software com usuários que pedem coisas. Se eles pedem coisas realmente chocantes, eu simplesmente digo não. Mas se eles pedem coisas que são razoáveis ​​em algum contexto, mas não em outros - nem mesmo na maioria - eu levo isso em consideração.

No caso de sites, quase sempre não estamos falando de testes de unidade. Testes funcionais de nível superior geralmente requerem sequenciamento. Se isso é feito por meio de um conjunto de etapas no teste ou de uma série de métodos, é um detalhe de implementação para nós e uma questão de conveniência para o usuário. Pessoalmente, acho que provavelmente precisamos de algo chamado [Step] que fica dentro de uma classe [StepFixture], ou alguns nomes semelhantes, para que possamos remover todas essas coisas de ordenação / sequenciamento do teste de unidade. Talvez eu tenha tempo para fazer isso antes que a web morra. :-)

De qualquer forma, é sempre interessante aprender como as pessoas realmente usam seu software.

@CharliePoole , por favor, não me entenda mal perguntando isto (só quero ter certeza): Esse recurso será adicionado à próxima versão (3.5, com vencimento em 29 de setembro de 2016)?

Embora eu pudesse fingir que predizia o futuro, isso só o satisfaria até setembro. :-)

Deixe-me responder explicando como nós "programamos" os recursos.

No momento, estamos tentando (desde o início do ano) uma abordagem que tem lançamentos saindo uma vez por trimestre. À medida que melhoramos o lançamento, podemos aumentar o ritmo. Eventualmente, podemos fazer uma implantação contínua.

Em um projeto voluntário de código aberto, não há uma quantidade fixa de esforço disponível por mês. Podemos usar a abordagem do "clima de ontem", mas verifica-se que a quantidade de tempo que as pessoas passam no NUnit, bem como o número de pessoas que se oferecem como voluntárias, é bastante variável.

Como um meio-termo, selecionamos um pequeno número de problemas que são essenciais para um lançamento e os adicionamos ao marco antecipadamente. Minha preferência é adicionar não mais do que cerca de 25% do que esperamos realizar. A maioria dos problemas em uma versão só é adicionada a esse marco depois de concluídos ou, na melhor das hipóteses, quando alguém se compromete a trabalhar neles. Geralmente, você não encontrará problemas em aberto em nosso marco 3.5 sem alguém atribuído a eles, embora eu faça isso ocasionalmente se parecer que algo está bloqueando outro trabalho.

Portanto, o lado positivo do que fazemos é que podemos praticamente garantir que o lançamento será lançado no prazo. O lado negativo é que não podemos dizer o que estará nele. :-(

Para este problema em particular ... Eu dei alta prioridade para dizer aos nossos desenvolvedores que ele é importante. Alguém tem que ser livre para trabalhar nisso e ter experiência suficiente para um projeto desse escopo e dificuldade. Se alguém com o histórico certo perceber isso nas próximas semanas, acho que pode ser feito até o lançamento. Como diretriz, acho que levaria cerca de um mês, enquanto trabalhava em algumas outras coisas, para resolver isso.

Desculpe, não há resposta mais definitiva, mas tal resposta seria necessariamente uma mentira!

@CharliePoole existe alguma atualização considerando este recurso?

@tomersss , não começamos a trabalhar nisso ainda e o 3.5 esperamos ser lançado em algumas semanas, então é improvável que seja no próximo lançamento. Gostaríamos de ver esse recurso adicionado em breve, mas estivemos bastante ocupados esta semana reorganizando nossos repositórios e base de código. Porém, está marcado como alta prioridade, por isso está em nosso radar.

@CharliePoole há alguma atualização para esse problema?

@KPKA , ainda não começamos a trabalhar nisso, então não há atualizações. Para usuários com ZenHub instalado, você verá este problema passar de Backlog para ToDo e em Anding conforme começamos a trabalhar nele.

Para não usuários do Zenhub, você poderá saber quando alguém o identificar, observando quem está responsável pelo problema.

@CharliePoole @rprouse

Oi!

Alguma notícia de acordo com este assunto?
Se será no próximo lançamento ou se está planejado em um dos próximos marcos?

De momento, este é o único problema que nos impede de mudar para o NUnit.
Seria gentil se alguém pudesse confessar que vai trabalhar nisso em um futuro próximo, já que há muitas pessoas afetadas, eu acho.

Espero ouvir respostas suas logo

@GitSIPA qual framework de teste você está usando que permite executar métodos de teste em paralelo?

Para responder à sua pergunta, ninguém começou a trabalhar nessa questão, então não há ETA, mas levaremos seu voto em consideração enquanto estivermos decidindo o que trabalharemos a seguir.

+1, concordo com @GitSIPA. Esta é uma funcionalidade realmente importante

@GitSIPA +1
@rprouse Estamos usando mbunit, mas este framework não é compatível agora. E temos alguns problemas com mbunit.

@rprouse Também estamos usando MbUnit no momento, mas como o suporte não é fornecido para as novas versões do Visual Studio, consideramos mudar para NUnit.

Na edição # 1921 @ jnm2 perguntou "O que nos

Segunda pergunta primeiro: Com certeza! Adoraríamos sua ajuda.

E para a primeira pergunta:

  1. Executamos "WorkItems", que atualmente mapeiam um a um para testes. Acho que precisamos tratar OneTimeSetUp e OneTimeTearDown para um acessório como WorkItems separados como uma etapa preliminar. A edição # 1096 trata disso.

  2. Precisamos ter uma maneira de fazer um WorkItem depender de outros WorkItems, de forma que ele só seja agendado para ser executado quando todos aqueles que dependem de itens estiverem completos. Atualmente fazemos isso de uma forma muito simplista usando um CountDown, mas precisamos de algo mais geral. O primeiro uso disso, é claro, seria fazer OneTimeTearDown depender da conclusão de todos os testes. Ele teria outros usos posteriormente, quando implementarmos a dependência entre os testes. Eu imagino isso como uma fila de itens de trabalho pendentes, mas pode haver outras maneiras de implementá-lo.

  3. Com essas duas coisas resolvidas, poderíamos começar a trabalhar no próprio problema principal: agendar testes para serem executados em vez de executá-los no mesmo thread que fez o OneTimeSetUp para o fixture.

Se você gostaria de trabalhar nisso, você terá que se familiarizar com alguns dos aspectos internos de como o NUnit realmente despacha os testes para execução. Ficarei feliz em ajudá-lo a fazer isso.

Qual planejamento foi feito até agora?
Minhas necessidades são executar casos TestCaseSource suficientes em paralelo para saturar a CPU. Não tenho requisitos de configuração, desmontagem ou pedido. Outras pessoas precisarão que isso seja levado em consideração.

Eu esperaria que a execução de TestCaseSource fosse paralelizada, então dois métodos no mesmo dispositivo que usavam TestCaseSources diferentes executariam as enumerações em paralelo. Também parece que seria bom se dois métodos usassem o mesmo TestCaseSource se ele fosse executado apenas uma vez - pensamentos sobre isso?

Edit: comentando CONDIÇÃO DE CORRIDA. Já começamos bem! 😆

Vou repetir uma história que tenho tido que contar muito ultimamente. :sorriso:

O NUnit primeiro carrega os testes (também conhecido como descobre, explora) e, em seguida, os executa uma ou mais vezes, dependendo do tipo de corredor.

Seu TestCaseSource é usado para carregar testes, não para executá-los, e nós nem mesmo o consideramos como parte do seu teste - embora você possa tê-lo na mesma classe do seu teste.

IOW, seus casos de teste não "usam" sua fonte de caso de teste, em vez disso, o NUnit usa a fonte para criar os casos de teste. Claro, eles não podem fazer nada até serem criados. Faz sentido?

Na verdade, a criação dos testes a partir da fonte é feita de forma sequencial. Se você tiver algum código sendo executado na fonte que torne isso um problema, meu primeiro palpite seria que você está fazendo muito na fonte do caso de teste. Por exemplo, você não deseja criar instâncias de classes em sua fonte de caso de teste, em vez disso, deseja armazenar parâmetros que serão usados ​​para criá-los. Infelizmente, este pode ser um capítulo inteiro de um livro. :sorriso:

Portanto, esse problema trata de __running__ casos de teste em paralelo. Isso significa todos os casos de teste em um dispositivo elétrico, a menos que você tenha marcado alguns como não passíveis de paralelizabilidade. Testes simples e não parametrizados, bem como casos individuais de um teste parametrizado, seriam tratados igualmente neste caso.

Seria uma experiência interessante permitir a paralelização de testes em aparelhos onde não há OneTimeTearDown (acho que OneTimeSetUp está OK). Poderia funcionar facilmente se você pudesse fazer essa determinação corretamente. A determinação é mais difícil do que você pensa, no entanto, porque OneTimeTearDown pode incluir métodos herdados e ActionAttributes globais.

@ jnm2 Já teve a oportunidade de resolver este problema específico?

@julianhaslinger Não. Está na minha lista depois de meus dois problemas mais imediatos, 1885 e 1933. Se você quiser resolver isso, tanto melhor!

@julianhaslinger Já que não nos conhecemos, desculpe-me por dizer que essa é uma pergunta difícil de enfrentar. Certifique-se de examinar como as coisas estão sendo feitas agora e por quê - o último nem sempre é óbvio, temo. Veja meu comentário em https://github.com/nunit/nunit/issues/164#issuecomment -265267804 para uma divisão em PRs separados que eu gostaria de ver para consertar isso. Se você vier com uma abordagem mais simples, poste sobre isso antes de codificá-la, para que possamos comparar as considerações futuras com o YAGNI óbvio envolvido na previsão do futuro.

@CharliePoole @ jnm2 Oi pessoal!

Não é que eu quisesse começar a implementar esse recurso ausente, mas apenas saber sobre seu progresso. Como posso dizer por suas respostas (acima), não houve nenhum progresso (?) Em relação a essa solicitação de recurso específico.

@CharliePoole Um dos problemas potenciais que encontrei ao pesquisar o código foi como as luminárias são tratadas agora. Atualmente todos os WorkItems têm acesso à mesma instância de Fixture , o que significa que se os WorkItems fossem executados em paralelo, eles estariam acessando uma única instância da classe de teste. Isso é problemático por causa das condições de corrida que ele cria quando os testes contam com Setup ou Teardown para definir campos de nível de instância.

Uma solução para isso seria fazer com que cada WorkItem opere em uma nova instância da classe de teste, mas isso provavelmente complicará como as configurações do aparelho se comportam, uma vez que não haveria mais uma única instância do aparelho

@ chris-smith-zocdoc Sim, essa é a maior diferença entre o NUnit e seu antecessor junit. Antigamente, era amplamente discutido prós e contras, mas não é muito discutido agora. Por esse motivo, os testes NUnit deveriam ser stateless, com toda a inicialização realizada no método SetUp.

Depois que TestFixtureSetUp (agora chamado OneTimeSetUp) foi introduzido, tornou-se possível fazer uma inicialização mais cara uma vez e ter todos os testes operando nos mesmos valores inicializados. Isso é mais útil ao criar instâncias das classes que estão sendo testadas, que podem ter estado. Nos últimos anos, cada vez mais usuários têm aproveitado esse recurso.

O assunto de adicionar uma opção para criar uma instância separada do acessório do usuário por caso de teste surge periodicamente. Até agora, não chegou ao estágio de ser um recurso planejado. Está definitivamente relacionado à usabilidade de um recurso de método paralelo por parte dos usuários, mas acho que é ortogonal à implementação. SE estivéssemos criando um novo equipamento por instância, simplesmente executaríamos a configuração "única" mais de uma vez. Claro, isso afetaria fortemente qualquer usuário que esteja fazendo uso da estática. 😢

Adiamos os métodos de teste paralelos por dois motivos: (1) é difícil de implementar e (2) parecia que os acessórios paralelos, embora mais fáceis para nós, são suficientes para a maioria dos usuários. Muito poucos usuários parecem compartilhar o estado entre vários aparelhos, embora pareça (com base em discussões online) muitos usuários compartilham o estado entre os métodos de teste. Até agora, muitos usuários estão aproveitando o paralelismo existente e, embora alguns desejem muito o paralelismo de métodos, eles parecem ser um grupo relativamente pequeno.

Mesmo assim, acho que é hora de fazer algo. Vou fazer isso no primeiro trimestre, pelo menos até o ponto de executar alguns experimentos e possivelmente chegar a uma divisão sensata de tarefas que outros possam acompanhar.

SE estivéssemos criando um novo equipamento por instância, simplesmente executaríamos a configuração "única" mais de uma vez. Claro, isso afetaria fortemente qualquer usuário que esteja fazendo uso da estática.

Eu acho que é razoável exigir que não haja estado estático se você optar por rodar em paralelo, na medida em que é sua culpa se algo quebrar por misturar estado estático e paralelismo. Felizmente, todo o seu código estará em teste, por isso deve ser difícil de ignorar 😆

Mesmo assim, acho que é hora de fazer algo. Vou fazer isso no primeiro trimestre, pelo menos até o ponto de executar alguns experimentos e possivelmente chegar a uma divisão sensata de tarefas que outros possam acompanhar.

Conte comigo para isso.

Eu também!

No sábado, 14 de janeiro de 2017 às 03h58, Joseph Musser [email protected]
escreveu:

>
>
>
>

[image: Boxbe] https://www.boxbe.com/overview

Limpeza automática: mantenha os últimos 1 e-mails (notificaçõ[email protected])

Editar regra
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Dwa43L7bW5j4V5ymh5QXh%252FNXk%252F0KVSSFJSqwHw2yu4No%253D%26token%3DjkWoQ96YyOE%252FHA7PvZA8g%252FOAgpOQMZdIE7ophiWCxqx1y6zZCFJ%252FKSZ2WZELsWD3YQoDEdjwb%252BWo6wGi4xiUEkGngbggedv8iYBxU7zk% 252FJamyOuVtPzie4dhQJXQkQQ% 252BtolspNKBzqBxtH6H% 252FhqnTQ% 253D% 253D & tc_serial = 28420100882 & tc_rand = 128339648 & utm_source = stf & utcontentium & UACMEDI = e-mail & utcontent1 ANUTA_TANTO = e-mail_ utcamED1 = 00_ utcontent & utcontent = ANTMEDI_TANTI = e-utcMEDLE = 00_ utcontent = ANITANITANITent = e-UTCMED1 = e-UTCMEDI = 00_ utcontent & utcont = ANITANITLE = e-mail & utmEDITANITENT1 = e-utm_MEDI = 00CNTANIT = e-UTCAMED1 = e-UTMEDI = 00cont.

| Excluir regra
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Dwa43L7bW5j4V5ymh5QXh%252FNXk%252F0KVSSFJSqwHw2yu4No%253D%26token%3DjkWoQ96YyOE%252FHA7PvZA8g%252FOAgpOQMZdIE7ophiWCxqx1y6zZCFJ%252FKSZ2WZELsWD3YQoDEdjwb%252BWo6wGi4xiUEkGngbggedv8iYBxU7zk% 252FJamyOuVtPzie4dhQJXQkQQ% 252BtolspNKBzqBxtH6H% 252FhqnTQ% 253D% 253D & tc_serial = 28420100882 & tc_rand = 128339648 & utm_source = stf & utcontentium & UACMEDI = e-mail & utcontent1 ANUTA_TANTO = e-mail_ utcamED1 = 00_ utcontent & utcontent = ANTMEDI_TANTI = e-utcMEDLE = 00_ utcontent = ANITANITANITent = e-UTCMED1 = e-UTCMEDI = 00_ utcontent & utcont = ANITANITLE = e-mail & utmEDITANITENT1 = e-utm_MEDI = 00CNTANIT = e-UTCAMED1 = e-UTMEDI = 00cont.

| Marcar importante
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Dwa43L7bW5j4V5ymh5QXh%252FNXk%252F0KVSSFJSqwHw2yu4No%253D%26token%3DjkWoQ96YyOE%252FHA7PvZA8g%252FOAgpOQMZdIE7ophiWCxqx1y6zZCFJ%252FKSZ2WZELsWD3YQoDEdjwb%252BWo6wGi4xiUEkGngbggedv8iYBxU7zk% 252FJamyOuVtPzie4dhQJXQkQQ% 252BtolspNKBzqBxtH6H% 252FhqnTQ% 253D% 253D% 26important% 3Dtrue% 26emlId% 3D54854949581 & tc_serial_util_util_util_utilizador_util_ & tcienta = 28420100882 & tc_serial = 28420100882 & tc_serial_ utcontNo = & utcont / e-mail & tcn / TANTA2 & tcn / c / e-mail_ utcont / e-mail_a096 & tcn / a_ utcont / e-mail_a_tient_a_tc = e-utcn / a = & tcn / c / e-mail_ utcient_a_t;

SE estivéssemos criando um novo acessório por instância, simplesmente executaríamos "um"
configuração de tempo mais de uma vez. Claro, isso afetaria fortemente qualquer usuário que seja
fazendo uso de estática.

Acho que é razoável exigir que não haja estado estático se você
opte por correr em paralelo, na medida em que é sua culpa se algo
quebras para misturar estado estático e paralelismo. Felizmente, todo esse código vai
estar em teste, então deve ser difícil de perder: D

Mesmo assim, acho que é hora de fazer algo. Eu vou assumir isso
para o primeiro trimestre, pelo menos a ponto de realizar alguns experimentos
e possivelmente chegar a uma divisão sensata de tarefas que outros podem
acompanhar.

Conte comigo para isso.

-
Você está recebendo isto porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/nunit/nunit/issues/164#issuecomment-272488655 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAHNVlwVps8pQ93UIwZw6zY7TOyHO0a6ks5rR61EgaJpZM4CUZ8r
.

Executando alguns testes de tempo, descobri algo interessante. Há uma ambigüidade em chamar os casos de teste de paralelizáveis. Isso também pode se aplicar a luminárias e outras suítes, mas é menos óbvio.

Aqui está o problema: se um método é completamente não paralelizável, isso significa que ele não pode ser executado em paralelo com __qualquer outro método__. OTOH, se for não paralelizável dentro de seu aparelho, então ele não pode ser executado em paralelo com __qualquer outro método no mesmo aparelho .__

Proponho que tratemos esta distinção da seguinte forma:

  1. Se um método de teste não tem nenhum atributo Parallelizable, ele deve rodar no mesmo thread que o fixture que o contém, desde que nenhum outro atributo (por exemplo, Apartment) o chame para ser executado em um thread diferente

  2. Se ele tiver um atributo Parallelizable com um escopo Self, ou se uma suíte de nível superior especificar um escopo Children, então o método de teste é executado em paralelo com os outros métodos no aparelho.

Pensamentos @ nunit / core-team?

Deixado de fora acima:

  1. Se ele tiver um atributo Parallelizable com um escopo None, ele será executado na fila não paralela.

@CharliePoole - seus três pontos fazem sentido, embora eu não esteja certo sobre qual seria a alternativa que você está sugerindo que não fazemos. Você poderia esclarecer?

Atualmente tratamos não ter um atributo da mesma forma que ter um com ParallelScope.None. Isso os coloca na fila não paralela se eu habilitar o envio deles e a execução do teste diminuir significativamente.

PR # 2011 dá alguns passos iniciais para a implementação desse recurso, mas contém um #define que força os casos de teste a serem executados no encadeamento de seu dispositivo de fixação. Este comentário documenta o que acho que precisa ser feito para remover essa limitação.

Atualmente, o OneTimeTearDown de um fixture é executado no thread que foi usado para terminar o último caso de teste executado. Se os casos de teste forem executados em paralelo, não podemos prever qual caso de teste será. Pode ser uma rosca com características diferentes das exigidas para o acessório. Por exemplo, se o último teste a ser finalizado estiver rodando no STA, é isso que será usado para rodar o OneTimeTearDown, mesmo que o OneTimeSetUp tenha rodado em um MTA. Em muitos casos, isso pode não causar nenhum problema, mas em alguns pode.

Na verdade, isso também pode ser um problema com acessórios de nível superior, mas a introdução de casos de teste paralelos significa que haverá muito mais oportunidades para uma incompatibilidade que causa um erro.

Portanto, para garantir que a desmontagem do dispositivo de fixação ocorra no tipo certo de thread, não podemos mais executá-lo no thread do último teste a ser executado. Em vez disso, o despachante precisará manter as informações sobre todas as desmontagens pendentes e ser notificado para executá-las no encadeamento adequado no momento adequado. Descobrir como fazer isso é a fase de "design" desse recurso.

para quem está seguindo este tópico desde o início (em 2014) e não quer ou é incapaz de implementar sua própria solução alternativa enquanto aguarda a adição deste recurso, acabei de encontrar uma implementação usando o NUnit 2.6.3 disponível em CodePlex que parece bastante simples de usar (eu verifiquei que funciona na execução de nossos testes funcionais em vários threads paralelos).

http://cpntr.codeplex.com/

desculpas antecipadamente @CharliePoole se esta mensagem for um pouco ortogonal às discussões recentes neste tópico, mas se alguém mais esteve esperando nos últimos 3 anos por esta adição de recurso com base nas promessas estabelecidas para NUnit 3 (bem no início dias), acho que pode oferecer uma solução até que vocês consigam resolver os problemas de design (parece que vocês estão se aproximando da solução).

@CharliePoole

Portanto, para garantir que a desmontagem do dispositivo de fixação ocorra no tipo certo de thread, não podemos mais executá-lo no thread do último teste a ser executado. Em vez disso, o despachante precisará manter as informações sobre todas as desmontagens pendentes e ser notificado para executá-las no encadeamento adequado no momento adequado. Descobrir como fazer isso é a fase de "design" desse recurso.

Precisamos que o despachante saiba antecipadamente sobre os itens de desmontagem pendentes ou podemos despachá-los assim que estiverem disponíveis? Mais concretamente, onde CompositeWorkItem atualmente chama PerformOneTimeTearDown, podemos usar o despachante para despachar uma nova unidade de trabalho para o turno de trabalho correto?

@ chris-smith-zocdoc Sim, é exatamente o que estou fazendo. Eu criei um novo tipo de item de trabalho, OneTimeTearDownWorkItem , que está aninhado em CompositeWorkItem e é despachado quando o último teste filho é executado. Mais tarde, podemos observar algumas eficiências quando o OneTimeSetUp e todos os testes foram executados no mesmo encadeamento.

Não li tudo com muito cuidado, mas uma coisa que gostaria de solicitar como parte desse recurso é que o paralelismo seja "inteligente", especialmente para testes de limite de E / S. Por exemplo, se você tiver 10 threads executando 100 testes paralelizáveis, não deve ser o caso de os 10 threads ficarem parados e esperar que os primeiros 10 testes sejam concluídos antes de passar para os próximos 10 testes. Se os primeiros 10 testes começarem a aguardar tarefas de E / S de longa duração, os threads devem estar livres para passar para outros testes. Quando as tarefas de E / S forem concluídas, os threads retomarão os testes em espera à medida que os threads forem liberados.

Basicamente, estou pedindo um gerenciamento de taxa de transferência inteligente para testes de limites de E / S que fazem uso extensivo de async / await. Este é, de longe, nosso gargalo número um em testes.

@ chris-smith-zocdoc Na verdade, é exatamente isso que estou fazendo. Estou usando essencialmente o mecanismo de contagem regressiva existente para acionar o envio de uma tarefa de desmontagem única. O truque é enviá-lo para a fila adequada.

@gzak Tenha em mente que o mecanismo para execução paralela já existe. Depende de trabalhadores puxando tarefas de forma independente, em vez de ter um controlador que envia tarefas para os trabalhadores. Portanto, se um trabalhador estiver ocupado com uma tarefa por um tempo, os outros continuarão a executar outras tarefas independentemente. O truque é definir o número de trabalhadores com base na natureza dos testes que estão sendo executados. O NUnit se sai razoavelmente bem por padrão com testes de unidade normais vinculados ao computador, mas outros tipos de testes podem exigir que o usuário defina um nível apropriado de paralelismo.

Alguém pode me explicar como funciona?
Eu tenho uma aula de teste
Quando eu executo os testes desta classe NÃO em paralelo - todos os testes foram aprovados
Mas quando eu os executo com [Parallelizable (ParallelScope.Children)]
Portanto, eles são executados em paralelo (vários métodos na mesma classe)
mas por algum motivo alguns testes estão falhando.
Eu tenho campos de instância nesta classe que são usados ​​nos testes e parece que esses campos são compartilhados entre threads
Estou certo?
Você cria apenas 1 instância dessa classe e chama os métodos simultaneamente neste único objeto?
CharliePoole

Você descobriu! Sim, todos os testes em um aparelho usam a mesma instância. Isso é histórico com o NUnit, que sempre funcionou dessa forma. Você deve escolher entre executar os casos de teste em paralelo e ter qualquer estado que seja modificado por teste. Não há maneira de contornar isso atualmente.

Dito isso, se você tiver uma proporção decente de acessórios, simplesmente executá-los em paralelo pode proporcionar um bom desempenho.

É possível ter o [Parallelizable (ParallelScope.Children)] no
Arquivo AssemblyInfo.cs?

Alguém viu isso funcionando?

Em 14 de junho de 2017 às 01:37, CharliePoole [email protected] escreveu:

[image: Boxbe] https://www.boxbe.com/overview Limpeza automática: manter
últimos 1 e-mails (notificaçõ[email protected]) Editar regra
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DCCP9ir0TebdbdQOWVtGMQyr2TETYOrzfkbItPzUTgDk%253D%26token%3D0PvYtf1G2B%252FJ2FNN3b7MTSmP1zvs6x3Cu8z6LaAB8%252BJm73uy8ZNUCnQcknlgWKxRQ5zjE%252BY30Xkv1W1Gue9gGnpyi72YUTaHP2h6wvuEpTXe1WoQDoSHpUGDQefgQu6LDH0rRhsEvF%252FW%252BhysbMtsDw%253D% 253D & tc_serial = 30872123699 & tc_rand = 2087335475 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Excluir regra
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DCCP9ir0TebdbdQOWVtGMQyr2TETYOrzfkbItPzUTgDk%253D%26token%3D0PvYtf1G2B%252FJ2FNN3b7MTSmP1zvs6x3Cu8z6LaAB8%252BJm73uy8ZNUCnQcknlgWKxRQ5zjE%252BY30Xkv1W1Gue9gGnpyi72YUTaHP2h6wvuEpTXe1WoQDoSHpUGDQefgQu6LDH0rRhsEvF%252FW%252BhysbMtsDw%253D% 253D & tc_serial = 30872123699 & tc_rand = 2087335475 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Marcar importante
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DCCP9ir0TebdbdQOWVtGMQyr2TETYOrzfkbItPzUTgDk%253D%26token%3D0PvYtf1G2B%252FJ2FNN3b7MTSmP1zvs6x3Cu8z6LaAB8%252BJm73uy8ZNUCnQcknlgWKxRQ5zjE%252BY30Xkv1W1Gue9gGnpyi72YUTaHP2h6wvuEpTXe1WoQDoSHpUGDQefgQu6LDH0rRhsEvF%252FW%252BhysbMtsDw%253D% 253D% 26important% 3Dtrue% 26emlId% 3D61187554820 & tc_serial = 30872123699 & tc_rand = 2087335475 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001

Você descobriu! Sim, todos os testes em um aparelho usam a mesma instância.
Isso é histórico com o NUnit, que sempre funcionou dessa forma. Você deve
escolher entre executar os casos de teste em paralelo e ter qualquer estado que
é modificado por teste. Não há maneira de contornar isso atualmente.

Dito isso, se você tiver uma proporção decente de acessórios, basta executar
acessórios em paralelo podem oferecer um bom desempenho.

-
Você está recebendo isto porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/nunit/nunit/issues/164#issuecomment-308157832 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAHNVuK-J-X74mlAA_eT7OX7dxs7MpoRks5sDqzLgaJpZM4CUZ8r
.

@agray Sim, na verdade essa é a única razão pela qual tenho um AssemblyInfo.cs agora.

Oi joseph,

Que linha de paralelismo você está adicionando ao arquivo AssemblyInfo.cs?

Adoraria saber o que funciona.

Saúde,

Andrew

Na quarta-feira, 14 de junho de 2017 às 4:17 PM, Joseph Musser [email protected]
escreveu:

[image: Boxbe] https://www.boxbe.com/overview Limpeza automática: manter
últimos 1 e-mails (notificaçõ[email protected]) Editar regra
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DnRGYOf%252FKR68McP8RTipuFTLF9WUvAkSKSh6OYJYvJ2w%253D%26token%3DDcwWzMT9yPtQLckdXD3BLhW5xAB%252BMpc9XdsrbBlwdQJZC%252Bjo3SjsyMVC8vese%252BCNRw2IyucWqEcHR5Is7CK7nx01VuSQESvjG4ZUj%252B2Cfcwg51yUFFQJSwrmTVxqAk4%252BTVGDSrnutdAuqiJ3kTaYQA% 253D% 253D & tc_serial = 30882364582 & tc_rand = 1974513896 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Excluir regra
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DnRGYOf%252FKR68McP8RTipuFTLF9WUvAkSKSh6OYJYvJ2w%253D%26token%3DDcwWzMT9yPtQLckdXD3BLhW5xAB%252BMpc9XdsrbBlwdQJZC%252Bjo3SjsyMVC8vese%252BCNRw2IyucWqEcHR5Is7CK7nx01VuSQESvjG4ZUj%252B2Cfcwg51yUFFQJSwrmTVxqAk4%252BTVGDSrnutdAuqiJ3kTaYQA% 253D% 253D & tc_serial = 30882364582 & tc_rand = 1974513896 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Marcar importante
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DnRGYOf%252FKR68McP8RTipuFTLF9WUvAkSKSh6OYJYvJ2w%253D%26token%3DDcwWzMT9yPtQLckdXD3BLhW5xAB%252BMpc9XdsrbBlwdQJZC%252Bjo3SjsyMVC8vese%252BCNRw2IyucWqEcHR5Is7CK7nx01VuSQESvjG4ZUj%252B2Cfcwg51yUFFQJSwrmTVxqAk4%252BTVGDSrnutdAuqiJ3kTaYQA% 253D% 253D% 26important% 3Dtrue% 26emlId% 3D61214070592 & tc_serial = 30882364582 & tc_rand = 1974513896 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001

@array https://github.com/array Sim, na verdade essa é a única razão de eu
tenha um AssemblyInfo.cs agora.

-
Você está recebendo isto porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/nunit/nunit/issues/164#issuecomment-308325726 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAHNVghNAX8CJkqAy-qhAz8bXNhZcFOQks5sD3NigaJpZM4CUZ8r
.

@agray Aquele sobre o qual você perguntou:

c# [Parallelizable(ParallelScope.Children)]

não se esqueça do alvo

[assembly: Parallelizable(ParallelScope.Children)]

@LirazShay Eu uso o NUnit para conduzir os testes do Selenium, e estava usando campos no nível do fixture para manter coisas como referências a contas de usuário e à instância do Selenium WebDriver com a qual eu estava trabalhando e, portanto, não era possível executar testes paralelos no fixture. A maneira como eu contornei isso foi escrever uma "fábrica" ​​(eu uso aspas porque não tenho certeza se é o termo certo) que implementa IDisposable que para cada teste encapsula todas as minhas necessidades de teste e as elimina de forma limpa no final do teste sem necessidade de [TearDown] ou [OneTimeTearDown] mais ou menos assim:

 public class TestFactory : IDisposable
    {
    // Instantiate a new SafeHandle instance.
    private readonly System.Runtime.InteropServices.SafeHandle handle = new Microsoft.Win32.SafeHandles.SafeFileHandle(IntPtr.Zero, true);

    // Flag: Has Disposed been called?
    private bool disposed = false;

    public TestFactory()
    {
        this.UserRepository = new List<UserAccount>();
        this.DU = new DataUtility();
    }

    // A list of users created for this test
    public List<UserAccount> UserRepository { get; private set; }

    // A very simple data layer utility that uses Dapper to interact with the database in my application 
    public DataUtility DU { get; private set; }

    // Gets a new user and adds it to the repository
    public UserAccount GetNewUser()
    {
        var ua = new UserAccount();
        this.UserRepository.Add(ua);
        return ua;
    }


    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (this.disposed)
        {
            return;
        }

        if (disposing)
        {
            // Deletes all user accounts created during the test
            foreach (UserAccount ua in this.UserRepository)
            {
                try
                {
                    ua.Delete();
                }
                catch (Exception)
                {
                    // Take no action if delete fails.
                }
            }

            this.DU.DeleteNullLoginFailures(); // Cleans up the database after tests
            Thread.Sleep(1500);
        }

        this.disposed = true;
    }
}

Então, dentro de um teste, posso fazer isso:

[TestFixture]
public class UserConfigureTests
{
    [Test]
    public void MyExampleTest()
    {
        using (TestFactory tf = new TestFactory())
        {
            var testUser = tf.GetNewUser();

    tf.DU.DoSomethingInTheDatabase(myParameter);

    // Test actions go here, and when we exit this using block the TestFactory cleans
    // up after itself using the Dispose method which calls whatever cleanup logic you've written into it
        }
    }
}

Dessa forma, posso evitar muita duplicação de código e, se precisar alterar as dependências do meu teste, faço isso apenas uma vez na fábrica. Se alguém tiver comentários sobre a estratégia que usei, agradeço!

@tparikka Eu mesmo recomendo altamente exatamente essa abordagem.

Tenho o seguinte em meu arquivo AssemblyInfo:

[montagem: Parallelizable (ParallelScope.Children)]
[montagem: LevelOfParallelism (16)]

Eu preciso do atributo LevelOfParallelism também?

Em 15 de junho de 2017 às 04:37, Joseph Musser [email protected] escreveu:

[image: Boxbe] https://www.boxbe.com/overview Limpeza automática: manter
últimos 1 e-mails (notificaçõ[email protected]) Editar regra
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Doth%252FFbAPG%252FhDbtUlS0i2PDDdQ0lP4dBi8o7QQmkLEMQ%253D%26token%3DHe7HfTrm%252Fiba3yIDazaBx8JO9NrmoL8p5TWtDB1hUxq0qp%252BhCRCB3OSl7sUQ6wDshc2I5LQhbR2jszLWr6FnRy%252FZUrCqghZIIilbDWKszT7pkI44xp9vaL6cszH9Sgg1YPCAHdVWqccZYxYXGW174A%253D% 253D & tc_serial = 30894750852 & tc_rand = 1847060911 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Excluir regra
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Doth%252FFbAPG%252FhDbtUlS0i2PDDdQ0lP4dBi8o7QQmkLEMQ%253D%26token%3DHe7HfTrm%252Fiba3yIDazaBx8JO9NrmoL8p5TWtDB1hUxq0qp%252BhCRCB3OSl7sUQ6wDshc2I5LQhbR2jszLWr6FnRy%252FZUrCqghZIIilbDWKszT7pkI44xp9vaL6cszH9Sgg1YPCAHdVWqccZYxYXGW174A%253D% 253D & tc_serial = 30894750852 & tc_rand = 1847060911 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Marcar importante
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Doth%252FFbAPG%252FhDbtUlS0i2PDDdQ0lP4dBi8o7QQmkLEMQ%253D%26token%3DHe7HfTrm%252Fiba3yIDazaBx8JO9NrmoL8p5TWtDB1hUxq0qp%252BhCRCB3OSl7sUQ6wDshc2I5LQhbR2jszLWr6FnRy%252FZUrCqghZIIilbDWKszT7pkI44xp9vaL6cszH9Sgg1YPCAHdVWqccZYxYXGW174A%253D% 253D% 26important% 3Dtrue% 26emlId% 3D61245244440 & tc_serial = 30894750852 & tc_rand = 1847060911 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001

@tparikka https://github.com/tparikka Eu recomendo exatamente isso
me aproxime.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/nunit/nunit/issues/164#issuecomment-308521058 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAHNVmEzVDbw32Xx0jkYcGK9bZW3tLvXks5sECh8gaJpZM4CUZ8r
.

Eu não tentei usar LevelOfParallelism ainda. O padrão é o número de núcleos que você tem.

Se seus testes não forem limitados pela CPU, mais alto faz sentido. Mas, como sempre, com o desempenho, a resposta depende tanto do cenário que é melhor medir do que adivinhar.

@CharliePoole Estou usando TestcaseSource , mas parece que os casos de teste resultantes não estão sendo executados em paralelo. Espera-se que algo assim funcione:

`` `c #
[TestFixture]
classe desserialização
{
public static IEnumerableShouldDeserializeAllCases () => Enumerable.Repeat (0, 5) .Select (x => TimeSpan.FromSeconds (2));

    [TestCaseSource("ShouldDeserializeAllCases"), Parallelizable(ParallelScope.Children)]
    public void ShouldDeserializeAll(TimeSpan t)
    {
        Thread.Sleep(t);
        Assert.AreEqual(1, 1);
    }
}

`` `

O tempo total gasto é de 10 segundos em vez de ~ 2.

Vou pensar que não há filhos, então, neste caso, você poderia usar melhor
[Parallelizable (ParallelScope.All)]
ou mova seu atributo no nível da classe.

@ParanoikCZE Obrigado. Na verdade, estou voando às cegas em relação ao que esse atributo significa, então tentei todos os valores enum lá. Independentemente de qual All , Children , Fixture ou Self eu uso, obtenho um tempo de execução de 10 segundos (pelo menos no Visual Studio).

Eu apenas tentei mover para a classe, mas isso também não parece ajudar.

Experimente isso é fonte de inspiração :)

class Deserialization
{
    public static IEnumerable<TestCaseData> ShouldDeserializeAllCases
    {
        get
        {
            for (int i = 1; i <= 5; i++)
                yield return new TestCaseData(TimeSpan.FromSeconds(i)).SetName($"Thread_worker_{i}");
        }
    }

    [TestCaseSource(nameof(ShouldDeserializeAllCases)), Parallelizable(ParallelScope.Children)]
    public void ShouldDeserializeAll(TimeSpan t) => System.Threading.Thread.Sleep(t);
}

@ParanoikCZE Obrigado novamente. Eu testei isso no Visual Studio e a visualização é muito mais clara, mas os testes ainda estão sendo executados sequencialmente. Mais fácil de ver isso se você usar um sono constante para cada caso de teste em vez de aumentar as etapas.

Tente adicionar [assembly: LevelOfParallelism (5)] em AssemblyInfo, acho que há algum valor padrão, mas talvez não funcione para você de alguma forma. De qualquer forma, estou sem ideias. :)

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