Both Testng and Junit are Testing framework used for Unit Testing. So what are the diffrences and advantages of JUnit and the TestNG?
Unit Testing Frameworks
Both JUnit and TestNG are Testing framework used for Unit Testing. TestNG is similar to JUnit. Few more functionalities are added to it that makes TestNG more powerful than JUnit. TestNG is a testing framework inspired by JUnit and NUnit.
Differences
Advantages of TestNG
TestNG Annotations are easy to understand over JUnit.
No constraints like declaring #BeforeClass and #AfterClass in
TestNG, which are present in JUnit.
As method name constraint is present in JUnit, such method name
constraint is not present in TestNG and you can specify any test
method names.
TestNG enables you to group test cases easily which is not possible
in JUnit. TestNG supports following three 3 additional
setUp/tearDown level: #Before/AfterSuite, #Before/AfterTest and
#Before/AfterGroup.
TestNG do not require extend any class.
TestNG allows to execute test cases based on group which isn't
possible in JUnit.
Parallel execution of Selenium test cases is possible in TestNG.
Related
Currently, as far as I am aware, Cucumber supports being run on JUnit 5 through the vintage execution engine.
Suppose I have the following test runner:
#RunWith(Cucumber.class)
#CucumberOptions(plugin = { "pretty", "html:target/cucumber" },
features={ "src/test/resources" },
strict = true)
#Tag("ACCEPTANCE_TEST")
public class TestRunner { }
If I run this with the tag expression defined as "ACCEPTANCE_TEST" in JUnit 5 it won't be picked up and run.
However, if I run it with the expression defined as a NOT (which would be true for the test class) e.g. "!UNIT_TEST" then it will be picked up and run.
How can I mix the JUnit 5 tag with a JUnit 4 test runner (such as the one above) so that it works for the positive match of a tag expression?
TLDR
You cannot.
Still TLDR
You cannot, at least not without reimplementing most of what Cucumber's JUnit4 runner does.
Long Story
To understand why, you have to grasp the differences of some terms:
JUnit 4: A single module (jar file) containing the test writing API, the test executor, the API to run tests, and at least two different mechanisms to extend it (rules and runners).
Cucumber JUnit4 runner: Cucumber's way to integrate with JUnit 4. Activated through #RunWith(Cucumber.class)
JUnit 5: A platform to run different test engines that comes in a few modules and provides an API to be used by IDEs and build tools and an SPI to plug-in test engines
Vintage: The test engine to use JUnit 4 within the JUnit 5 platform
Jupiter: The new test engine that evolves in sync with the JUnit 5 platform and is maintained by the same team.
Here's the thing: The #Tag annotation is a Jupiter feature and cannot possibly work with Cucumber's JUnit 4 runner. The JUnit 5 way to use Cucumber is the Cucumber test engine: https://github.com/cucumber/cucumber-jvm/tree/master/junit-platform-engine. AFAIU it has its own tagging mechanism and does not use #Tag because different test engines work side-by-side but do not share functionality.
I was wondering if JMockit is compatible with JUnit parameterized tests or JUnitParams, because I haven't found a way to make them work together so far, since you can only specify one JUnit runner, and both JMockit, JUnitParams and Parameterized require you to use their own runner.
JMockit does not require you to use an own runner. Using an own runner is just one of the possible ways to make sure JMockit got initialized properly before your tests run. You can also add JMockit as Java agent via commandline parameters, depend on classpath ordering (having JMockit in the classpath before JUnit) or call the JMockit initialization method manually before the actual tests start if you have such a place where you can call it, e. g. if you use an own JUnit runner.
Could you please outline new major features of JUnit 5 in comparison to JUnit 4?
What are new annotations, if any, and what they are used for (if few words)?
JUnit 5 programming model remained almost unchanged. We still have to use annotations to declare test and life-cycle methods.
At first sight there are no big changes. However, they exists:
Neither test classes nor test methods need to be public.
#Test annotation does not have additional parameters
Life-cycle annotations were renamed
#BeforeAll / #AfterAll
#BeforeEach / #AfterEach
#Disabled is the analogous to JUnit 4’s #Ignore
Also some changes was made for Assertions and Assumptions:
The optional message is now the last parameter
Assertion messages can be lazily evaluated using Supplier<String>
Now it is possible to assert boolean condition using BooleanSupplier
Also JUnit 5 introduced some new concepts into programming model:
Tagging and filtering
#Tag and #Tags used to declare tags for filtering tests, either at the class or method level; analogous to Categories in JUnit 4
#Nested test classes
For better grouping and organization, shared initialization state.
#DisplayName
Allow to declare custom display names — with spaces, special characters, and even emojis — that will be displayed by test runners and test reporting.
Dynamic tests
Useful when you need to run the same set of tests on many different input values or configurations.
JUnit 5 doen't support anymore Runners and Rules. These partially competing concepts have been replaced by a single consistent extension model.
Since test execution follows a certain life cycle. And each phase of that life cycle that can be extended is represented by an interface. Extensions can express interest in certain phases in that they implement the corresponding interface(s).
Using extensions you can implement:
Conditional test execution
TestExecutionCondition
ContainerExecutionCondition
Constructor and methods parameters resolution (dependency injection)
ParameterResolver
Exception handling
TestExecutionExceptionHandler
Handle test life-cycle
TestInstancePostProcessor
BeforeAllCallback
BeforeEachCallback
BeforeTestExecutionCallback
AfterTestExecutionCallback
AfterEachCallback
AfterAllCallback
It is great that SONAR can detect junit test without an assertion, but in practice mocking technology may be used during junit test, f.e. EasyMock or Mockito. Then question raises from here: some of the test cases only need verification of mocking object method call, and no assertion is needed. Is there a way to tell SONAR to accept mocking utility verification method as a valid assertion besides junit assertion?
B.R.
I'm currently working on a class, dealing with network issues. Using JUnit 3.8.1 and having a hardware device, that's not always around to test against, I'd like to conditionally suppress individual tests. Is there a way to achive this with a simple annotation like #if(!gatewayAvailable) -> test's suppressed?
Thanx for any pointers, marcus
There is no such feature in JUnit 3.8.1. You have to use JUnit4 and its Assume class.