Running a set of #Order ordered JUnit5 tests multiple times - junit

I wanted to know if there was a straightforward way of running a set of ordered tests multiple times with JUnit5, as opposed to running each test multiple times with the #RepeatedTest annotation.
For example, my tests:
#Test
#Order(1)
public void myFirstTest() {
//code here
}
#Test
#Order(2)
public void myFirstTest() {
//code here
}
#Test
#Order(3)
public void myFirstTest() {
//code here
}
I want them to run sequentially, 1-3 but repeated once the sequence has finished. Can this be done easily in JUnit 5 or is a #RunWith(Parameterized.class) still the easiest way, as described here

#RunWith(Parameterized.class) won't work in JUnit 5.
You could use your own launcher. Which might be overkill but it works.
The test class with tests that needs to be repeated:
#TestMethodOrder(MethodOrderer.OrderAnnotation.class)
#Disabled
public class OrderedExampleTest {
#Test
#Order(1)
public void shouldRunFirst() {
System.out.println("First!! ");
}
#Test
#Order(2)
public void shouldRunSecond() {
System.out.println("Second!!");
}
#Test
#Order(3)
public void shouldRunThird() {
System.out.println("Third!!");
}
}
And then in a separate class a special test method that will re-run this whole class multiple times:
public class ExternalRunnerTest {
#Test
public void shouldRepeatTestClass() {
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(
selectPackage("org.igorski.repeated"),
selectClass(OrderedExampleTest.class)
)
.configurationParameter("junit.jupiter.conditions.deactivate", "org.junit.*DisabledCondition")
.build();
Launcher launcher = LauncherFactory.create();
int numberOfRepeats = 5;
for(int i = 0; i < numberOfRepeats; i++) {
launcher.execute(request);
}
}
}
The OrderedExampleTest is disabled. So it should not run on its own when you run all the tests together. But, the special repeat test will ignore the disabling condition and run the test.
In my case this prints:
First!!
Second!!
Third!!
First!!
Second!!
Third!!
First!!
Second!!
Third!!
First!!
Second!!
Third!!
First!!
Second!!
Third!!

Related

Unit test for Spring KafkaListener with "Acknowledge" interface as an argument

