JUnit 5 #EnabledIfSystemProperty doesn't work as expected - java

I migrated my test from JUnit 4 to JUnit 5. All works fine but the translation of my previous annotation:
#IfProfileValue(name = "run.import.tests", values = {"true"})
into
#EnabledIfSystemProperty(named = "run.import.tests", matches = "true")
doesn't work as expected. Before the migration I runned my tests passing the argument
-Drun.import.tests=true
only if I passed it they were runned. With Junit 5, even with annotation #EnabledIfSystemProperty(named = "run.import.tests", matches = "true") the test is runned even if the argument run.import.tests is not set.
Am I doing something wrong?

To make it work an "opposite" annotation has to be added, so both of them together look like this:
#EnabledIfSystemProperty(named = "run.import.tests", matches = "true")
#DisabledIfSystemProperty(named = "run.import.tests", matches = "(?!true)")
I've checked it and the test class is disabled if the run.import.tests property is not set or if it is set to any other value than true; if the value is set to true - the test class is not disabled.
Curiously, the documentation of #EnabledIfSystemProperty states:
If the specified system property is undefined, the annotated class or method will be disabled.
Yet it does not work that way and it may be a bug. I will try and debug the JUnit classes and if I create an issue on their GitHub, I will link it here.
I've gone through the code and tested it a few more times - here is the summary:
When I run the test using Maven (mvn test), the annotation #EnabledIfSystemProperty alone works fine - the test is run only when I add -Drun.import.tests=true argument. #DisabledIfSystemProperty is not needed in that case.
When I run the test using IntelliJ's Run XxxTest handling of the property worked fine only if both annotations were present. After some debugging I came across JupiterTestEngine - a class that is run by external launchers (Maven, IntelliJ, any other). It seems that IntelliJ adds a property to it's test launcher: junit.jupiter.conditions.deactivate, which is usually useful - thanks to that we can run even tests that are disabled with conditional annotations locally, ignoring them. The value of the property is org.junit.*Enabled*Condition when #DisabledIfSystemProperty is not present and org.junit.*Disabled*Condition when it is - the conditions are JUnit's extensions that resolve disabled state for the test.
The functionality described in (2) is usually useful, but in your case it made it look like the annotation is not working. It actually is working, but IntelliJ just bypasses it.

Related

How to execute test runner with multiple tags in Cucumber

