I want to achieve writing to log file with Log4j.
I have found one easy solution - surround test body with try - catch:
#Test(groups = "GMAIL_PAGE")
public void testAllMailLink() {
try {
List<WebElement> allMessages = page.takeAllMessage();
page.clickInboxLink();
List<WebElement> inboxMessages = page.takeInboxMessage();
page.clickDraftLink();
List<WebElement> draftMessages = page.takeDraftMessage();
Assert.assertTrue(allMessages.containsAll(inboxMessages),
"All messages doesn't contains all inbox messages");
Assert.assertTrue(allMessages.containsAll(draftMessages),
"All messages doesn't contains all draft messages");
log.info("test is passed");
} catch (Exception e) {
log.error(e);
}
}
But it has some drawbacks - this test is always passed, even if it fails.
It is ok if I work on my machine and able to see console. But what to do when this test is pushed to Continuous Integration server?
Does exist any other way to write info into log file, when test fail?
Add Assert.fail() below your log.error(e):
catch (Exception e) {
log.error(e);
Assert.fail();
}
By the way, you're calling Logger#error(Object), which uses e.toString(). In this case, it is better to use a descriptive message and then pass the exception to get the respective stacktrace:
catch (Exception e) {
log.error("Some descriptive message should go here.", e);
Assert.fail("Some descriptive message should go here as well.");
}
Related
I'm working on a SpringBootApplication. In this app I have 4 micro-services using Feign to communicate between eachothers. In a Controller I have a piece of code like this below, to catch exceptions and return it to the view, in case something is wrong.
try {
patientDTO = patientProxyFeign.getPatientById(id);
noteDTOList = historyProxyFeign.getAll(id);
assessmentDTO = assessmentProxyFeign.getPatientAssessment(id);
} catch (Exception e) {
log.error("" + e.getMessage());
model.addAttribute("errorMsg", e.toString());
return "error/error";
}
If there is an exception I got a message like this to the view :
feign.FeignException$NotFound: [404] during [GET] to [http://localhost:8081/patient/12000] [PatientProxyFeign#getPatientById(Integer)]: [{"timestamp":"2021-12-16T16:21:27.790+00:00","status":404,"error":"Not Found","path":"/patient/12000"}]
What I want to do, is to get only the status code and the message "not found".
Is someone got an idea how to do it ? (Search on google, but seems to be too specific. I probably don't use the right keywords.)
You can get the status by calling e.status() and then you can switch-case the status and get a message based on that. You could also build a Map of <Integer, String> and get the message by status. To read about FeignException more kindly visit https://github.com/OpenFeign/feign/blob/master/core/src/main/java/feign/FeignException.java
And it is strongly advisable to be specific about what you catch:
} catch (FeignException e) {
I am trying to continuously poll an NFC tag using an android phone (OnePlus 6T if it's relevant). When my tag is only powered by NFC, I get null values even though the debugger shows the payload being not null and supposedly correctly formatted (screenshot below).
Debugger output when getNdefMessage returns null
Debugger output when the returned value is not null
The code I am using to poll the tag, based on Continuously detect an NFC tag on Android and Is it possible to read an NFC tag from a card without using an intent?
protected void onResume() {
super.onResume();
if (nfcAdapter != null) {
if (!nfcAdapter.isEnabled()) {
Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
startActivity(intent);
}
Bundle options = new Bundle();
options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 250);
nfcAdapter.enableReaderMode(this, new NfcAdapter.ReaderCallback() {
#Override
public void onTagDiscovered(Tag tag) {
Log.d("Tag", "New tag detected, attempting connect");
readMessage(tag);
tagInRange = true;
}
},
NfcAdapter.FLAG_READER_NFC_A
| NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS, options);
}
}
Read message function, msg variable is a private volatile NdefMessage:
private void readMessage(Tag tag) {
Log.d("Tag", "Starting thread");
new Thread(() -> {
try {
Thread.sleep(1800);
} catch (InterruptedException e) {
e.printStackTrace();
}
final Ndef ndef = Ndef.get(tag);
Log.d("Tag", "New tag detected, attempting connect");
while (tagInRange) {
try {
ndef.connect();
msg = ndef.getNdefMessage();
Log.d("Tag", "Running on UI thread");
if (msg == null) {
Log.d("Tag", String.valueOf(ndef));
continue;
}
runOnUiThread(() -> {
parseMessage(msg);
dataElapsedTime += 0.2;
});
} catch (IOException | FormatException e) {
e.printStackTrace();
tagInRange = false;
System.out.println("Tag Connection Lost");
}
finally {
try {
ndef.close();
Log.d("tag", "Tag connection closed successfully");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
Does the getNdefMessage function use some sort of lazy loading? Or is this the result of multiple threads being spawned and some strange race condition occurring?
Update 2
Looking at the source of the ndef object the mNdefMsg you highlighted is the cached Ndef message that the System Reads before passing you the Tag object
As you seem have a custom behaving tag and may be this tag won't allow you to read the same data twice without going through a disconnect/connect mechanism.
Based on you debug data I would use ndef.getCachedNdefMessage() to read this data you are highlighting but this might not get you want you want.
Some Background, when the Android NFC service detects a Tag normally it tries to read and Ndef message from it as it might need to parse the Ndef message itself.
When you call ndef.getNdefMessage() it actually re-reads the data directly from the Tag and ignores what the System NFC service has previous read.
I would try enabling FLAG_READER_SKIP_NDEF_CHECK to stop the system reading the Ndef Message and using up you one chance to read the custom Tag .
So try add that flag e.g.
nfcAdapter.enableReaderMode(this, new NfcAdapter.ReaderCallback() {
#Override
public void onTagDiscovered(Tag tag) {
Log.d("Tag", "New tag detected, attempting connect");
readMessage(tag);
tagInRange = true;
}
},
NfcAdapter.FLAG_READER_NFC_A
| NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK
| NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS, options);
Original
I think the problem is your ndef.close() is in the wrong place.
You should not close the tag unless you never want to communicate with it again.
At the moment on the first iteration of the while loop, it does the try block with the ndef.connect(); and the finally is always executed after the code in the preceding try block.
Really you should only ndef.close() outside the while block.
Adjusted code (You should also catch the TagLostException from getNdefMessage )
private void readMessage(Tag tag) {
Log.d("Tag", "Starting thread");
new Thread(() -> {
try {
Thread.sleep(1800);
} catch (InterruptedException e) {
e.printStackTrace();
}
final Ndef ndef = Ndef.get(tag);
Log.d("Tag", "New tag detected, attempting connect");
try {
ndef.connect();
} catch (IOException e) {
e.printStackTrace();
tagInRange = false;
System.out.println("Failed to Connect");
}
while (tagInRange) {
try {
msg = ndef.getNdefMessage();
Log.d("Tag", "Running on UI thread");
if (msg == null) {
Log.d("Tag", String.valueOf(ndef));
continue;
}
runOnUiThread(() -> {
parseMessage(msg);
dataElapsedTime += 0.2;
});
} catch (TagLostException | IOException | FormatException e) {
e.printStackTrace();
tagInRange = false;
System.out.println("Tag Connection Lost");
}
}
// End of while loop try close just on the safe side
try {
ndef.close();
Log.d("tag", "Tag connection closed successfully");
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
Note you might think the raw tag debug output still has an Ndef Message in it, but as you have not disabled FLAG_READER_SKIP_NDEF_CHECK then this is probably the cached data for ndef.getCachedNdefMessage()
If you look at the docs for ndef.getCachedNdefMessage you will see that it says that it causes no RF activity as this just returns the NDEF message that the System NFC read when it first detected the Tag and passed to you in the Tag Object.
Where as getNdefMessage cause I/O (RF) activity and reads the current Ndef message at time of calling (which might be different to the one the system read previously)
Update
I seem to remember you cannot call connect() multiple times and and the docs say "Only one TagTechnology object can be connected to a Tag at a time. " even though it is the same Tag tech it is probably not the same instance, so in the example I've moved connect out of the while loop.
This issue was finally resolved by understanding the following things:
The mNdefmessage variable in the ndef object corresponds to the cached message and would remain unchanged as long as the same tag instance is connected. I was reading the object wrong and presuming that that is the message I want. Thanks to Andrew for pointing this out!
The null I was receiving was not a result of where the connect/close were called and the android code needed minimal changes from what was initially posted. In the documentation for the function getNdefMessage(), it says, function may return null if tag is initialised stage. This turned out to be the real issue, which was only spotted when I set my tag (NHS3152) to blink an LED when starting up and noticed it was restarting several times after taking a set of readings from a connected resistor which shouldn't be happening (this also led to a lot of tag lost/null object exceptions).
Since the documentation on this is scanty, the reason the tag was restarting/reset turned out to be its inability to handle voltages over a certain threshold on its output pins when powered by the NFC field only and connected to a load. This led to the strange scenario of everything working just fine when the tag was being read while connected to a debugging board (LPCLink2) or being powered by the NFC but not connected to a load. This was finally addressed by changing the output voltage on the DAC pin.
I have the following function:
public class NorthboundApiLogicTest {
#Test
public void testIfParametersValuesAreCorrect() {
String body = "{\"exception\":\"world\",\"error\":\"Not Found\",\"message\":\"hello\""
+ ",\"timestamp\":\"2020-01-07T12:26:48.334386Z\",\"status\":\"404\"}";
try {
JSONAssert.assertEquals("{message:hello, exception:world, status:403, error:Not Found}",
body, false);
} catch (Exception e) {
System.err.println(e);
}
System.out.println(body);
}
}
I run this test with Maven, and strangely it pass successfully.
However, it should not, because I assert that status=403 but the value is 404. What am I doing wrong?
It's failing to parse the JSON before it even performs an assertion on the structure, and you're simply logging that via your catch.
catch (Exception e) {
System.err.println(e);
}
You need to let that exception be thrown from the method, or catch it and call fail() with an appropriate message.
And then fix the issue of your non-parseable JSON, of course!
Am working on selenium Automation
I want to know the name of which elements is not found when test cases got failed instead of getting object not found with property By.id("Login")
am expecting output like Object not found LoginButton(Customized name which i will give in code) when test cases fails due to defect
public static void logonCustomerPortal() throws Exception{
Thread.sleep(5000);
driver.findElement(By.xpath("//a[#id='nav_login']/span")).click();
Thread.sleep(2000);
}
I am new to Automation. Can anyone please help me ?
try to use try catch like this :
public void urmethod(){
try {
//do your code
}catch (Exception e){
e.printStackTrace();
}
}
this will print details of your error, in other words, what kind of error, in which line it fails...etc
How can I retrieve a compile time error message from StringTemplate as a String?
This code for instance:
STGroup stg = new STGroup('<', '>');
CompiledST compiledTemplate = stg.defineTemplate("receipt", "<an invalid template<>");
if (compiledTemplate == null)
System.out.println("Template is invalid");
Will simply log something like "invalid came as a complete surprise to me", but I want to display this error message in my UI.
I can access the ErrorManager with stg.errMgr. I expected a method like getErrors() here, but there isn't...
You could set an error listener for the group, which would allow you to catch the error, and then pass it to the UI from there.
This answer tells you more about implementing an STErrorListener. The example they give doesn't compile since they're throwing checked exceptions from within the ErrorListener. Perhaps a better approach would be to handle the errors directly inside the listener, or you could just throw a RuntimeException so you could catch the errors when you call stg.defineTemplate(...).
public class MySTErrorListener implements STErrorListener {
...
#Override
public void compileTimeError(STMessage msg) {
// do something useful here, or throw new RuntimeException(msg.toString())
}
...
}
If you were to throw the RuntimeException you could then catch it when you define the ST:
stg.setListener(new MySTErrorListener());
try{
CompiledST compiledTemplate = stg.defineTemplate("receipt", "<an invalid template<>");
} catch (Exception e)
{
// tell the UI about the error
}