I'm not expert at unit test but trying to write unit test for :
#KafkaListener(id = "group_id", topics = "topic" )
public AvroObject listen(AvroObject test, Acknowledgment ack)
But no idea how I can make it when there is and interface as an argument. I try this but not sure is it something useful or not make sense as an test :
#InjectMocks
KafkaConsumer kafkaConsumerTest;
#Test
#DisplayName("Assert Valid Consume")
void consumeValidEvent() throws URISyntaxException, IOException, InterruptedException {
// given
AvroObject event = createEvent(); //Create sample object as AvroObject
// when
AvroObject response = kafkaConsumerTest.listen(event, new Acknowledgment() {
#Override
public void acknowledge() {
}
#Override
public void nack(long sleep) {
//do nothing
}
// then
assertNotNull(response);
assertEquals(response.getCode1() ,98765);
assertEquals(response.getCode2() ,123456);
}
I was wondering if you can give me the best approach for this situation! cheers

Stop test execution after first fail [duplicate]

This question already has answers here:
Interrupt test class at the first test failure
(3 answers)
Closed 1 year ago.
I have to write a test divided into several steps. Each step is based on the previous one so if one fails, testing should be stopped.
#TestMethodOrder(AlphanumericOrder.class)
public class TestCase {
#Test
public void step10() {
Assertions.assertTrue(true);
}
#Test
public void step20() {
Assertions.assertTrue(false);
}
#Test
public void step30() {
Assertions.assertTrue(true);
}
#Test
public void step40() {
Assertions.assertTrue(true);
}
}
In the example above testing should be terminated after step20(). I implemented custom MethodOrder to ensure correct sequence of execution. The problem I have is how to stop other tests after one fails? I tried to implement TestWatcher with no success. Is there any built-in mechanism in JUnit5 that can solve my problem?
Working solution that was shared in the comments:
Reference: Interrupt test class at the first test failure
#ExtendWith(StepwiseExtension.class)
#TestMethodOrder(AlphanumericOrder.class)
public class TestCase {
#Test
public void step10() {
Assertions.assertTrue(true);
}
#Test
public void step20() {
Assertions.assertTrue(false);
}
#Test
public void step30() {
Assertions.assertTrue(true);
}
#Test
public void step40() {
Assertions.assertTrue(true);
}
#BeforeEach
public void before(){
}
}
class StepwiseExtension implements ExecutionCondition, TestExecutionExceptionHandler {
#Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) {
ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
ExtensionContext.Store store = storeFor(extensionContext, namespace);
String value = store.get(StepwiseExtension.class, String.class);
return value == null ? ConditionEvaluationResult.enabled("No test failures in stepwise tests") :
ConditionEvaluationResult.disabled(String.format("Stepwise test disabled due to previous failure in '%s'", value));
}
#Override
public void handleTestExecutionException(ExtensionContext extensionContext, Throwable throwable) throws Throwable {
ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
ExtensionContext.Store store = storeFor(extensionContext, namespace);
store.put(StepwiseExtension.class, extensionContext.getDisplayName());
throw throwable;
}
private ExtensionContext.Namespace namespaceFor(ExtensionContext extensionContext){
return ExtensionContext.Namespace.create(StepwiseExtension.class, extensionContext.getParent());
}
private ExtensionContext.Store storeFor(ExtensionContext extensionContext, ExtensionContext.Namespace namespace){
return extensionContext.getParent().get().getStore(namespace);
}
}

How to run different tests on a single Document variable which was fetched with Jsoup.connect(string)

I have multiple test cases and I want to use a single Document variable with all of them.
There are more test units which will use this Document.
I had an idea to download the html code, in order to avoid connecting to the site multiple times and taking up server resources, but still I think that it wouldn't be an optional approach to testing.
public class ScrapperTest {
public ScrapperTest() {
}
#BeforeClass
public static void setUpClass() {
}
#AfterClass
public static void tearDownClass() {
}
#Before
public void setUp() {
}
#After
public void tearDown() {
}
/**
* Test of scrapeManufacturer method, of class Scrapper.
*/
#Test
public void testScrapeManufacturer() {
System.out.println("scrapeManufacturer");
Document html = null;
Scrapper instance = new ScrapperImpl();
String expResult = "";
String result = instance.scrapeManufacturer(html);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
}
/**
* Test of scrapeMinPrice method, of class Scrapper.
*/
#Test
public void testScrapeMinPrice() {
System.out.println("scrapeMinPrice");
Document html = null;
Scrapper instance = new ScrapperImpl();
String expResult = "";
String result = instance.scrapeMinPrice(html);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}

junit for multi threaded class with mockito

Please, help me write a JUnit test for this code using Mockito.
class A{
private BlockingQueue<Runnable> jobQueue;
public void methodA(List<String> messages) {
try {
jobQueue.put(() -> methodB(message));
} catch(InterruptedException e) {}
}
private void methodB(Message message) {
//other logic
}
}
Your example lacks context as to what it is methodB is doing... Without knowing what the functionality is that you want to verify, just verifying that methodB gets called wouldn't be a particularly useful test, nor is mocking the BlockingQueue. I'm going to go out on a limb and assume that methodB interacts with another object, and it's this interaction that you really want to verify, if that's the case my code and test would look something like:
class A {
private BlockingQueue<Runnable> jobQueue;
private B b;
public void methodA(Message message) {
try {
jobQueue.put(() -> methodB(message));
} catch (InterruptedException e) {
}
}
private void methodB(Message message) {
b.sendMethod(message);
}
}
class B {
public void sendMethod(Message message) {
// other logic
}
}
And my test would potentially look something like:
class Atest {
private A testSubject;
#Mock
private B b;
#Test
public void testASendsMessage() {
Message message = new Message("HELLO WORLD");
testSubject.methodA(message);
verify(b, timeout(100)).sendMethod(message);
}
#Before
public void setup() throws Exception {
testSubject = new A();
}
}
In general you want to avoid needing to verifying bits with multiple threads in a unit test, save tests with multiple running threads mainly for integration tests but where it is necessary look at Mockito.timeout(), see example above for how to use. Hopefully this helps?

Repeating TestNG or JUnit test suite

I trying to repeat login_logout.class 10 times. Why can't I repeat this 10 times?
#RunWith(Suite.class)
#SuiteClasses({login_logout.class})
public class AllTests {
#Parameters
public static Collection<Object[]> getData(){
Object[][] data = new Object[10][0];
return Arrays.asList(data);
}
}
My understanding is "new Object[10][0]" is to construct an two-dimension array:
(1) [10][0] mean the array has 10 lines that each line holds zero object
==> Is it supposed to be "[10][1]" ?
(2) As only the code you uploaded, you didn't actually create any real object,
because the "new Object[10][0]" only make an array not any real object
The Suite test runner doesn't support parameters. You could rewrite login_logout as a parameterized test:
#RunWith(Parameterized.class)
public class LoginLogoutTest {
#Parameterized.Parameters
public static Collection<Object[]> values() {
return Arrays.asList(
new Object[10][1]);
}
public LoginLogoutTest(Object ignored) {
}
#Test
public void doSomething() {
}
}
That being said, I can't think of too many use cases for running the exact same test ten times.