Events 如何在带有SetUpFixture的mutliple Nunit TestFixture中使用单个Log4Net实例

Events 如何在带有SetUpFixture的mutliple Nunit TestFixture中使用单个Log4Net实例,events,nunit,log4net,Events,Nunit,Log4net,我刚刚开始使用SeleniumWebDriver及其EventFireing,这样我就可以将驱动程序抛出的任何异常记录到文件或电子邮件中 我已经让Log4Net正常工作,并且我的单元测试在Selenium中运行良好 我遇到的问题是让Log4Net创建1个日志文件,但是针对多个测试装置 这里有一些重要的课程,我想我需要向你们展示,以解释我的问题 public class EventLogger : EventFiringWebDriver { // Not sure if this is

我刚刚开始使用SeleniumWebDriver及其EventFireing,这样我就可以将驱动程序抛出的任何异常记录到文件或电子邮件中

我已经让Log4Net正常工作,并且我的单元测试在Selenium中运行良好

我遇到的问题是让Log4Net创建1个日志文件,但是针对多个测试装置

这里有一些重要的课程,我想我需要向你们展示,以解释我的问题

public class EventLogger : EventFiringWebDriver
{
    // Not sure if this is the best place to declare Log4Net

    public static readonly ILog Log = LogManager.GetLogger(typeof(EventLogger));

    public EventLogger(IWebDriver parentDriver) : base(parentDriver)
    {
        // To get Log4Net to read the configuration file on what logger to use
        // To console , file, email etc

        XmlConfigurator.Configure();

        if (Log.IsInfoEnabled)
        {
            Log.Info("Logger started.");
        }

    }

    protected override void OnFindingElement(FindElementEventArgs e)
    {
        base.OnFindingElement(e);

        //TODO:

        if (Log.IsInfoEnabled)
        {
            Log.InfoFormat("OnFindingElement: {0}", e);
        }
    }       

    protected override void OnElementClicked(WebElementEventArgs e)
    {
        base.OnElementClicked(e);

        //TODO:

        if (Log.IsInfoEnabled)
        {
            Log.InfoFormat("OnElementClicked: {0}", e.Element.GetAttribute("id"));
        }

    }
}
这是我的SetupFixture——我认为每次运行新的TestFixture类时都会运行它

    [SetUpFixture]
public class BaseTest
{
    protected static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    private FirefoxProfile firefoxProfile;
    private IWebDriver driver;
    private EventLogger eventLogger;   

    public IWebDriver StartDriver()
    {
        Common.WebBrowser = ConfigurationManager.AppSettings["WebBrowser"];
        Log.Info("Browser: " + Common.WebBrowser);       

        switch (Common.WebBrowser)
        {
            case "firefox":
                {
                    firefoxProfile = new FirefoxProfile { AcceptUntrustedCertificates = true };
                    driver = new FirefoxDriver(firefoxProfile);
                    break;
                }
            case "iexplorer":
                {
                    driver = new InternetExplorerDriver();
                    break;
                }
            case "chrome":
                {
                    driver = new ChromeDriver();
                    break;
                }
        }

        driver.Manage().Timeouts().ImplicitlyWait(Common.DefaultTimeSpan);


        // Here is where I start my EventLogger to handle the events from selenium
        // web driver, onClick, OnFindingElement etc.
        // Is this the best way? Seems a bit messy, lack of structure

        return eventLogger = new EventLogger(driver);


    }

    public EventLogger EventLogger
    {
        get { return eventLogger; }
    }

}
这里是我拥有的众多测试装置中的一个,每一个都基于Selenium2 PageObjects

[TestFixture]
public class LoginPageTest : BaseTest
{
    private IWebDriver driver;
    private LoginPage loginPage;

    [SetUp]
    public void SetUp()
    {         

        // Where I use the Log from the BaseTest 
        // protected static readonly ILog Log <-- top of BaseTest

        Log.Info("SetUp");


        driver = StartDriver();
        driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));

        loginPage = new LoginPage();
        PageFactory.InitElements(driver, loginPage);         
    }

    [Test]
    public void SubmitFormInvalidCredentials()
    {
        Console.WriteLine("SubmitFormInvalidCredentials");


        loginPage.UserName.SendKeys("invalid");
        loginPage.Password.SendKeys("invalid");
        loginPage.SubmitButton.Click();            

        IWebElement invalidCredentials = driver.FindElement(By.Id("ctl00_ctl00_ctl00_insideForm_insideForm_ctl02_title"));
        Assert.AreEqual("Invalid user name or password", invalidCredentials.Text);
    }
}
[TestFixture]
公共类LoginPageTest:BaseTest
{
私人IWebDriver;
私人登录页面登录页面;
[设置]
公共作废设置()
{         
//我使用BaseTest中的日志的地方

//受保护的静态只读ILog日志请在您正在使用的FileAppender的log4net配置中尝试显式设置
AppendToFile=“True”


财产

获取或设置一个标志,该标志指示是否应追加文件 覆盖或覆盖

关于
[SetupFixture]
,我相信您使用它的方式是错误的。它不应该用这个属性来标记每个TesFixture的基类,这看起来很混乱。您应该声明被认为是SetupFixture的类,并用
[SetupFixture]来标记它
属性,以便对给定(声明)命名空间中的所有TestFixture调用一次

从NUnit文档中,:

这是一个属性,用于标记包含一次性 给定条件下所有测试夹具的设置或拆卸方法 命名空间。该类最多可以包含一个用 SetUpAttribute和一个用TearDownAttribute标记的方法


谢谢你的回复。我已经像你提到的那样更改了SetUpFixture。我仍然使用两个ILog,但没关系,它们都附加到同一个文件中。现在每个派生类都可以使用基类中的ILog,因为我不再声明它是静态的,这样记录器就可以在它总是作为BaseTest记录之前知道它来自哪个类。现在它以LoginPageTest、SearchPageTest等形式登录。但是关于
AppendToFile=“true”
,它对您有帮助吗?是的,这是我在App.config部分中设置的。:)