I found some solution to rerun failed #Test in this forum at How to Re-run failed JUnit tests immediately?. In my case i execute the test from command line. And i want to rerun the complete test if it fails. Given below is my Test Script template and i want to rerun everything (from start to end) if it fails
#BeforeClass
public static void Start(){
...
}
#Test
public void Test_One(){
...
}
#Test
public void Test_Two(){
...
}
#AfterClass
public static void End(){
...
}
I will get to know in End() method if my test script has failed. If it fails, i would like to run everything like
#BeforeClass
#Test (all #Test)
#AfterClass
Is it possible with JUnit?
I am not sure if the template that i am using is correct :(
JanakiL,
It is a very good question. I tried to find some solution but i didn't manage to find clean solution for this task.
I can only propose to do some workaround that eventually will work.
So, in order to re-run suite you need to do following steps:
You need to create #ClassRule in order to execute whole suite.
All Suite you can retry using following code:
public class Retrier implements TestRule{
private int retryCount;
private int failedAttempt = 0;
#Override
public Statement apply(final Statement base,
final Description description) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
base.evaluate();
while (retryNeeded()){
log.error( description.getDisplayName() + " failed");
failedAttempt++;
}
}
}
retryNeeded() – method that determines whether you need to do retry or not
This will retry all tests in your suite. Very important thing that retry will go after #AfterClass method.
In case you need to have “green build” after successful retry you need to write a bunch of another gloomy code.
You need to create #Rule that will not allow “publish” failed result. As example:
public class FailedRule extends TestWatcher {
#Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
List<Throwable> errors = new ArrayList<Throwable>();
try {
base.evaluate();
} catch (AssumptionViolatedException e) {
log.error("", e.getMessage());
if (isLastRun()) {
throw e;
}
} catch (Throwable t) {
log.error("", t.getMessage());
if (isLastRun()) {
throw t;
}
}
};
};
}
}
isLastRun() – methods to verify whether it is last run and fail test only in case ir is last run.
Only last retry needs to be published to mark you test failed and build “red”.
3. And finally in your test class you need do register two rules:
#Rule
public FailedRule ruleExample = new FailedRule ();
#ClassRule
public static Retrier retrier = new Retrier (3);
In the Retrier you can pass count of attempts to retry.
I hope that somebody could suggest better solution !
More flexible solution is to write custom runner.
I described this answer in the following post:
How to Re-run failed JUnit tests immediately?
Using Eclipse, in the Junit view, you have a button "ReRun Tests - Failures First"
You can also see this answer: How to Re-run failed JUnit tests immediately?
Related
I have the following code in my performFinish() method of my Wizard Class :
public boolean performFinish() {
try {
getContainer().run(true, false, changeArtifactRunnable());
}
catch (InvocationTargetException | InterruptedException e) {
LoggerClass.logException(e);
}
I want to test Exception for InvocationTargetException and InterruptedException using Mockito.
In the above code, getContainer() method is from org.eclipse.jface.wizard.Wizard class and
public void run(boolean fork, boolean cancelable,
IRunnableWithProgress runnable) throws InvocationTargetException,
InterruptedException;
method is from org.eclipse.jface.operation.IRunnableContext class.
How do I test both the exceptions in performFinish() method?
You can use the expected keyword in order to do so. For example:
#Test(expected = InvocationTargetException.class)
public void testInvocationTargetException() {
\\Invoke the method to be tested under the conditions, such that InvocationTargetException is thrown by it. No need of any assert statements
}
===========================================================================
Edit:
#RunWith(MockitoJUnitRunner.class)
public class EditArtifactWizardTest {
#Spy
//use correct constructor of EditArtifactWizard
private EditArtifactWizard editArtifactWizardSpy=Mockito.spy(new EditArtifactWizard ());
#Test(expected = InvocationTargetException.class)
public void testInvocationTargetException() {
\\Invoke the method to be tested under the conditions, such that InvocationTargetException is thrown by it. No need of any assert statements
Mockito.when(editArtifactWizardSpy.getContainer()).thenThrow(InvocationTargetException.class);
editArtifactWizardSpy.performFinish();
}
}
You can create the Spy of EditArtifactWizard class and mock the behavior of the getContainerMethod.
P.S: Please excuse for typos or compilation error as I am not using any editor.
When i use fail()[Junit] in the script, the scripts stops running and Skipped the next steps.
In TestNG, We can do that using "org.testng.Assert.fail("");" .
my requirement is to continue to run the next scenario even if my previous case was failure .
Please help me .
You need to use soft asssertions. Something like this
public static void verifyFalse(boolean condition) {
try {
assertFalse(condition);
} catch(Throwable e) {
e.printStackTrace();
throw new YourException("your message");
}
JUnit has the ErrorCollector rule for soft assertions.
public class ATest {
#Rule
public final ErrorCollector collector = new ErrorCollector();
#Test
public void test() {
//do some stuff
collector.addError(new Throwable("something went wrong"));
//do other stuff
}
}
I'm recently digging into the source code of JUnit-4.11, what confuse me is that the seemingly redundant Protectable interface. the declaration is as follows:
public interface Protectable {
public abstract void protect() throws Throwable;
}
In the TestResult class, there is a void run(final TestCase test) method, in which a anonymous Protectable instance is realized as follows:
protected void run(final TestCase test) {
startTest(test);
Protectable p = new Protectable() {
public void protect() throws Throwable {
test.runBare();
}
};
runProtected(test, p);
endTest(test);
}
runProtected method is as follows:
public void runProtected(final Test test, Protectable p) {
try {
p.protect();
} catch (AssertionFailedError e) {
addFailure(test, e);
} catch (ThreadDeath e) { // don't catch ThreadDeath by accident
throw e;
} catch (Throwable e) {
addError(test, e);
}
}
As we can see, what runProtected does is just executing test.runBare();, so is there any sense to the existence of Protectable interface? Why can't we just write code like below.
protected void run(final TestCase test) {
startTest(test);
test.runBare();
endTest(test);
}
To answer your final question first, you can't use
protected void run(final TestCase test) {
startTest(test);
test.runBare();
endTest(test);
}
because it won't do what you want. JUnit manages asserts using exceptions, specifically AssertionFailedError. So, Assert.assertEquals() throws an AssertionFailedError when the two values aren't equal. So, in the above method, the endTest(test) won't get called if there is an assertion failure, which means the correct events (failure/error of the test) won't get fired, and tearDown() won't get executed.
The Protectable interface is there to give a more generic interface to the runner, so that you don't have to hand a TestCase to the method, to allow different actions.
As an aside, this is part of the package junit.framework.*, which is JUnit 3. JUnit 4 is where it's at, and if you want to learn, look more in the org.junit.* packages.
It seems to handle thrown exceptions in specific way :
Call addFailure for assertion exception (your test failed), addError for other exception (your test is not well coded)
This interface is to protect the TestCase by adding Throwable.
so junit could run any testcase safely.
The Throwable class is the superclass of all errors and exceptions in the Java language.
I need to integrate DbUnit with TestNG.
1) Is it possible to use DbUnit with TestNG as DbUnit is basically an extension of JUnit.
2) If yes how?
Finally i found out a way to use DbUnit with TestNG!
Using Instance of IDatabaseTester works,
but another work around would be :
To extend AbstractDatabaseTester and implement getConnection and override necessary functions.
But one important thing is to call onSetup() and onTeardown() before and after testing.
Hope this helps...
Not sure what you are trying to do exactly, but perhaps Unitils would be helpful. It is like a dbunit extension but not limited to that, and supports integration with TestNg (by extending UnitilsTestNG class for your testcase).
Here is simple class that performs the required function.
public class SampleDBUnitTest {
IDatabaseTester databaseTester;
IDataSet dataSet;
#BeforeMethod
public void setUp() throws Exception {
// These could come as parematers from TestNG
final String driverClass = "org.postgresql.Driver";
final String databaseUrl = "jdbc:postgresql://localhost:5432/database";
final String username = "username";
final String password = "password";
dataSet = new FlatXmlDataSet(Thread.currentThread().getContextClassLoader().getResourceAsStream("dataset.xml"));
databaseTester = new JdbcDatabaseTester(driverClass, databaseUrl, username, password);
databaseTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT);
databaseTester.setDataSet(dataSet);
databaseTester.setTearDownOperation(DatabaseOperation.NONE);
databaseTester.setDataSet(dataSet);
databaseTester.onSetup();
}
#AfterMethod
public void tearDown() throws Exception {
databaseTester.onTearDown();
}
#Test
public void t() throws Exception {
// Testing, testing
}
}
I am writing integration tests to test existing Routes. The recommended way of getting the response looks something like this (via Camel In Action section 6.4.1):
public class TestGetClaim extends CamelTestSupport {
#Produce(uri = "seda:getClaimListStart")
protected ProducerTemplate producer;
#Test
public void testNormalClient() {
NotifyBuilder notify = new NotifyBuilder(context).whenDone(1).create();
producer.sendBody(new ClientRequestBean("TESTCLIENT", "Y", "A"));
boolean matches = notify.matches(5, TimeUnit.SECONDS);
assertTrue(matches);
BrowsableEndpoint be = context.getEndpoint("seda:getClaimListResponse", BrowsableEndpoint.class);
List<Exchange> list = be.getExchanges();
assertEquals(1, list.size());
System.out.println("***RESPONSE is type "+list.get(0).getIn().getBody().getClass().getName());
}
}
The test runs but I get nothing back. The assertTrue(matches) fails after the 5 second timeout.
If I rewrite the test to look like this I get a response:
#Test
public void testNormalClient() {
producer.sendBody(new ClientRequestBean("TESTCLIENT", "Y", "A"));
Object resp = context.createConsumerTemplate().receiveBody("seda:getClaimListResponse");
System.out.println("***RESPONSE is type "+resp.getClass().getName());
}
The documentation is a little light around this so can anyone tell me what I am doing wrong with the first approach? Is there anything wrong with following the second approach instead?
Thanks.
UPDATE
I have broken this down and it looks like the problem is with the mix of seda as the start endpoint in combination with the use of a recipientList in the Route. I've also changed the construction of the NotifyBuilder (I had the wrong endpoint specified).
If I change the start endpoint to
direct instead of seda then the test will work; or
If I comment out the recipientList
then the test will work.
Here's a stripped down version of my Route that reproduces this issue:
public class TestRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
// from("direct:start") //works
from("seda:start") //doesn't work
.recipientList(simple("exec:GetClaimList.bat?useStderrOnEmptyStdout=true&args=${body.client}"))
.to("seda:finish");
}
}
Note that if I change the source code of the NotifyTest from the "Camel In Action" source to have a route builder like this then it also fails.
Try to use "seda:getClaimListResponse" in the getEndpoint to be sure the endpoint uri is 100% correct
FWIW: It appears that notifyBuilder in conjunction with seda queues are not quite working: a test class to illustrate:
public class NotifyBuilderTest extends CamelTestSupport {
// Try these out!
// String inputURI = "seda:foo"; // Fails
// String inputURI = "direct:foo"; // Passes
#Test
public void testNotifyBuilder() {
NotifyBuilder b = new NotifyBuilder(context).from(inputURI)
.whenExactlyCompleted(1).create();
assertFalse( b.matches() );
template.sendBody(inputURI, "Test");
assertTrue( b.matches() );
b.reset();
assertFalse( b.matches() );
template.sendBody(inputURI, "Test2");
assertTrue( b.matches() );
}
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from(inputURI).to("mock:foo");
}
};
}
}