TestNG console output into log4j.log - java

I need to get output result (FAIL or SUCCESS) into log4j output.
Assert.assertTrue(availresponse);
Is there any way to add TestNG console output into log4j.log file?

I found a simple, easy and perfect way to log TestNG output into log4j.log file. But this can't be log Final Report Details into log4j (PASS or FAIL).
implements ITestListener
Then add unimplemented methods
public void onTestSuccess(ITestResult result) {
logger.info(result);
}
public void onTestFailure(ITestResult result) {
logger.info(result);
}
You can add log4j logger in the methods you need. Enjoy!

If you need that, you could use if .. else construct to do the logging.
if(null != availresponse) {
//log success message
} else {
//log failure message
}
Another way is to write a custom class implementing TestListenerAdapter. You can see full example code here.

Wrap the assert with a logger e.g.
log.info(Assert.assertNotNull(availresponse));
However this is a bit limited in terms of information. What I usually do is:
if(availresponse==null)
{
log.fatal("availresponse was null");
}
Assert.assertNotNull(availresponse);
I know it's a bit of a hassle, testing for the condition twice but it does allow you to tweak the output level of the logger and add any other information you think would be useful e.g. the variables which were used to determine the contents of availresponse.
Alternatively you could try getting the console output to appear in your log file in which case you'll need to add something like:
log4j.appender.stdout.Target=System.out
to your log4j properties file.

You can find test-output folder in your project PATH. index.html will show the Test output of Success or Fail.
If the testMethod() is Success, there will no any output result shows in index.html file. You can add Success message by using Reporter.log()
If testmethod() fail, automatically it will prints output in file.
NOTE : java.lang.AssertionError is an error that thrown to indicate that an assertion has failed.
If anyone know how TestNG inserting that error to the report, comment below.

