Serenity: Step define are not displays on report when extend class different package - serenity-bdd

I am using Serenity with junit5, i have defined step class as follow:
step class define
Two classes CommonStep and ShopStep not in same package
CommonStep.class
public class CommonStep {
#Step("#actor this is step common")
public void testStep(){
System.out.println("Hello CommonStep");
}
ShopStep.class
public class ShopStep extends CommonStep {
#Step("#actor this is step of ShopStep")
public void testShopStep() {
System.out.println("Hello ShopStep");
}
}
In test file
#ExtendWith(SerenityJUnit5Extension.class)
#TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TC_CreateShop{
#Steps
ShopStep I;
#Test
public void test(){
I.testShopStep();
I.testStep();
}
}
It run correct but in report, all steps of CommonStep which extended by ShopStep is not displayed.
Report not display step
Note: If both CommonStep, and ShopStep in same package , all steps in report are displayed correctly

Related

JUnit5: Before and After Suite method invocation

I've spent a few days trying to find out a solution, so I know all the basic answers
I've read the documentation, and I know, that #BeforeClass/#AfterClass is replaced with #BeforeAll/#AfterAll, #RunWith no longer exists; superseded by #ExtendWith
I've read all the topics here on the stackoverflow (removed links, since stackoverflow pretends it's a spam:(
I used to run some JUnit4 tests in the suites. Each Suite class Suite1.class, Suite2.class had several #Test methods and #BeforeClass/#AfterClass were running exactly before/after all the testing methods.
#RunWith(StopOnFailureSuite.class)
#Suite.SuiteClasses({
Test1.class,
Test2.class
})
public class TSuite_20 {
private static final byte SUITE_NUMBER = 20;
#BeforeClass
public static void setUpClass() {
//some logic for suite setup
}
#AfterClass
public static void tearDownClass() {
//some logic for teardown
}
}
As I wanted to use #ParameterizedTests I need to migrate to JUnit5.
And suddenly I realised, that exact the same behaviour, that used to be in JUnit4 is no more achievable.
[run some custom setup code; run several test classes, which may contain several #Test methods; run some custom tear down code];
Does anybody know (better with examples) an approach to make it with JUnit 5?
Option 1
This code will never execute BeforeAfterSuite#beforeAll and BeforeAfterSuite#afterAll
#ExtendWith(BeforeAfterSuite.class)
#Suite
#SelectClasses({
Test1.class,
Test2.class
})
public class TSuite_20 {
public static final byte SUITE_NUMBER = 20;
}
public class BeforeAfterSuite implements BeforeAllCallback, AfterAllCallback
/*,TestInstancePreConstructCallback, BeforeTestExecutionCallback,
AfterTestExecutionCallback, ExtensionContext.Store.CloseableResource*/ {
private static boolean started = false;
#Override
public void beforeAll(ExtensionContext context) {
if (!started) {
started = true;
//before stuff
}
}
#Override
public void afterAll(ExtensionContext context) throws Exception {
//after all;
}
}
Option 2
I was just curious, how will JUnit treat suite class if I put a test method into it...
This code will execute BeforeAfterSuite#beforeAll and BeforeAfterSuite#afterAll once, before and after TSuite_20#test
#ExtendWith(BeforeAfterSuite.class)
#Suite
#SelectClasses({
Test1.class,
Test2.class
})
public class TSuite_20 {
public static final byte SUITE_NUMBER = 20;
#Test
public void test() {
}
}
Option 3
We also can apply #ExtendWith(BeforeAfterSuite.class) per Test class which will results in a BeforeAfterSuite#beforeAll and BeforeAfterSuite#afterAll per Test class. (in this example - 2 times).
#ExtendWith(BeforeAfterSuite.class)
public class Test1 {
#Test
public void test11() {
}
#Test
public void test12() {
}
}
#ExtendWith(BeforeAfterSuite.class)
public class Test2 {
#Test
public void test21() {
}
#Test
public void test22() {
}
}
Option 4
I also give a shot for
a Suite class without #ExtendWith() and #BeforeAll + #AfterAll; (as expected nothing happened)`
a Suite class without #ExtendWith() and #BeforeAll + #Test + #AfterAll; (as expected single execution of BeforeAll/AfterAll for the specific Suite class)`
Option 5
Listeners were my last hope to achieve the desired behaviour.
I've created my own impl for LauncherSessionListener, just because I've thought it will allow me to execute smth exactly before tests start.
public class BeforeAfterSuiteLauncher implements LauncherSessionListener {
private static boolean started = false;
#Override
public void launcherSessionOpened(LauncherSession session) {
if (!started) {
started = true;
//before all
}
}
#Override
public void launcherSessionClosed(LauncherSession session) {
//after all
}
}
And I've added also some default impl CompositeLauncherSessionListener
Packages structure screenshot to show Java SPI configuration: LauncherSessionListener
For TestExecutionListener I've added two default impls, just to catch at least one Listener:
org.junit.platform.launcher.listeners.LoggingListener
org.junit.platform.launcher.listeners.SummaryGeneratingListener
and one custom
public class BeforeAfterExecutionListener implements TestExecutionListener {
#Override
public void testPlanExecutionStarted(TestPlan testPlan) {
//before all
}
#Override
public void testPlanExecutionFinished(TestPlan testPlan) {
//after all
}
}
Packages structure screenshot to show Java SPI configuration:TestExecutionListener
And only SummaryGeneratingListener was triggered!
What am I doing wrong? Why my BeforeAfterExecutionListener impl was not loaded and triggered?
P.S. All of the above code was executed under Intellij Idea 2021.1.3 Ultimate Edition
java version "1.8.0_341"
Java(TM) SE Runtime Environment (build 1.8.0_341-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.341-b10, mixed mode)
here is intelliJs command:
C:\Tools\jdk\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:61280,suspend=y,server=n -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:C:\Users\userName\AppData\Local\JetBrains\IntelliJIdea2021.1\groovyHotSwap\gragent.jar -javaagent:C:\Users\userName\AppData\Local\JetBrains\IntelliJIdea2021.1\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath C:\Users\userName\AppData\Local\Temp\classpath1705687115.jar com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit5 com.testdirectly.application.testcase.TSuite_20
Which results in JUnit5IdeaTestRunner
My gradle dependencies
dependencies {
//JUnit platform
// to group tests by package, by class name, by class name pattern, etc (use #Suite, #SelectClasses) :junit-platform-suite-api:1.9.2
// and to filter/discover and run them (SuiteLauncher, SuiteTestEngine, SuiteTestDescriptor) :junit-suite-engine:1.9.2
testImplementation "org.junit.platform:junit-platform-suite:1.9.2"
//Launcher, engine discovery
testImplementation "org.junit.platform:junit-platform-launcher:1.9.2"//to run tests
//JUnit Jupiter
//to use assertions and so on
testImplementation "org.junit.jupiter:junit-jupiter-api:5.9.2"
//to use #ParameterizedTest
testImplementation "org.junit.jupiter:junit-jupiter-params:5.9.2"
//Jupiter engine to run junit5 tests (JupiterTestEngine, Extensions, etc)
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.9.2"
}
Short answer
Option 5 works if you tweak it slightly (see below).
Long answer
Options 1 and 2 do not work because #ExtendWith is a Jupiter extension mechanism whereas #Suite triggers an engine of its own.
Test engines do not combine on the JUnit platform.
The same goes for option 4 since #BeforeAll and #AfterAll are Jupiter annotations.
Making Option 5 Work
First of all I'd suggest to use TestExecutionListener instead of LauncherSessionListener because the latter is still experimental.
Thus we have
package my.project.suites;
import org.junit.platform.launcher.*;
public class BeforeAfterSuiteListener implements TestExecutionListener {
#Override
public void testPlanExecutionStarted(TestPlan testPlan) {
System.out.println("before all");
}
#Override
public void testPlanExecutionFinished(TestPlan testPlan) {
System.out.println("after all");
}
}
The missing thing is now that you'll have to register BeforeAfterSuiteListener globally.
In classpath-based Java you do that through a resource file
META-INF/services/org.junit.platform.launcher.TestExecutionListener:
my.project.suites.BeforeAfterSuiteListener
Now before all and after all should show up in your output exactly once per test run.

