Repeating a JUnit3 test - junit

I am using Apache's Surefire JUnit plug-in for maven.
I would like to re-run a test suite in JUnit 3.x. This is possible easily in JUnit 4, which offers the 'Parameterized' annotation.
Do you know how I can do the same in JUnit 3.x?
My goal is to run the entire suite of tests twice so that two different test data can be seeded into all the tests.

In JUnit 3.x you can define your own test suite. If you add
public static Test suite()
method to yout JUnit class than JUnit will run all methods that are defined in the returned variable. You can look on JUnit and junit.framework.TestSuite - No runnable methods (to the question) or http://junit.org/apidocs/junit/framework/TestSuite.html
You can do also something like this:
public static Test suite() {
TestSuite suite = new TestSuite(YouTestClass.class);
suite.addTest(new TestSuite(YouTestClass.class)); //you want to run all twice
// suite.addTest(new YouTestClass("foo", 0);
// for (int i = 0; i < TEST_SETALL.length; i++) {
// suite.addTest(new YouTestClass("setAllTest",i ));
// }
Test setup = new TestSetup(suite) {
protected void setUp() throws Exception {
// do your one time set-up here!
}
protected void tearDown() throws Exception {
// do your one time tear down here!
}
};
return setup;
}

Related

Conditionally skip a Junit 5 test

