Как использовать один экземпляр Log4Net в нескольких Nunit TestFixtures с SetUpFixture - PullRequest
2 голосов
/ 09 ноября 2011

Я только начинаю использовать Selenium Webdriver и его EventFiring, чтобы я мог записывать любые исключения, сгенерированные драйвером, в файл или электронную почту и т. Д.

У меня работает 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; }
    }

}

Вот один изу меня есть много TestFixtures, каждое из которых основано на PageObjects Selenium2

[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);
    }
}

Мой Log.txt файл, очевидно, переписывается снова и снова после каждого TestFixture запуска,

Какмогу ли я настроить свое тестирование NUnit так, чтобы я запускал Log4Net только один раз, чтобы я мог использовать его как в своих EventLogger и TestFixtures?

Я много гуглил, может быть, это что-то простое,Есть ли у меня некоторые проблемы со структурой моего проекта?

1 Ответ

3 голосов
/ 10 ноября 2011

Попробуйте явно указать AppendToFile="True" в конфигурации log4net для используемого FileAppender:

<log4net>
    <appender name="..." type="log4net.Appender....">
      <appendToFile value="true" />

FileAppender.AppendToFile свойство

Получаетили устанавливает флаг, который указывает, должен ли файл быть добавлен или перезаписан

Относительно [SetupFixture], я полагаю, вы используете его неправильно.Он не должен помечать базовый класс каждой TesFixture этим атрибутом, это выглядит грязно.Вы должны объявить класс, который считается SetupFixture, и пометить его атрибутом [SetupFixture], чтобы он назывался ONCE для всех TestFixtures в данном пространстве имен (объявлений).

Из документации NUnit, SetUpFixtureAttribute :

Этот атрибут помечает класс, содержащий одноразовые методы настройки или разрыва для всех тестовых приборов в данном пространстве имен.Класс может содержать не более одного метода, помеченного с помощью SetUpAttribute, и одного метода, помеченного с помощью TearDownAttribute

...