How to find all dependencies between two classes using VS Enterprise Code Map?

If I pull a class A and class B onto a Code Map, VSE (Visual Studio Enterprise) will map the direct calls of class A calling methods in class B.
So,
public class A
{
public void DoSomething()
{
b.DoSomethingElse();
}
}
This will map. But if it's something like:
public class A
{
public void DoSomething()
{
d.DoManyThings();
}
}
public class D
{
public void DoManyThings()
{
c.DoThings();
}
}
public class C
{
public void DoThings()
{
b.DoSomethingElse();
}
}
public class B
{
public void DoSomethingElse()
{
// imagine code here
}
}
Then the Code Map won't map between class A and class B automatically. The only way I've found to show those dependencies is to go to each method and click "Show Methods This Calls".
Is there a way to get VSE make the Code Map all those dependencies initially without having to investigate every method?

How to get reference to static class of Java super class in Kotlin

I've got sample third party Java code:
public class ApiClass extends PackagePrivateClass {
}
abstract class PackagePrivateClass {
public static class StaticClass {
}
}
So only ApiClass and StaticClass are public. In Java I can get reference to StaticClass with: ApiClass.StaticClass. For the same code in Kotlin I got Unresolved reference: StaticClass. I can't also get reference via PackagePrivateClass, because it's package private (captain obvious). Is there any hack to get reference to StaticClass (it's third party code so I can't simply make PackagePrivateClass public)?
I understand that it's probably 'by design', however it forbids me from using 3p code
It seems the only solution is to build Java wrapper class that your kotlin class can access to.
public class ApiClass extends PackagePrivateClass {
}
abstract class PackagePrivateClass {
public static class StaticClass {
void instanceFunction() {
}
static void classFunction() {
}
}
}
The adapter java class (StaticClassAdapter.java):
class StaticClassAdapter {
private static ApiClass.StaticClass staticClass;
void instanceFunction() {
staticClass.instanceFunction();
}
static void classFunction() {
PackagePrivateClass.StaticClass.classFunction();
}
}
So in your kotlin code...
class KotlinClass {
fun main() {
StaticClassAdapter().instanceFunction()
StaticClassAdapter.classFunction()
}
}

