我有一个自动化项目(Java、Maven with TestNG、log4j)。我试图为每个测试类创建日志文件(LoginTest将创建LoginTest.log,HomeTest将创建HomeTest.log,等等),为此我实现了自己的日志机制,但在运行结束时,我只得到最后一个类测试日志文件(用于运行的最后一个测试类)。
这是我的逻辑:
public class TestLogger extends LoggerFormat {
private static final DateTimeFormatter TIMESTAMP_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of(EnvConf.getDefaultTimeZone());
private final ThreadLocal<Map<String, List<String>>> testsLogMap = new ThreadLocal<>();
public void info(ITestContext context, String messageFormat, Object... args) {
String msg = handleFormatMsg(messageFormat, args);
super.info(msg);
log(Level.INFO, context, msg);
}
public void error(ITestContext context, Throwable t, String messageFormat, Object... args) {
String msg = handleFormatMsg(messageFormat, args);
super.error(msg, t);
log(Level.ERROR, context, msg, t);
}
public void error(ITestContext context, String messageFormat, Object... args) {
String msg = handleFormatMsg(messageFormat, args);
super.error(msg);
log(Level.ERROR, context, msg);
}
public void warn(ITestContext context, String messageFormat, Object... args) {
String msg = handleFormatMsg(messageFormat, args);
super.warn(msg);
log(Level.WARN, context, msg);
}
public void warn(ITestContext context, Throwable t, String messageFormat, Object... args) {
String msg = handleFormatMsg(messageFormat, args);
super.warn(msg, t);
log(Level.WARN, context, msg, t);
}
public void debug(ITestContext context, String messageFormat, Object... args) {
String msg = handleFormatMsg(messageFormat, args);
super.debug(msg);
if (LoggerFactory.isDebug()) {
log(Level.DEBUG, context, msg);
}
}
public void debug(ITestContext context, Throwable t, String messageFormat, Object... args) {
String msg = handleFormatMsg(messageFormat, args);
super.debug(msg, t);
if (LoggerFactory.isDebug()) {
log(Level.DEBUG, context, msg, t);
}
}
private void log(Level level, ITestContext context, Object message, Throwable t) {
message = String.format("%s\n%s", message, throwableToString(t));
log(level, context, message);
}
private void log(Level level, ITestContext context, Object message) {
Map<String, List<String>> logsMap = getLogsMap();
if (!logsMap.containsKey(context.getName())) {
logsMap.put(context.getName(), new ArrayList<>());
}
logsMap.get(context.getName()).add(formatMsg(message, level));
if (level.toInt() != Level.DEBUG.toInt()) {
Reporter.log((String) message, 0);
}
}
private static String formatMsg(Object message, Level level) {
LocalDateTime dateTime = LocalDateTime.now(DEFAULT_ZONE_ID);
return String.format("[%s][%s]%s",
TIMESTAMP_FORMAT.format(dateTime),
level, message);
}
public List<String> getAndDeleteLogsByTest(String testName) {
return getLogsMap().remove(testName);
}
private Map<String, List<String>> getLogsMap() {
if (testsLogMap.get() == null) {
testsLogMap.set(new HashMap<>());
}
return testsLogMap.get();
}
private static String throwableToString(Throwable t) {
StringBuilder builder = new StringBuilder();
for (StackTraceElement traceElement : t.getStackTrace()) {
builder.append(traceElement.toString()).append('\n');
}
return builder.toString();
}
private static String handleFormatMsg(String message, Object... args) {
if (args.length == 0 && message.contains("%")) {
message = message.replaceAll("%", "%%");
}
return String.format(message, args);
}
}
这是我的基本测试类:
@Listeners({NeoTestListener.class})
public class BaseTest {
private static final Browser BROWSER = Browser.valueOf(EnvConf.getProperty("ui.browser.type"));
private static final File SCREENSHOTS_FOLDER = new File(EnvConf.getProperty("test_output.screenshots.folder"));
// private static final File DOWNLOADS_FOLDER = new File(EnvConf.getProperty("workspace.tests.downloads"));
private static final File DOWNLOADS_FOLDER = new File(EnvConf.getProperty("test_output.logs.folder"));
private static final String ADMIN_USERNAME = EnvConf.getProperty("hackeruso.admin.user.email");
private static final String ADMIN_PASSWORD = EnvConf.getProperty("hackeruso.admin.user.password");
protected static DriverWrapper driver;
protected LoginPage loginPage;
protected Date testStartTime;
protected ITestContext context;
protected TopBar topBar;
protected final File testTempFolder;
static {
if (!SCREENSHOTS_FOLDER.exists()) {
FileUtil.createFolder(SCREENSHOTS_FOLDER, true);
}
if(!DOWNLOADS_FOLDER.exists()) {
FileUtil.createFolder(DOWNLOADS_FOLDER, false);
}
}
protected static String randSuffix(String prefix){
return prefix + "_" + String.valueOf(System.nanoTime()).substring(9);
}
public BaseTest() {
this.testTempFolder = new File(DOWNLOADS_FOLDER, randSuffix(getClass().getSimpleName()));
FileUtil.createFolder(testTempFolder, false);
// testTempFolder.deleteOnExit();
}
@BeforeClass
public final void baseSetup(ITestContext context) throws IOException {
this.context = context;
driver = DriverWrapper.open(BROWSER, DOWNLOADS_FOLDER);
loginPage = new LoginPage(driver);
info("<!!! '%s' START !!!>" , context.getName());
testStartTime = new Date();
this.context.setAttribute("test_start_time", testStartTime);
info("testStartTime=[%s]" , testStartTime);
}
private void printBrowserLog() {
List<LogEntry> serverLogLines = driver.manage().logs().get(LogType.BROWSER).getAll();
if (serverLogLines.size() > 0) {
Log.i("<---------Browser [SERVER] log start--------->");
for (LogEntry entry : serverLogLines) {
Log.e(entry.toString());
}
Log.i("<---------Browser [SERVER] log end------------>");
}
}
@AfterClass
public final void baseTeardown(ITestContext context) {
Date testEndTime = new Date();
if (driver != null) {
printBrowserLog();
driver.quit();
}
info("<!!! '%s' END !!!>" , context.getName());
info("testEndTime=[%s]" , testEndTime);
}
public static DriverWrapper getDriver() {
return driver;
}
protected void info(String message , Object...args){
TESTS_LOG.info(context , message , args);
}
public void error(Throwable t , String messageFormat , Object...args) {
TESTS_LOG.error(context , t , messageFormat , args);
}
public void error(String messageFormat , Object...args) {
TESTS_LOG.error(context , messageFormat , args);
}
protected void warn(String messageFormat , Object...args) {
TESTS_LOG.warn(context , messageFormat , args);
}
public void warn(Throwable t ,String messageFormat , Object...args) {
TESTS_LOG.warn(context , t , messageFormat , args);
}
protected void debug(String messageFormat , Object...args) {
TESTS_LOG.debug(context , messageFormat , args);
}
public void debug(Throwable t , String messageFormat , Object...args) {
TESTS_LOG.debug(context , t , messageFormat , args);
}
}
这是我的听众:
public class NeoTestListener implements ITestListener {
private final File SCREENSHOTS_FOLDER = new File(EnvConf.getProperty("test_output.screenshots.folder"));
private static final SimpleDateFormat FOLDER_NAME_FORMAT = new SimpleDateFormat("dd_MM_HH_mm_ss");
private static final SimpleDateFormat LOG_NAME_FORMAT = new SimpleDateFormat("dd_MM_HH_mm_ss");
private static final File TESTS_LOGS_FOLDER = new File(EnvConf.getProperty("test_output.logs.folder"));
static {
if (!TESTS_LOGS_FOLDER.exists()) {
FileUtil.createFolder(TESTS_LOGS_FOLDER, true);
}
}
private static String getTestMethodName(ITestResult iTestResult){
return iTestResult.getMethod().getConstructorOrMethod().getName();
}
@Attachment
public byte[] saveFailureScreenShot(DriverWrapper driver){
return driver.getScreenshotAsByte();
}
@Attachment(value = "{0}", type = "text/plain")
public static String saveTextLog(String message){
return message;
}
@Override
public void onStart(ITestContext context) {
context.setAttribute("WebDriver", getDriver());
}
@Override
public void onFinish(ITestContext context) {
}
@Override
public void onTestStart(ITestResult result) {
TESTS_LOG.info(result.getName() +" " + result.getTestClass() );
// TESTS_LOG.info("[Test: " + getTestClassName(result.getTestContext())+ " Started]");
}
@Override
public void onTestSuccess(ITestResult result) {
}
@Override
public void onTestFailure(ITestResult result) {
TESTS_LOG.error(String.format("I am in onTestFailure method:=[%s] failed", getTestMethodName(result)));
Object testClass = result.getInstance();
DriverWrapper driver = getDriver();
takeScreenshot(getTestMethodName(result));
//Allure ScreenShot and SaveTestLog
TESTS_LOG.info(String.format("Screenshot for class=[%s], method=[%s]", getTestClassName(result.getTestContext()), getTestMethodName(result)));
saveFailureScreenShot(driver);
try {
saveLogTextFile(result);
} catch (IOException e) {
e.printStackTrace();
}
saveTextLog(getTestMethodName(result) + " failed and screenshot taken!");
}
@Attachment
private byte[] saveLogTextFile(ITestResult result) throws IOException {
return saveToLogFile(result.getTestContext());
}
@Override
public void onTestSkipped(ITestResult result) {
}
@Override
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
}
@Override
public void onTestFailedWithTimeout(ITestResult result) {
}
private void takeScreenshot(String filePrefix){
File dest = new File(SCREENSHOTS_FOLDER , filePrefix + "_" + FOLDER_NAME_FORMAT.format(new Date()) + ".png");
takeScreenshot(dest, getDriver());
}
private void takeScreenshot(File destFile, DriverWrapper driver){
File scrFile = driver.getScreenshotAsFile();
Path src = Paths.get(scrFile.toURI());
Path dest = Paths.get(destFile.toURI());
try {
Files.copy(src, dest , StandardCopyOption.REPLACE_EXISTING);
TESTS_LOG.info("[[ATTACHMENT|" + destFile.getAbsolutePath() + "]]");
} catch (IOException e) {
TESTS_LOG.error("Failed to save screen shot at file: " + destFile.getName());
TESTS_LOG.error(e.getMessage());
}
}
private byte[] saveToLogFile(ITestContext context) throws IOException {
File logFile = createLogFile(context);
boolean created = FileUtil.createNewFile(logFile);
if(created){
List<String> testLogLines = TESTS_LOG.getAndDeleteLogsByTest(context.getName());
if(testLogLines == null){
TESTS_LOG.error(context, "test=[%s] don't have any log lines!" , context.getName());
}else{
FileUtil.writeToFile(logFile.getAbsolutePath(), testLogLines);
}
}else{
TESTS_LOG.error(context, " failed to create test log file=[%s]", logFile.getAbsolutePath());
}
return FileUtils.readFileToByteArray(logFile);
}
private static File createLogFile(ITestContext context){
return new File(TESTS_LOGS_FOLDER, String.format("%s_%s.log",getTestClassName(context), LOG_NAME_FORMAT.format(context.getStartDate())));
}
private static String getTestClassName(ITestContext context){
return context.getAllTestMethods()[0].getInstance().getClass().getSimpleName();
}
}
这是我的环境中的类测试示例:
public class ForgotPasswordTest extends BaseTest {
private String verifyEmailURL = "";
private static final String AUTOMATION_EMAIL= EnvConf.getProperty("automation.email.user");
private static final String AUTOMATION_EMAIL_PASSWORD=EnvConf.getProperty("automation.email.password");
private static final String AUTOMATION_WEBAPP_USER = "AUTOMATION_TESTER";
private ResetPasswordPage rpp;
private final static String NEW_PASSWORD = "1Qaz2wsx3edc";
private final static String ENVIRONMENT_BASE_URL = EnvConf.getProperty("base.url");
@BeforeClass
public void setup() {
topBar = new TopBar(driver);
rpp = new ResetPasswordPage(driver);
}
@Test(priority = 1)
public void navigateToLoginPage(){
loginPage.navigateAndVerify();
}
@Test(priority=2)
public void sendChangePasswordInstructions() {
ForgotPasswordPage fpp = loginPage.clickAndVerifyForgotPasswordButtonAction();
fpp.sendForgotPasswordInstructions(AUTOMATION_EMAIL);
Assert.assertTrue(loginPage.getForgotMsgAlertText().contains("Thank You, An Email Has Been Send"));
info("Sending forget password instructions phase is successful!");
}
@Test(priority=3)
public void verifyEmail(){
verifyEmailURL = "";
String regex = "href=\"([^\"]*)" ;
String from = "<SOME_URL>";
String subject = getSubject();
String msg = MailHelper.getMessagesFromGmail( AUTOMATION_EMAIL, AUTOMATION_EMAIL_PASSWORD, from, subject, testStartTime);
Pattern linkPattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher pageMatcher = linkPattern.matcher(msg);
while (pageMatcher.find()) {
if (pageMatcher.group(1).contains("reset-password")) {
verifyEmailURL = pageMatcher.group(1);
verifyEmailURL = ENVIRONMENT_BASE_URL.concat("/").concat(verifyEmailURL.split("/")[3]);
info("Verify URL: " + verifyEmailURL);
}
}
info("Verifying email address is successful!");
}
@Test(priority = 4)
public void navigateToResetPasswordScreen(){
navigateTo(verifyEmailURL);
}
@Test(priority=5)
public void connectToUpdateNewPassword() {
rpp.changeNewPassword(NEW_PASSWORD);
info("Changing password is successful!");
}
@Test(priority=6)
public void verifyPasswordChanged() {
signIn(AUTOMATION_EMAIL, NEW_PASSWORD, true);
assertTrue(topBar.verifyExistenceTopBarNavigationItem(TopRightNavBarItem.SUPPORT));
info(String.format("Password for user=[%s] changed successfully", AUTOMATION_WEBAPP_USER));
}
private String getSubject(){
return "Reset Password";
}
}
每次我使用mvn clean test运行我的程序时,我都无法保存每个测试类的日志,它总是会保存上次运行的测试类和其他未按预期保存的日志文件。
缺少什么?我试图寻找解决方案,尝试了各种行动,但没有得到预期的结果。
Maven Surefire插件具有参数
>
println(): First test...
22:32:25.537 [main] INFO igb.so.so65465538.FirstTest - log.info(): First test...
igb。所以so65465538。第二个测试输出。txt
:
println(): Second test...
22:32:25.561 [main] INFO igb.so.so65465538.SecondTest - log.info(): Second test...
我正在构建一个网络项目,它使用Maven进行构建,并使用泽西进行RESTful API。我使用TestNG和泽西测试框架编写了单元测试,并在内存中运行它们,而不是在网络服务器上。 在我的测试中,我对MySQL数据库进行了JDBC调用,并得到了一些结果。当我使用TestNG for Eclipse插件从Eclipse内部运行时,测试运行良好。但是,当我尝试使用以下两个命令之一从Maven运行时: 或
问题内容: 我想使用Jenkins运行用TestNG框架编写的Selenium测试。 在jenkins job(Freestyle project)中配置的命令: 注意:对于,给定目录路径 当我运行作业(选项)时,它被Selenium的create session活动打中并给出错误。 注意: 同样的命令运行 成功地 从运行时 的命令行 。 控制台输出的错误日志: (jenkins) 以下是测试课程
我想使用Jenkins运行在TestNG框架中编写的Selenium测试。 jenkins作业(Freestyle项目)中配置的命令: 控制台输出的错误日志:(jenkins) 下面是测试类: 以下是: null
我正在从Eclipse迁移到Intellij理念。当我在Intellij理念中运行测试时,我得到了图像中显示的错误,但在Eclipse中没有。测试在Eclipse中运行良好。请告诉我如何解决这个问题。 这就是我运行测试的方式。我得到的错误是:
问题内容: 我们有一个weblogic批处理应用程序,它可以同时处理来自使用者的多个请求。我们使用log4j记录目的。现在,我们登录到单个日志文件以处理多个请求。调试给定请求的问题变得很麻烦,因为所有请求都将日志记录在一个文件中。 因此,计划是每个请求只有一个日志文件。使用者发送一个请求ID,必须对其进行处理。现在,实际上可能有多个使用者将请求ID发送到我们的应用程序。因此,问题是如何根据请求隔离