In my Junit Jupiter API 5.5 test, I am calling my method which internally makes a HTTP call to a remote service.
Now the remote service can be down or behave incorrectly. I want to skip my test in case the remote service is not behaving expectedly.
#Test
void testMe() {
// do something
Result res1 = myObject.retrieveResults(params)
// assert something
Result res2 = myObject.retrieveResults(param2)
//asert on results
}
Result retrieveResults(Parameters param) {
// do something
// call to remote service
// if they do not give result throw CustomException()
// return Result
}
So basically in my test i would want to check if myObject.retrieveResult is throwing CustomException then skip that test, otherwise evaluate normally.
We have 2 different ways to accomplish this tasks in JUnit 5.
For demo purposes, I have created a basic class which sends a request to the url
that is passed as an argument to its call(String url) method and
returns true or false depending on the request result.
The body of the method is irrelevant here.
Using Assumptions.assumeTrue()/assumeFalse() methods
Assumptions class provides us with two overloaded methods - assumeTrue
and assumeFalse. The idea is that, if the assumption is wrong, the test will be skipped.
So, the test will be something like this.
#Test
void call1() {
Assumptions.assumeTrue(new EndpointChecker(), "Endpoint is not available");
Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
Here is the code for EndpointChecker class.
static class EndpointChecker implements BooleanSupplier {
#Override
public boolean getAsBoolean() {
// check the endpoint here and return either true or false
return false;
}
}
When the test is run, the availability of the endpoint will be checked first, if it is up, then the test will run.
Using JUnit 5 extension mechanisms.
So, let's start with creating the annotation. It is pretty straightforward.
#Retention(RetentionPolicy.RUNTIME)
#ExtendWith(EndpointAvailabilityCondition.class)
public #interface SkipWhenEndpointUnavailable {
String uri();
}
And EndpointAvailabilityCondition class. Even though, it looks big, overall logic is very simple.
import static org.junit.platform.commons.util.AnnotationUtils.findAnnotation;
public class EndpointAvailabilityCondition implements ExecutionCondition {
#Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
final var optional = findAnnotation(context.getElement(), SkipWhenEndpointUnavailable.class);
if (optional.isPresent()) {
final SkipWhenEndpointUnavailable annotation = optional.get();
final String uri = annotation.uri();
// check connection here start
boolean result = false; // dummy value
// check connection here end
if (result) {
return ConditionEvaluationResult.enabled("Connection is up");
} else {
return ConditionEvaluationResult.disabled("Connection is down");
}
}
return ConditionEvaluationResult.enabled("No assumptions, moving on...");
}
}
Hence, we can do the following in our tests.
#Test
#SkipWhenEndpointUnavailable(uri = "https://www.google.com")
void call2() {
Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
We can go ahead and add #Test annotation over #SkipWhenEndpointUnavailable and remove it from our test code. Like, so:
#Retention(RetentionPolicy.RUNTIME)
#ExtendWith(EndpointAvailabilityCondition.class)
#Test
public #interface SkipWhenEndpointUnavailable {
String uri();
}
class HttpCallerTest {
#SkipWhenEndpointUnavailable(uri = "https://www.google.com")
void call2() {
Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
}
I hope it helps.

how to unit test block of code that has db call and subsequent line depending on the db call

How to write junit test for testing the block of function that has the db call and the subsequent lines based on the db call result? any samples or example is appreciated
My function to test:
public String functionality(String input)
{
String readDBValue = db.giveMeValue();
if (input.contains(readDBValue))
{
return input;
}
else
{
return null;
}
}
My Junit4 test case:
public class JunitTest
{
#Test
public void testFunctionality()
{
String inputTst = "new input";
String expectTst = "new input";
assertEquals(functionality(input), expectTst);
}
}
How to test the line in functionality that returns some value from database from a dependent function?
Can you mock the DB and inject the mock into whatever class you are testing?
Using a test double of some description for the database will speed up your tests and allow you to specify the behaviour of the database calls so you can test branches in your code.
Edited 2019-04-28 18:17:00+13:00: Adding a code sample to illustrate.
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
public class TestMyClass {
#Test
public void test1() {
// create mock
MyDatabase mockDb = mock(MyDatabase.class);
// set behaviour required in test
when(mockDb.giveMeValue()).thenReturn("new input");
// inject mock into object being tested
MyClass objectUnderTest = new MyClass(mockDb);
// use mock in test....
assertEquals(objectUnderTest.functionality("input"), "new input");
}
}

How to use these #DataMongoTest and #SpringBootTest together in integration test

I am trying to write integration test case for one of my rest application which uses mongodb internally to persist the data
#DataMongoTest
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MainControllerTest {
#LocalServerPort
private int port = 8080;
/* some test cases*/
}
but I am getting below error
java.lang.IllegalStateException: Configuration error: found multiple declarations of #BootstrapWith for test class [com.sample.core.controller.MainControllerTest]: [#org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTestContextBootstrapper), #org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.context.SpringBootTestContextBootstrapper)]
looks like these two are mutually exclusive, so how to do the integration testing .
Use #AutoConfigureDataMongo with #SpringBootTest and this will resolve this ambiguity issue. #SpringBootTest and #DataMongoTest cannot be used together.
Answering to a very old post hoping it may help others.
#AutoConfigureDataMongo will connect to real database. In order to still use the embedded mongo, one can initiate the embedded mongoDb manually.
#SpringBootTest(classes = SubscriptionEventApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SubscriptionEventApiIntegrationTest {
#BeforeAll
static void setup() throws Exception {
startEmbeddedMongoDbManually();
}
private static void startEmbeddedMongoDbManually() throws IOException {
final String connectionString = "mongodb://%s:%d";
final String ip = "localhost";
final int port = 27017;
ImmutableMongodConfig mongodConfig = MongodConfig
.builder()
.version(Version.V3_5_5)
.net(new Net(ip, port, Network.localhostIsIPv6()))
.build();
MongodStarter starter = MongodStarter.getDefaultInstance();
mongodExecutable = starter.prepare(mongodConfig);
mongodExecutable.start();
mongoTemplate = new MongoTemplate(MongoClients.create(String.format(connectionString, ip, port)), "test");
}
#AfterAll
static void clean() {
mongodExecutable.stop();
}
#Test
public void test() {
.....
}
}
Purushothaman suggested starting embedded MongoDB server manually. I am suggesting to start it automatically using #DataMongoTest, but creating WebTestClient manually instead.
Kotlin code below, translates to Java trivially:
#DataMongoTest
// #ContextConfiguration may not be needed for your case.
#ContextConfiguration(
classes = [
Application::class,
MainController::class,
// Add more needed classes for your tests here.
// ...
]
)
#TestPropertySource(properties = ["spring.mongodb.embedded.version=4.0.12"])
class MainControllerTest(
#Autowired
private val mainController: MainController,
// Add more beans needed for your tests here.
// ...
) {
// Creating a WebTestClient is easy and
// can be done in different ways.
// Here is one of the possible ways.
private val webTestClient: WebTestClient =
WebTestClient.bindToController(mainController).build()
#Test
fun someTest() {
// ...
}
}

Re-run failed Test Script 'completely' using JUnit

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?

how to use DbUnit with TestNG

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
}
}