how to pass parameters to a test case while running it using Junit Suite

I want to run multitple Junit tests i have created in a package. Every test needs region and server paramter to load the correct data files. I am using System.getProperty to fetch region and serverdetails for all junit tests. I am not sure how to pass these parameters in a TestSuite Runner. Here is the test case i have created
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ExpenseTests {
private static String server = System.getProperty("server");
private static String region = System.getProperty("region");
#BeforeClass
public static void setup() throws Exception {
SetUp setUp = new SetUp(region, server);
Login(region, server);
CreateClient(region, server);
}
#Test
public void test1_checkexpense() {
// code here
}
#Test
public void test2_addbasicExpense() {
//code here
}
#AfterClass
public static void teardown() throws Exception {
quit(webpage);
}
}
Here is the TestSuite
#RunWith(Suite.class)
#Suite.SuiteClasses({
ExpenseTests.class
AnotherTest.class
})
public class SmokeTestSuite {
}
I can run ExpenseTest using mvn install -Dtest="ExpenseTests" -Dserver="prod" -Dregion="us" but how do i pass region and server details in above SmokeTestSuite?
I think you may use Global variable to pass parameter to all test cases.
Example
public static String server = System.getProperty("server");
public static String region = System.getProperty("region");
Then pass it to all test cases.

Mockito Liferay service testing

I try testing my LocalServiceUtil classes, generated by service builder, with PowerMock but always getting 'null' or '0' from Util's methods.
Test class
#RunWith(PowerMockRunner.class)
#PrepareForTest(EntityLocalServiceUtil.class)
public class EntityTest {
#Test
public void testGetAnswer() throws PortalException, SystemException {
PowerMockito.mockStatic(EntityLocalServiceUtil.class);
assertEquals("hello", EntityLocalServiceUtil.getHello());
}
}
Util class contains
public static java.lang.String getHello() {
return getService().getHello();
}
and this service working correctly on deployed portlet. What i do wrong?
You have forgot to mock the methode:
#Test
public void testGetAnswer() throws PortalException, SystemException {
PowerMockito.mockStatic(EntityLocalServiceUtil.class);
when(EntityLocalServiceUtil.getHello()).thenReturn("hello"); // <- here
assertEquals("hello", EntityLocalServiceUtil.getHello());
}