问题描述
我正在使用Selenium Webdriver及其EventFiring,以便我可以将驱动程序抛出的任何异常记录到文件或电子邮件等。
我有Log4Net工作,我的单元测试运行正常与Selenium。
我遇到的问题是使Log4Net创建1个日志文件,但是对于多个测试夹具。
以下是一些重要的课程,我认为我需要向您展示以解释我的问题。
public class EventLogger:EventFiringWebDriver
{
//不确定这是否是声明Log4Net
的最佳位置public static readonly ILog Log = LogManager.GetLogger(typeof运算(事件记录器));
public EventLogger(IWebDriver parentDriver):base(parentDriver)
{
//要让Log4Net读取配置文件,要使用哪个记录器
// To控制台,文件,电子邮件等
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);
私人FirefoxProfile firefoxProfile;
私人IWebDriver驱动程序;
私人EventLogger eventLogger;
public IWebDriver StartDriver()
{
Common.WebBrowser = ConfigurationManager.AppSettings [WebBrowser];
Log.Info(Browser:+ Common.WebBrowser);
switch(Common.WebBrowser)
{
casefirefox:
{
firefoxProfile = new FirefoxProfile {AcceptUntrustedCertificates = true};
driver = new FirefoxDriver(firefoxProfile);
break;
}
caseiexplorer:
{
driver = new InternetExplorerDriver();
break;
}
casechrome:
{
driver = new ChromeDriver();
break;
}
}
driver.Manage()。Timeouts()。ImplicitlyWait(Common.DefaultTimeSpan);
//这里是我启动我的EventLogger来处理来自selenium
// web driver,onClick,OnFindingElement等的事件
//这是最好的办法?似乎有点凌乱,缺乏结构
返回eventLogger =新的EventLogger(驱动程序);
}
public EventLogger EventLogger
{
get {return eventLogger; }
}
}
TestFixtures我有,每个基于Selenium2 PageObjects
[TestFixture]
public class LoginPageTest:BaseTest
{
私人IWebDriver驱动程序;
private LoginPage loginPage;
[SetUp]
public void SetUp()
{
//我在BaseTest中使用日志
//保护静态readonly ILog日志< - BaseTest的顶部
Log.Info(SetUp);
driver = StartDriver();
driver.Manage()。Timeouts()。ImplicitlyWait(TimeSpan.FromSeconds(30));
loginPage = new LoginPage();
PageFactory.InitElements(driver,loginPage);
}
[测试]
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(无效的用户名或密码,invalidCredentials.Text);
}
}
我的 Log.txt
文件显然在每个 TestFixture
运行后一遍又一遍地重写,
如何设置我的NUnit测试,以便我只运行一次Log4Net,以便我可以在我的 EventLogger
和 TestFixtures
?
我已经有很多Googled,也许它的东西很简单。我的项目结构有一些设计问题吗?
在log4net中明确设置 AppendToFile =True
您正在使用的FileAppender的配置:
< log4net>
< appender name =...type =log4net.Appender ....>
< appendToFile value =true/>
属性
关于 从NUnit文档,: I'm just getting into the use of Selenium Webdriver and its EventFiring so that I can log any exceptions thrown by the driver to a file or email etc. I have got Log4Net working and my Unit Tests are running fine with Selenium. What I am having issues with is having Log4Net create 1 log file, but for multiple test fixtures. Here are some important classes which I think I need to show you in order to explain my issue. Here is my SetupFixture - which I THINK is run every time a new TestFixture class is run. Here is one of the many TestFixtures I have, each one based on a Selenium2 PageObjects My How can I set up my NUnit Testing so that I only run the Log4Net once, so that I can use it in both my I have Googled around a lot, maybe its something simple. Do I have some design issues with the structure of my project? Try out setting explicitly FileAppender.AppendToFile property Regarding From NUnit documentation, SetUpFixtureAttribute: 这篇关于如何使用SetUpFixture在多个Nunit TestFixture中使用单个Log4Net实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! [SetupFixture] / code>,我相信你以错误的方式使用它。它不应该通过此属性标记每个TesFixture的基类,这看起来很乱。你应该声明一个被认为是SetupFixture的类,并通过
[SetupFixture]
属性来标记它,所以在一个给定的(声明)命名空间中,所有的TestFixture都被称为ONCE。 >
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]
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; }
}
}
[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
file is obviously being re-written over and over after each TestFixture
is run,EventLogger
and TestFixtures
?AppendToFile="True"
in the log4net configuration for the FileAppender you are using:<log4net>
<appender name="..." type="log4net.Appender....">
<appendToFile value="true" />
[SetupFixture]
, I believe you are using it in wrong way. It not supposed to mark base class of the each TesFixture by this attribute, this looks messy. You should declare class which considered to be SetupFixture and mark it by [SetupFixture]
attribute so it will be called ONCE for all TestFixtures within a given (declaration) namespace.