You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSTest中ClassInitialize内调用方法触发空引用异常求助

问题:MSTest中使用[ClassInitialize]调用登录接口触发NullReferenceException

异常信息

Class Initialization method TestAutomation.Organisation2.OneTimeSetUp threw exception. System.NullReferenceException: Object reference not set to an instance of an object..

栈跟踪

Stack Trace: 
ILoginManager2.UILogin(IWebDriver driver, WebDriverWait wait) line 20
Organisation2.OneTimeSetUp(TestContext context) line 30
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)

相关代码

基类代码

namespace TestAutomation.TestBase
{
    public class TestBaseClass
    {
        public static IWebDriver driver;
        public static WebDriverWait wait;

        [TestInitialize]
        public void DriverSetUp()
        {
            driver = new ChromeDriver();
            driver.Manage().Window.Maximize();
            wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
        }
    }
}

测试类代码

using TestAutomation.TestBase;
namespace TestAutomation
{
    [TestClass()]
    public class Organisation2: TestBaseClass
    {
        [ClassInitialize()]
        public static void OneTimeSetUp(TestContext context)
        {
            ILoginManager2.UILogin(driver, wait); // driver和wait继承自TestBaseClass
        }

        [TestInitialize]
        public void Login()
        {
            // code
        }

        [TestMethod()]
        public void CreateOrg()
        {
            // code
        }
    }
}

登录接口代码

namespace SAMSAutomation
{
    public interface ILoginManager2
    {
        public static void UILogin(IWebDriver driver, WebDriverWait wait)
        {
            driver.Navigate().GoToUrl("https://www.example.com");

            IWebElement tbUserName = driver.FindElement(By.Name("SWEUserName"));
            IWebElement tbPassword = driver.FindElement(By.Name("SWEPassword"));
            IWebElement bLogin = driver.FindElement(By.Id("s_swepi_22"));

            tbUserName.SendKeys("User");
            tbPassword.SendKeys("Password");

            bLogin.Click();

            wait.Until(ExpectedConditions.ElementExists(By.LinkText("Home")));
        }
    }
}

原因分析

MSTest的执行顺序是**[ClassInitialize]先于[TestInitialize]执行**:

  1. 测试类的OneTimeSetUp(标记[ClassInitialize])会在类中所有测试方法执行前运行
  2. 基类的DriverSetUp(标记[TestInitialize])是在每个测试方法执行前才会运行
  3. 因此调用ILoginManager2.UILogin时,driver和wait还未被初始化,传入的是null,触发空引用异常

解决方案

方案1:将driver初始化移到[ClassInitialize]中

修改测试类的OneTimeSetUp,先完成driver和wait的初始化,再调用登录:

[ClassInitialize()]
public static void OneTimeSetUp(TestContext context)
{
    // 先初始化driver和wait
    driver = new ChromeDriver();
    driver.Manage().Window.Maximize();
    wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
    
    ILoginManager2.UILogin(driver, wait);
}

同时调整基类,添加[ClassCleanup]确保测试后关闭浏览器,避免资源泄漏:

namespace TestAutomation.TestBase
{
    public class TestBaseClass
    {
        public static IWebDriver driver;
        public static WebDriverWait wait;

        [ClassCleanup]
        public static void DriverTearDown()
        {
            // 安全关闭浏览器
            driver?.Quit();
            driver?.Dispose();
        }
    }
}

方案2:将初始化逻辑封装到基类的[ClassInitialize]

如果多个测试类都需要类似的初始化,可以把逻辑放到基类的静态方法中,子类自动继承执行:

namespace TestAutomation.TestBase
{
    public class TestBaseClass
    {
        public static IWebDriver driver;
        public static WebDriverWait wait;

        [ClassInitialize]
        public static void BaseClassInitialize(TestContext context)
        {
            driver = new ChromeDriver();
            driver.Manage().Window.Maximize();
            wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
        }

        [ClassCleanup]
        public static void DriverTearDown()
        {
            driver?.Quit();
            driver?.Dispose();
        }
    }
}

测试类的OneTimeSetUp只需调用登录:

[ClassInitialize()]
public static void OneTimeSetUp(TestContext context)
{
    ILoginManager2.UILogin(driver, wait);
}

注意事项

  • 静态成员driver和wait会在当前测试类的所有测试方法中共享,若测试项目启用并行测试,可能会导致不同测试类之间的资源冲突,这种情况下建议使用TestContext存储driver实例,或者为每个测试类创建独立的driver。
  • 如果需要整个测试程序集只初始化一次浏览器,可以使用[AssemblyInitialize]标记静态方法,但需注意后续测试方法可能受到之前测试状态的影响。

内容的提问来源于stack exchange,提问作者Jimmy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 03:18:16