testNG: sending report via mail within the #AfterSuite section - email

I'd like to send the report generated by testNG ( java+eclipse+testNG) within the #AfterSuite section.
It's not a problem to send it, but the point is that the report is generated after the #AfterSuite section, so , basically, i send the previous one instead of the last one !
Any idea about how can I solve it ?

As you are seeing, #AfterSuite runs before the report is generated.
Have you though about implementing a TestNG IReporter listener ?
public class MyReporter implements IReporter {
#Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> iSuites, String s) {
//Create your bespoke results
//Email results
}
}
Obviously you can see a flaw in that you have to generate your own results from the raw results data (which may be advantageous if you just want to email a subset of data).
The ideal solution would to be able to extend the default report generator, but I am not sure this can be done. However there is an existing listener provided by http://reportng.uncommons.org/, which actually provides a much nicer report output.
If you extend this this class, and call their code, and then add email generator code afterwards, it may work
public class MyReporter extends HTMLReporter {
#Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> iSuites, String s) {
super.generateReport(xmlSuites, iSuites, s);
//Email results
}
}
You can attach a listener to a test suite in several ways, as explained on the TEstNG website (http://testng.org/doc/documentation-main.html#listeners-testng-xml)
An alternative to all of this woudl be to use a build tool like Maven to run your tests, then have a post test event to email the results.

I copied the answer from Krishnan.
It works for me.
By the way, in my test environment, I need to extends the org.testng.reporters.EmailableReporter2 instead of EmailableReporter to make sure the correct count.
See below for your reference:
Krishnan Mahadevan Krishnan Mahadevan at Jul 31, 2012 at 8:58 am I am guessing that you are referring to the TestNG generated
"emailable-report.html" which you would want to mail.
With that assumption here's how you should be able to do it.
Extend org.testng.reporters.EmailableReporter
Override org.testng.reporters.EmailableReporter.generateReport(List,
List, String) and have it do something as below :
#Override
public void generateReport(List xml, List suites, String
outdir) {
super.generateReport(xml, suites, outdir);
SendFileEmail e= new SendFileEmail();
e.sendEmail();
}
Now add up this listener of yours into your suite file using
tag.

Related

Nunit Test Order - Single Test - Multiple Orders

For Nunit Test order, is it possible to have multiple order positions for a test, such as [Test, Order(3, 10, #...)]?
Scenario - I am automating a multi-page online application using end-to-end ordered tests (with Asserts verifying entered info), and I want to verify info on previous pages is still there - saved - when I click Back button (basically, reverse-check the end-to-end starting from last page of application using Back button to navigate). I want to reuse Asserts already there instead of rewriting the same ones again.
I have tried the following as an experiment, which generate build error CS1729 - 'type' does not contain a constructor that takes 'number' arguments:
[Test, Order(66, 67)]
**
[Test, Order(66)(67)]
**
[Test, Order(66), Order(67)]
**
[Test, Order(66)]
[Test, Order(67)]
I Googled this, and I don't see anything that does the above, so I assume it is not possible, but want to confirm. I cannot remove the Order attribute as that's part of the requirement for this test.
No, that's not possible. The OrderAttribute sets a property, which is a simple integer.
To simulate the effect you want, you may do the following:
Extract all the code of the test in question to a separate method, called by the test. It should have the same signature as the test.
Replicate the test you want to repeat, using a different name.
Assign a different order attribute to each test.
Assuming a signature of void TestMethod() it will look something like this...
[Test, Order(66)]
public void MyTest66()
{
MyRealTest();
}
[Test, Order(67)]
public void MyTest67()
{
MyRealTest();
}
private void MyRealTest()
{
// Your actual test code goes here
}
Note... this is a really ugly hack but the only guaranteed way I can think of to do what you indicate is required.

Changing jasper report parameters in runtime

I know, but we really need it.
We have a clear division of labor.
They create templates, I fill them in runtime according to some rules.
Can't teach my business to insert something like this and be sure they really did it ok(so can't move any logic to templates):
$P{risk_types}.get($F{risk_type}) ?: "UNDEFINED"
Also can not fill from files hardcoded in some adapter hadwritten by god-knows-who and unchangeable in runtime. It's a web app. Best option is to find a way to replace that file source from adapter to a ByteArrayStream.
SO:
Need to substitute contents of parameters(also default ones) at runtime.
example:
need to set JSON_INPUT_STREAM
Like this unsolved thread.
https://community.jaspersoft.com/questions/516611/changing-parameter-scriptlet
Really hope not to work on xml level, but xml also can't solve my problem as far as I tried.
Thank you!
The easiest and cleanest way we did this(bypassing usage of tons of deprecated documentation and unfinished bugged undocumented static antipatterned new features):
Create context with repository extension
SimpleJasperReportsContext jasperReportsContext = new SimpleJasperReportsContext();
jasperReportsContext.setExtensions(RepositoryService.class, Collections.singletonList(new MyRepositoryService(jasperReportsContext, yourOptionalParams)));
Fill this way(after compile and other usual actions)
JasperPrint print = JasperFillManager.getInstance(jasperReportsContext).fill(compiled, new HashMap<>());
Now your repository must extend default one to be hack-injected(cause of hodgie coded "isAssignableFrom") successfully
public class PrintFormsRepositoryService extends DefaultRepositoryService {
#Override
public InputStream getInputStream(RepositoryContext context, String uri) {
// return here your own good simple poj inputStream even from memory if you found source
// or pass to another repository service(default one probably)
return null;
}
}

Can we fetch selenium test result Passed or failed in selenium Ide or selenium RC using API

Actually I am executing my selenium test by reading test case data from excel.I wanted to fetch whether the test result is Passed or failed after execution of my first test case and write it in front of test case then y second test case and write it in front of test case and so on .
Before execution of my test case excelsheet screenshoot
http://i.stack.imgur.com/L2LNz.png
after execution of my test cases excelsheet screenshoot
http://i.stack.imgur.com/mMivW.png
You can fetch the results using TestNG. TestNG contains default listeners which reads if your test passed/failed/was skipped.
To set this data in excelsheet you need to create a class that implements from ITestListener
public class ExcelListener implements ITestListener
If you use any IDE, you should see a warning about need of creating unimplemented methods. Allow system to create them and you should see methods like
#Override
public void onTestSuccess(ITestResult result) {
// TODO Auto-generated method stub
}
Then all you have to code is
1. Open excel file
2. Find the right column
3. Insert status
To do that I recommend using Java Excel API.
To read existing excelsheet you need to provide absolute path, workbook name and a sheetname. Here's my code for method getExcel
public void getExcel(String filePath, String sheetName, String fileName) throws BiffException, IOException {
String absolutePath = filePath.concat("/").concat(fileName);
file = new FileInputStream(new File(absolutePath));
workbook = Workbook.getWorkbook(file);
worksheet = workbook.getSheet(sheetName);
}
After getting an excel file, you need to iterate through data.
You can provide exact column and row.
Hope it helps!
EDIT:
Place a listener like this
#Listeners(MyExcelListener.class)
public class MyTestClass {
}

How to write a custom Junit runner that will log results

I am working with JUnit and I have this idea which I want to implement.
I want to write a runner that will log the results of each test to an excel or a text file so that i can attach it in my reports.
What do i need to learn to get started
Two alternatives
Write a RunListener and use it like:
public void main(String... args) {
JUnitCore core= new JUnitCore();
core.addListener(new MyRunListener());
core.run(MyTestClass.class);
}
Write a RunListener again. But this time extend an org.junit.runner.Runner implementation and override its run method like
#Override
public void run(RunNotifier notifier) {
notifier.addListener(new MyRunNotifier());
super.run(notifier);
}
Second approach can also be used in tests with #RunWith(MyRunner.class) annotation.

NUnit extension

Hi All i have a question regarding NUnit Extension (2.5.10).
What i am trying to do is write some additional test info to the
database. For that i have created NUnit extension using Event
Listeners.
The problem i am experiencing is that public void
TestFinished(TestResult result) method is being called twice at
runtime. And my code which writes to the database is in this method
and that leaves me with duplicate entries in the database. The
question is: Is that the expected behaviour? Can i do something about
it?
The extension code is below. Thanks.
using System;
using NUnit.Core;
using NUnit.Core.Extensibility;
namespace NuinitExtension
{
[NUnitAddinAttribute(Type = ExtensionType.Core,
Name = "Database Addin",
Description = "Writes test results to the database.")]
public class MyNunitExtension : IAddin, EventListener
{
public bool Install(IExtensionHost host)
{
IExtensionPoint listeners = host.GetExtensionPoint("EventListeners");
if (listeners == null)
return false;
listeners.Install(this);
return true;
}
public void RunStarted(string name, int testCount){}
public void RunFinished(TestResult result){}
public void RunFinished(Exception exception){}
public void TestStarted(TestName testName){}
public void TestFinished(TestResult result)
{
// this is just sample data
SqlHelper.SqlConnectAndWRiteToDatabase("test", test",
2.0, DateTime.Now);
}
public void SuiteStarted(TestName testName){}
public void SuiteFinished(TestResult result){}
public void UnhandledException(Exception exception){}
public void TestOutput(TestOutput testOutput){}
}
}
I have managed to fix the issue by simply removing my extension
assembly from NUnit 2.5.10\bin\net-2.0\addins folder. At the moment
everything works as expected but i am not sure how. I thought that you
have to have the extension/addin assembly inside the addins folder.
I am running tests by opening a solution via NUnit.exe. My extension
project is part of the solution i am testing. I have also raised this issue with NUnit guys and got the following explanation:
Most likely, your addin was being loaded twice. In order to make it easier to test addins, NUnit searches each test assembly for addins to be loaded, in addition to searching the addins directory. Normally, when you are confident that your addin works, you should remove it from the test assembly and install it in the addins folder. This makes it available to all tests that are run using NUnit. OTOH, if you really only want the addin to apply for a certain project, then you can leave it in the test assembly and not install it as a permanent addin.
http://groups.google.com/group/nunit-discuss/browse_thread/thread/c9329129fd803cb2/47672f15e7cc05d1#47672f15e7cc05d1
Not sure this answer is strictly relevant but might be useful.
I was having a play around with the NUnit library recently to read NUnit tests in so they could easily be transfered over to our own in-house acceptance testing framework.
It turns out we probably wont stick with this but thought it might be useful to share my experiences figuring out how to use the NUnit code:
It is different in that it doesn't get run by the NUnit console or Gui Runner but just by our own console app.
public class NUnitTestReader
{
private TestHarness _testHarness;
public void AddTestsTo(TestHarness testHarness)
{
_testHarness = testHarness;
var package = new TestPackage(Assembly.GetExecutingAssembly().Location){AutoBinPath = true};
CoreExtensions.Host.InitializeService();
var testSuiteBuilder = new TestSuiteBuilder();
var suite = testSuiteBuilder.Build(package);
AddTestsFrom(suite);
}
private void AddTestsFrom(Test node)
{
if (!node.IsSuite)
AddTest(node);
else
{
foreach (Test test in node.Tests)
AddTestsFrom(test);
}
}
private void AddTest(Test node)
{
_testHarness.AddTest(new WrappedNUnitTest(node, TestFilter.Empty));
}
}
The above reads NUnit tests in from the current assembly wraps them up and then adds them to our inhouse test harness. I haven't included these classes but they're not really important to understanding how the NUnit code works.
The really useful bit of information here is the static to "InitialiseService" this took quite a bit of figuring out but is necessary to get the basic set of test readers loaded in NUnit. You need to be a bit careful when looking at the tests in NUnit aswell as it includes failing tests (which I assume dont work because of the number of statics involved) - so what looks like useful documentation is actually misleading.
Aside from that you can then run the tests by implementing EventListener. I was interested in getting a one to one mapping between our tests and NUnit tests so each test is run on it's own. To achieve this you just need to implement TestStarted and TestFinished to do logging:
public void TestStarted(TestName testName)
{
}
public void TestFinished(TestResult result)
{
string text;
if (result.IsFailure)
text = "Failure";
else if (result.IsError)
text = "Error";
else
return;
using (var block = CreateLogBlock(text))
{
LogFailureTo(block);
block.LogString(result.Message);
}
}
There are a couple of problems with this approach: Inherited Test base classes from other assemblies with SetUp methods that delegate to ones in the current assembly dont get called. It also has problems with TestFixtureSetup methods which are only called in NUnit when TestSuites are Run (as opposed to running test methods on their own).
These both seem to be problems with NUnit although if you dont want to construct wrapped tests individually I think you could just put in a call to suite.Run with the appropriate parameters and this will fix the latter problem