I want to execute two specified test cases one by one
I have test runner configured like below
#CucumberOptions(
features = {"src/test/resources/features"},
glue = "classpath:",
plugin = { "html:src/test/resources/execution/report/cucumber-reports.html" },
tags = "#Test213 and #Test214"
)
public class TestRunner extends AbstractTestRunner {
}
but when I run it none scenarios is executed - only #Before from testNG.
Console output:
14:32:09.036 [main] INFO integration.RestFXTestBaseClass - New browser instance opened
14:32:09.039 [main] INFO cleaner.RestFXCleaner - Cleaning execution directory...
14:32:09.044 [main] INFO cleaner.RestFXCleaner - Items deleted
===============================================
Default Suite
Total tests run: 0, Passes: 0, Failures: 0, Skips: 0
===============================================
It was due to my wrong understanding of this tags handling.
I thought that I need to join scenarios for execution by and but it's logical and
so this tags = "#Test213 and #Test214"executes only scenarios which are annotated by both these tags and there are not any in my suite.
If I want to run scenarios one by one I need to configure it like this tags = "#Test213 or #Test214"
The problem most likely is caused by glue = "classpath:"
In Cucumber, the "glue" is the location (folder) for your step definitions. I am sure your step definitions folder is not named classpath:. If the folder where your step definitions reside is called tests and it is inside your project, you could use a relative path such as glue = "tests". Most people choose to name their step definitions folder as stepDefinitions.
Also, make sure your tags are correct or you may see a similar problem.
UPDATE: According to the info provided by M.P. Korstanje, the glue can be a classpath URI. However, your URI is empty. The problem is the same: You are not letting Cucumber know where to find your step definitions. You need to provide either a package (i.e. com.myapp.mypackage), a path (i.e. com/myapp/mypackage), or an URI (i.e. classpath: http://com/myapp/mypackage).
You need to use 'or' if you want to run scenarios that are annotated with either of these tags.
'And' is to run scenarios that are annotated with both the tags
Sometimes we would want to run some regression scenarios that are failed in the last run.
So, that time we can use 'and' -> #Regression and #Defect

WebDriver is NULL when start more then one test case

I have a problem. There are 2 Test classes in my code and when I run each 1 test case manually both working fine. But when execute tests with maven only one test is executed successfully and other gives me error
java.lang.NullPointerException
at com.selenium.course.tests.ProductTests.executeProductTest(ProductTests.java:17).
Expected behavior: all tests should execute with maven.
Here is my code = https://github.com/Dermenji/SeleniumCourse
In your base calass where you have get methods for the driver, you need a "global" class variable which will be static.
public static WebDriver driver;
Selenium also works with annotations which they have not yet implemented.
For me, many test cases caused errors after I added annotations everything went well.
https://www.browserstack.com/guide/testng-annotations-in-selenium
maybe this Site helps u.
You should use same driver instance for all test classes
The solution is you can use util class for driver instance

DependONGroups annotation testng

I am using DependOnGroups parameter in #test annotation.the code looks like,
#Test(groups={"datacompare"},dependsOnGroups = {"AzkabanFlow"})
Now the requirement is we need to run the test only for the group datacompare which is done by specifying the maven parameter,
clean test site -DtestGroup=datacompare
Since the above group has dependency with the group azkban flow, i am getting the error
[ERROR] DependencyMap::Method "DataValidationTestSuite.data_Comparison(java.lang.reflect.Method)[pri:0, instance:com.kohls.test.automation.framework.testsuite.DataValidationTestSuite#1608e1a]" depends on nonexistent group "AzkabanFlow"
Can someone suggest me a way to run the test for datacompare without removing the parameter DependOnGroups and also not calling the particular group mentioned in dependOnGroup parameter in maven parameter for test run.
You might want to change your #Test annotation to something like below
#Test(groups={"datacompare"},dependsOnGroups = {"AzkabanFlow"}, ignoreMissingDependencies=true)
This would cause TestNG to ignore missing dependencies and hopefully it should solve your problem as well.
Javadocs for the same can be referred here.

Junit - Override default behaviour to run tests only once, even if they are added several times (in different Suites)

For our usecase, as an example - we need to run a JUnit test, even if it is added multiple times within a Test Suite, without being skipped.
Currently we notice that JUnit test runner skips a Test with the same name, if it finds the test somewhere else within a Test Suite. Here is an example screenshot to show test "Case_A" within "Procedure_A" being skipped within a Test Suite -
Could this behaviour be overriden, if so could someone point us in the right direction?
I did some research arround this problem.
Simple setting - one Test "TestCase_A" and one Suite "TestProcedure_A" that runs the TestCase_A twice :
public class TestCase_A {
#Test
public void test() throws Exception {
System.out.println("Case_A RUN");
Assert.assertTrue(true);
}
}
#RunWith(Suite.class)
#Suite.SuiteClasses({ TestCase_A.class, TestCase_A.class })
#SuppressWarnings("all")
public class TestProcedure_A {
}
I run the test Suite using Eclipse and maven.
Finding: The sysout statement actually shows, that the TestCase_A runs twice!
Therefore, the Eclispe View is misleading. Test are run multiple times - the tree also reflects this. However, the status of the actual single calls is not displayed properly in the Eclispe Junit View.
I presume the view is based on the junit.runner.TestRunListener. It probably worth looking into that.

JUnit parameterized tests: how do I run only 1 specific test from IntelliJ/Eclipse?

I have a #Parameterized junit test that spawns 50 tests:
#RunWith(Parameterized.class)
public class NurseRosteringSolveAllTurtleTest ... {
#Parameterized.Parameters(name = "{index}: {0}")
public static Collection<Object[]> getSolutionFilesAsParameters() {
return ... // returns 50 Files.
}
public NurseRosteringSolveAllTurtleTest(File unsolvedDataFile) {
...
}
...
#Test
public void solveDataFile() {
...
}
}
Running it takes an hour (and it's impossible to shorten that time, they are integration tests). Test 28 fails.
How do I run test 28 alone, without running the other 49 tests? Without changing the actual code, by simply configuring a -D or something similar in IntelliJ's (or Eclipse's) run configuration.
I just tested this in Eclipse with a simple parameterized test that always fails on test #4. One is able to right-click on the failed test and select Run. Only that test then executes.
Result:
Frustratingly, I can't see what Eclipse did to solve the problem. Nothing is apparently altered in the run configuration. In particular, if you select to run the configuration a second time, it executes all the tests.
Some further testing shows that Eclipse will regenerate all 10 parameter values, but only uses the 4th value. (This was determined by embedding a print statement in the #Parameters method).
Eclipse is now (as of the Mars M4 release) able to run not just a single test from the Parameterized test class but any kind of subtree.
This can be:
all methods for a single data set as returned by the #Parameterized-method
all datasets for a single #Test-method
And as already mentioned, the test can also be specified by entering the tests name into the "method" text filed within the launch configuration. There will be a marker indicating that the method doesn't exist, but the test will run anyway.
See this blog post for details.
Not sure if it will help, but you can try a trick which I used with Eclipse and JUnit parameterized tests.
In JUnit launch configuration in "Test method" field you can write the full name of parameterized test, in your example it should be something like this 'solveDataFile[28: /path/to/your/file]'. Eclipse will complain that method does not exist but will still lunch it successfully.
For a subset of tests ex( 27 & 28 ) Just add:
`.subList( startInclusive, stopExclusive );`
before returning your parameters collection.
Non consecutive subsets:
Collection<Object[]> c = Arrays.asList( data ).subList( startInclusive, stopExclusive );
c.add( another subset );
return c;
Similarly to Miguel's answer, if you are using the JUnit 5's
#ParameterizedTest
#CsvFileSource(resources = arrayOf("/sender.csv"))
you can go to your csv file and "comment out" some lines by prepending the # character to them.

Categories

Resources