Finally found the easiest way to log the Assert error in log4j
In catch block it should be Throwable, if it is Exception that will not work.
try {
Assert.assertTrue(hotel.getAmenitiesList().size() < 0, "Hotel Amenities Available!");
} catch (Throwable e) {
e.printStackTrace();
logger.error("FAILED: testRoomAmenities ", e);
Assert.fail();
When this implement that will not invoke as FAIL. It will show that scenario is PASSED. Therefore you should use Assert.fail() to make that is FAILED

Related

The console in Eclipse (Java) does not output things in the correct/chronological order

Why is the output not in the correct order for the following test code:
public static void main(String[] args) {
boolean test = false;
try {
assert test: "will fail with -ea enabled in VM args" ;
} catch (AssertionError e) {
e.printStackTrace();
System.out.println("idk why you would use this but...");
}
System.out.println(test + " sneaks in between");
}
run this with "-ea" enabled in the VM arguments (run config)
randomly the output is either:
java.lang.AssertionError: will fail with -ea enabled in VM args
at Main.main(Main.java:31)
FOO
BAR
(should happen) or:
java.lang.AssertionError: ERROR
FOO
BAR
at Main.main(Main.java:31)
(should not happen) and sometimes:
java.lang.AssertionError: ERROR
FOO
at Main.main(Main.java:31)
BAR
I was messing around with "assert" when this happened. I know the code is complete nonsense but it may also happen with other setups.
Seconldy consoles are not really used too much in many programs as an official thing, mostly for debugging. But it is still weird.
Is this because the try catch is running on a different thread? or is the stuff happening so fast after eachother that one thing pushes out before the other thing?
I do notice adding a Thread.sleep(1); (which needs to be thrown or caught)
does make it always go in chronological order, so...
Why does it not print the code in chronological order?
printStackTrace() prints to the error out. How that chronologically lines up with the standard out is indeterminate. You can try calling flush() on System.out, but I can't assure you the result will ever be as you expect unless you specifically print the stack trace to standard out using one of the other available methods.

How do I save Java log messages to a file like my Rails log messages?

I use JRuby and have a Rake task that calls a Java function. This Rake task uses ActiveSupport::Logger to log messages.
log = ActiveSupport::Logger.new('log/my_log.log')
log.info 'A message for the ruby logger'
Later I call a Java function.
obj = JavaThing.new
results = obj.callJavaFunction
The callJavaFunction() method then does some logging of its own.
public class JavaThing {
private static final Logger log = Logger.getLogger('com.stuff.thing');
public void callJavaFunction() {
// do stuff
log.info('A message for the Java logger');
}
}
'A message for the ruby logger' is output to my_log.log.
'INFO: A message for the Java logger' is output to the console when I run the Rake task.
I cannot modify the Java code. How do I save the message that comes from the Java function to a file?
I've tried rake my:task > java_log.log but this only catches console output generated by Rails.
I am using JRuby 1.7.16 and Rails 4.1.4.
I'm unsure if there will be any effect on my code due to the fact that Ruby is involved (no experience in that), but you could give the following a try. Do note that I originally wrote it as part of a JUnit test for logging (with #Before), so you will need to do some adjustments to work for your case.
Basically, what it is doing is to also direct the logging to the txt file (Logging.txt in this case) from the console. It will still print to the console.
private final static Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
public void loggerSetup() {
try {
fileTxt = new FileHandler("Logging.txt");
} catch (SecurityException | IOException e) {
logger.warning("Filehandler not functional");
}
logger.addHandler(fileTxt);
SimpleFormatter formatterTxt = new SimpleFormatter();
fileTxt.setFormatter(formatterTxt);
}
If you want to remove the console printing as well, something similar to the below might work. All of the logging will then be saved in the file only, as the console printing is overwritten and sent to the file.
Logger rootLogger = Logger.getLogger("");
Handler[] handlers = rootLogger.getHandlers();
if (handlers[0] instanceof ConsoleHandler) {
rootLogger.removeHandler(handlers[0]);
}

why it is not recommended to use e.printstacktrace() by sonar?

i recently started using sonar as code review tool.
When i analysed my code running sonar,
it reflected printing stack trace as violation of java coding standard.
As an alternative to stack trace, I tried:
e.getcause()
but this did not clear the exception as done by stack trace
Error handling can be tricky in any environment, java included. I haven't used sonar, but I can comment on general good practices for java error handling.
e.printStackTrace() is generally discouraged because it just prints out the stack trace to standard error. Because of this you can't really control where this output goes.
The better thing to do is to use a logging framework (logback, slf4j, java.util.logging, log4j, etc) because then you can control where the errors are logged to and what the log retention policy is.
And generally you'll want to catch the exception and if it's unexpected behavior, log it and either throw a new exception (probably specific to your application) or do whatever you have to do to continue operating gracefully.
If you're using java.util.logging, you can do something like the following:
class YourClass
{
Logger logger = Logger.getLogger(YourClass.class.getName());
...
public void someMethod() throws YourException
{
try
{
// your code here
} catch (NullPointerException e)
{
String message = "Unexpected NullPointerException in processing!";
logger.log(Level.ERROR, message, e);
throw new YourException(message, e);
}
}
}
Hope this helps!
A few thoughts:
I presume from the title you were using e.printStackTrace(). This does not "clear the exception", so I'm not sure exactly what your issue really is on that point. In java "clear the exception" doesn't make any sense at all in this context.
e.printStackTrace() is "not a good idea" because it writes to standard out. Much better to write such detail to a log file for later diagnostics, rather than put it out in front of a user (though that could depend on how the program actually runs). Your run-time environment may have something to say about use of standard output.
e.getCause() will return, if available, an "underlying exception" that may have been a "root cause" for the exception e. Must stack traces will show this after an initial stack dump denoted by "Caused by: : ..."
If you choose to try to capture and display/log an exception yourself - you might use e.printStackTrace(PrintStream s) or e.printStackTrace(PrintWriter s).
You'd be best served using a logging tool, as suggested by Matt.

How to keep sysout and syserr streams from intermixing?

In my code base is the (very simplified) following:
public static void main (String[] args) {
System.out.println("Starting application");
try {
System.out.println("About to validate");
validate(args);
catch (Exception e) {
e.printStackTrace();
}
}
public static void validate(String[] args) {
System.out.println("Your first arg is " + args[0]);
if (someProblemWith(args)) {
System.out.println("Your args are wrong. It should be: ...");
throw new BadArgsException(e);
}
}
Which works fine. Note that my example code above is contrived and simply meant to show multiple log statements prior to exception and stack trace printing. This often means that my last logging statement is lost in the middle of the stack trace output. Is there an elegant way to ask the e.printStackTrace() statement to wait until the System.out has finished its work? I'm essentially looking for the stacktrace to be the very last thing printed when an error occurs. Here's a sample output of my program above:
java.lang.Throwable
....
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
Your args are wrong. It should be: ...
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56)
The reason you are seeing the stack trace being printed between the System.out.println() statements, is because System.out is buffered, while System.err (used by stack trace) is unbuffered.
If you want the text to be displayed in the exact order in which things are happening, you need to "unbuffer" the System.out. The simplest way is to also just use System.err there instead of System.out.
Otherwise, call System.out.flush() before your stack traces happen in the catch clauses.
Option 2: Use the Logger class.
Option 3: Implement your own "buffer". In other words, first write everything to your own buffer, including the stack traces (using .toString() or however you wish) and then in the catch flushing you own buffer. (This is kind of redundant since you can just flush the System.out anyway).
-==-
FROM COMMENT
Sure. The Logger class can be used to create a much more robust and detailed logging experience. This is typically what is done in applications. An instance of the Logger class is grabbed from the Logger class (it is a singleton), taking as parameter the class from which is will be used. Then you log messages to it by using the .log() method. The nice thing about the Logger class is that you can set levels on it (example DEBUG, WARN...) and you are then able to filter / display only what you want. The "log" messages are then displayed in a uniform way in the console, typically in the format of:
2010-11-23 14:45:32,032 DEBUG [MyClass] Your message
The above format is from log4j, but you can use the standard Java Logger. The output should be similar, maybe a bit less. But I'm sure it can be configured.
Call e.printStackTrace(System.out);. Or, if you need it for debugging only, you can separate the process' output and error from the command line: .... 1>output.log 2>error.log

Stop ArrayOutOfBoundsException from halting program execution in Java

Im am currently developing an automated "test" class (running several individual tests on other classes in the same package). The aim of the test file is to show whether each test either passed or failed. Some of the files being tested are not written correctly creating an ArrayOutOfBoundsException when running the test, that produces my test file to crash and not carry on until the end performing other tests. I am not in the position to modify code to fix the errors on the project being tested.
-> how to stop an exception from halting program execution in Java without creating any new classes
Thank for all your help, advice and sharing.
Best way to stop it happening: fix the code to perform appropriate checking.
If you can't fix the code which is actually failing, you could catch the exception explicitly at an "outer" level, log a warning and continue with the next file:
try
{
operationWhichMightThrow();
}
catch (ArrayIndexOutOfBoundsException e)
{
log.warning("Failed file " + filename, e);
// Do whatever you need to continue to the next file.
}
Catch the exception and log it as a test failure.

Categories

Resources