Nunit: Diretório de trabalho para testes no console NUnit 3

Criado em 26 nov. 2015  ·  21Comentários  ·  Fonte: nunit/nunit

No NUnit 2.6.4, o diretório de trabalho para meus testes foi definido para o diretório bin/Debug da DLL de teste. Isso me permitiu carregar arquivos externos em testes por caminho relativo.

Parece que agora o dir de trabalho está definido como o diretório de trabalho do executor do console. Isso é intencional?

Como posso deixar os resultados do teste (arquivos * .xml) no diretório de trabalho do executor do console enquanto tenho o diretório de trabalho para meus testes definido como bin/Debug ?

notabug

Comentários muito úteis

@imakowski , você tentou definir o diretório de trabalho atual para um diretório conhecido em uma configuração de assembly? Código não testado, mas algo parecido;

`` `C #
[SetUpFixture]
public class MySetUpClass
{
[OneTimeSetUp]
RunBeforeAnyTests ()
{
var dir = Path.GetDirectoryName (typeof (MySetUpClass) .Assembly.Location);
Environment.CurrentDirectory = dir;

    // or
    Directory.SetCurrentDirectory(dir);
}

}
`` `

Todos 21 comentários

Isso ocorre por design, conforme mostrado aqui: https://github.com/nunit/nunit/wiki/Breaking-Changes

Em versões anteriores, o NUnit alterava o diretório de trabalho. Não é mais assim. Você pode usar TestContext.TestDirectory para obter o diretório que contém o assembly de teste.

Isso quebra muitos testes! Por que você mudou isso? Alguns dos testes não podem ser corrigidos porque o código de tempo de execução do aplicativo testado tem dependência de que o diretório de trabalho é o local do conjunto de teste.

@imakowski , você tentou definir o diretório de trabalho atual para um diretório conhecido em uma configuração de assembly? Código não testado, mas algo parecido;

`` `C #
[SetUpFixture]
public class MySetUpClass
{
[OneTimeSetUp]
RunBeforeAnyTests ()
{
var dir = Path.GetDirectoryName (typeof (MySetUpClass) .Assembly.Location);
Environment.CurrentDirectory = dir;

    // or
    Directory.SetCurrentDirectory(dir);
}

}
`` `

@imakowski você pode não ter controle sobre ele, mas o código / aplicativos não devem depender do diretório de trabalho atual que está sendo definido. Os aplicativos devem sempre determinar seu diretório bin com código como apresentei acima. Existem várias chamadas de API no Windows que alteram o diretório de trabalho atual sem que você perceba. Seu aplicativo pode funcionar bem na maioria das vezes, mas falhar depois que um usuário visitar uma parte raramente usada de seu aplicativo.

@rprouse este código não funciona quando está no modo de cópia de sombra
var dir = Path.GetDirectoryName(typeof(MySetUpClass).Assembly.Location);

Você pode usar isso neste caso:
var dir = Path.GetDirectoryName(new Uri(typeof(MySetUpClass).Assembly.CodeBase).LocalPath);

Como alternativa, nós o fornecemos como TestContext.CurrentContext.TestDirectory. :-)

Usamos o Uri conforme sugerido com alguns ajustes para casos especiais.

Como alternativa, nós o fornecemos como TestContext.CurrentContext.TestDirectory. :-)

não há mais propriedade TestDirectory em CurrentContext. eu uso o nunit 3.6.1. há apenas WorkDirectory que, no meu caso, quando começo o teste a partir de pontos de recompactação para o lugar errado :(

Existe TestContext.TestDirectory. É uma propriedade estática. Eu acredito que WorkDirectory também está?

bem, não consigo encontrá-lo usando o navegador do Visual Studio ou compilador ou descompilador telérico.
mas eu vejo isso na unidade 3.5. Não tenho certeza do que está errado

Eu estava errado.

É TestContext.CurrentContext.TestDirectory.

No entanto, não está lá na construção PORTABLE.

#if !PORTABLE
        /// <summary>
        /// Gets the directory containing the current test assembly.
        /// </summary>
        public string TestDirectory
        {
            get
            {
                Assembly assembly = _testExecutionContext?.CurrentTest?.TypeInfo?.Assembly;

                if (assembly != null)
                    return AssemblyHelper.GetDirectoryName(assembly);

#if NETSTANDARD1_6
                // Test is null, we may be loading tests rather than executing.
                // Assume that the NUnit framework is in the same directory as the tests
                return AssemblyHelper.GetDirectoryName(typeof(TestContext).GetTypeInfo().Assembly);
#else
                // Test is null, we may be loading tests rather than executing.
                // Assume that calling assembly is the test assembly.
                return AssemblyHelper.GetDirectoryName(Assembly.GetCallingAssembly());
#endif
            }
        }
#endif

está lá no 3.6.0, mas não no 3.6.1

Estou olhando para o repositório github atual e é exatamente como copiei e colei acima.

Tem certeza de que não está usando a compilação PORTABLE de alguma forma?

sim estou usando

Bem, é por isso que não está lá. Não é suportado na compilação PORTABLE, e nunca foi, que eu saiba. No entanto, nunca usei a compilação PORTABLE, apenas execute os testes de CI nela.

obrigada

Directory.SetCurrentDirectory (AppDomain.CurrentDomain.BaseDirectory);

Para as pessoas eyeballing de código real, reunindo o que @CharliePoole e @rprouse disse, é

[SetUpFixture]
public class MySetUpClass
{
    [OneTimeSetUp]
    public void RunBeforeAnyTests()
    {
        Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory;
        // or identically under the hoods
        Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
    }
}

Para inicialização global

Apenas não coloque a lógica acima dentro de nenhum namespace. ie

using NUnit.Framework;
using System;
using System.IO;

[SetUpFixture]
public class GlobalSetup
{
    [OneTimeSetUp]
    public void RunBeforeAnyTests()
    {
        Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory;
        // or identically under the hoods
        Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
    }
}

Além disso, parece que TestContext.CurrentContext.TestDirectory tem um pouco mais de inteligência para lidar com casos extremos, então eu escolheria isso acima de typeof(MySetUpClass).Assembly.Location

então eu escolheria isso em vez de typeof (MySetUpClass) .Assembly.Location

Location retorna a localização da sombra se a montagem for copiada, normalmente você não gostaria disso. Em vez disso, use CodeBase , que retorna Uri do local real de onde é executado inicialmente, antes de qualquer cópia de sombra.

Obviamente, é melhor usar TestDirectory , mas parece haver problemas com essa propriedade, consulte # 2872, causando exceções que não podem ser detectadas. Não sei se eles também podem aparecer se você usar OneTimeSetup (presumo que não), mas deve-se tomar cuidado até que isso seja resolvido.

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

Questões relacionadas

DavidKlempfner picture DavidKlempfner  ·  3Comentários

xplicit picture xplicit  ·  5Comentários

Thaina picture Thaina  ·  5Comentários

UyttenhoveSimon picture UyttenhoveSimon  ·  3Comentários

ffMathy picture ffMathy  ·  3Comentários