TestContext имеет значение null, когда к нему обращаются из виртуального метода базового класса.

У меня есть базовый класс ScriptBase, в котором есть виртуальная функция с именем MyTestInitialize(). Когда я вызываю MyTestInitialize() из производного класса, значение testContextInstance равно null. Есть ли какое-нибудь решение для этого? Пожалуйста, помогите, так как я новичок в автоматизированном тестировании. Заранее спасибо

[CodedUITest]
public class ScriptsBase
{
    public ScriptsBase()
    {   
    }

    private static TestContext bingTestContext;

    public static TestContext BingTestContext
    {
        get { return ScriptsBase.bingTestContext; }
        set { ScriptsBase.bingTestContext = value;}
    }

    #region TestInitialize
    //Use TestInitialize to run code before running each test 
    [TestInitialize()]
    public virtual void MyTestInitialize()
    {
        Browser.CloseAllBrowsers();
        BingTestContext = testContextInstance;
    }
    #endregion

    #region TestCleanup
    //Use TestCleanup to run code after each test has run
    [TestCleanup()]
    public virtual void MyTestCleanup()
    {
        PPI.HomePage = new HomePageUI();
        Browser.CloseAllBrowsers();
    }
    #endregion

    #region TestContext
    /// <summary>
    ///Gets or sets the test context which provides
    ///information about and functionality for the current test run.
    ///</summary>
    public TestContext TestContext
    {
        get
        {
            return testContextInstance;
        }
        set
        {
            testContextInstance = value;
        }
    }
    private TestContext testContextInstance;
    #endregion
}

 public class DestinationMasterTestScripts : ScriptsBase
  {
       public DestinationMasterTestScripts()
       {      
       }

       [TestInitialize()]
       public override void MyTestInitialize()
       {
           Console.WriteLine("Initialize");
           base.MyTestInitialize();
       }
   }     

person user3012888    schedule 20.11.2013    source источник
comment
Удалось ли вам найти какое-либо решение вашей проблемы? Однако, когда я попытался использовать ваш код, я также смог получить объект TestContext в базовом классе.   -  person digitguy    schedule 21.09.2014


Ответы (5)


Попробуйте создать Метод ClassInitialize:

    private static TestContext bingTestContext

    [ClassInitialize]
    public static void ClassInit(TestContext con)
    {
      bingTestContext = con;
    }
person Jens Kloster    schedule 20.11.2013
comment
Не помешает ли это результатам отдельных тестов, если вы это сделаете? - person Nathan; 30.01.2014
comment
Я не понимаю, как это могло быть. Но я не уверен. Это единственный способ (который я знаю), если вы хотите использовать TestContext - person Jens Kloster; 30.01.2014
comment
Я провел небольшое тестирование (MsTest, Visual Studio 2012), и с обычным свойством TestContext MsTest назначает другой экземпляр TestContext для каждого тестового метода. С описанным здесь подходом ClassInitialize у вас будет один TestContext экземпляр, совместно используемый всеми методами тестирования в классе. Это означает, что ваши модульные тесты больше не изолированы друг от друга, если они сохраняют что-либо в контексте теста или пишут в контекст теста с помощью своего метода WriteLine. - person Nathan; 30.01.2014
comment
Справедливости ради следует отметить, что исходный постер также имел статический экземпляр TestContext, который, вероятно, страдал бы от такого же отсутствия изоляции методов тестирования, даже если бы он работал — если только тесты [CodedUiTest] не ведут себя иначе, чем тесты [TestClass] — я проверял только тесты [TestClass]. - person Nathan; 30.01.2014
comment
@Nathan имеет отличную точку зрения, те же симптомы упоминаются здесь, я думаю, это БУДЬТЕ ОЧЕНЬ ОСТОРОЖНЫ с этим ответом, он будет работать в некоторых контекстах, а не в других. - person David Rogers; 18.01.2017
comment
Почему бы не сделать это [AssemblyInitialize], чтобы тестовые классы, работающие параллельно, не перезаписывали общий контекст? - person Luke Schoen; 08.01.2020
comment
См. также Транзакции модульных тестов в нагрузочных тестах Visual Studio., который заключает таймер в IDisposable и оператор using. - person Charlesdwm; 02.03.2021

Другой вариант - объявить TestContext как абстрактный в вашем базовом классе.

public abstract TestContext TestContext { get; set; }

И переопределите его в вашем наиболее производном конкретном классе (ах)

public override TestContext TestContext { get; set; }
person Nathan    schedule 29.01.2014

Вы должны использовать одинаковые классы для Assert и TestContext, например:

using Assert = NUnit.Framework.Assert;

using TestContext = NUnit.Framework.TestContext;
person Dmitry    schedule 01.11.2015

Посмотрите, поможет ли это, я считаю, что это работает, когда я устанавливаю базовый класс TestContext с производным классом один.

public TestContext TestContext
{
    get
    {
        return testContextInstance;
    }
    set
    {
        base.TestContext = value;
        testContextInstance = value;
    }
}

private TestContext testContextInstance;
person dev.bee    schedule 16.10.2014

Не уверен, что что-то изменилось за 6 лет с момента публикации этого вопроса, но у меня это работает почти как есть. Добавьте [TestClass] в производный класс, и TestContext будет настроен просто отлично. Также нет необходимости в BingTestContext. Просто используйте this.TestContext из производных классов.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

public class ScriptsBase
{
    public static TestContext BingTestContext { get; set; }

    public TestContext TestContext { get; set; }

    [TestInitialize]
    public virtual void MyTestInitialize()
    {
        BingTestContext = this.TestContext;
    }

    [TestCleanup]
    public virtual void MyTestCleanup()
    {
    }
}

[TestClass]
public class DestinationMasterTestScripts : ScriptsBase
{
    [TestInitialize]
    public override void MyTestInitialize()
    {
        base.MyTestInitialize();
    }

    [TestMethod]
    public void Foo()
    {
        Console.WriteLine(this.TestContext);
    }
}
person Luke Schoen    schedule 08.01.2020