Junit

JUnit is considered the standard unit testing framework to test Java applications. Now days every IDE comes with the inbuilt support of JUnit, For this Junit Mockito Tutorial we will be using JUnit 5 and Eclipse Oxygen version.

Changes in Junit 5

There are few changes in Junit 5 compared with junit 4, below are few major changes in JUnit 5
1. Annotations reside in the org.junit.jupiter.api package.
2. Assertions reside in org.junit.jupiter.api.Assertions.
3. Assumptions reside in org.junit.jupiter.api.Assumptions.
4. @Before and @After no longer exist; use @BeforeEach and @AfterEach instead.
5. @BeforeClass and @AfterClass no longer exist; use @BeforeAll and @AfterAll instead.
6. @Ignore no longer exists: use @Disabled instead.
7. @Category no longer exists; use @Tag instead.
8. @RunWith no longer exists; superseded by @ExtendWith.
9. @Rule and @ClassRule no longer exist; superseded by @ExtendWith

@Annotations

JUnit provides may annotations, we have explained them below based on the usage, Neither test classes nor test methods need to be public in Junit 5.

Methods annotated with @Test, @TestTemplate, @RepeatedTest, @BeforeAll, @AfterAll, @BeforeEach, or @AfterEach annotations must not return a value, So always the return type of the method shoud be void.

@Test :

@Test is the actual test method where we place our code to test the applications.

@BeforeTest :

@BeforeTest method will be executed before executing the @Test method, @AfterTest executes for each and every @Test

@AfterTest :

@AfterTest method will be executed after @Test method compltes its execution, @AfterTest executes for each and every @Test

@BeforeAll :

@BeforeAll method will be executed before executing any method in the class, @BeforeAll method gets executed once per class

@AfterAll :

@AfterAll method will be executed after completing execution of all the methods in the class, @BeforeAll method gets executed once per class

@Disabled :

@Disabled annotation used to tell the compiler that method should not be executes, @Disabled makes the method to skip.

@DisplayName:

@DisplayName displays a custom name for the method / class, @DisplayName is applicable for class and methods. Display name can contain alphabets, spaces, special characters, and even emojis


										import static org.junit.Assert.fail;
										import org.junit.jupiter.api.AfterAll;
										import org.junit.jupiter.api.AfterEach;
										import org.junit.jupiter.api.BeforeAll;
										import org.junit.jupiter.api.BeforeEach;
										import org.junit.jupiter.api.Disabled;
										import org.junit.jupiter.api.DisplayName;
										import org.junit.jupiter.api.Test;

										@DisplayName("Class level Display name")
										public class SampleJunit {
											
											@BeforeAll
											static void initAll() {
												System.out.println("@BeforeAll");
											}

											@BeforeEach
											void init() {
												System.out.println("@BeforeEach");
											}

											@Test
											void succeesTest() {
												System.out.println("@Test Success");
											}

											@Test
											@DisplayName("Fail test : Chercher Tech")
											void failingTest() {
												System.out.println("@Test failure");
												fail("Failing the test to to demo");
											}

											@Test
											@Disabled("for demo purposes")
											void skippedTest() {
												// not executed
												fail("Failing the test to to demo");
											}

											@AfterEach
											void tearDown() {
												System.out.println("@AfterEach");
											}

											@AfterAll
											static void tearDownAll() {
												System.out.println("@AfterAll");
											}
										}

										

Output of Junit Annotations : output-annotations-junit-mokito

From the above out itself we can know the order of execution in Junit:
1. BeforeAll
2. BeforeEach
3. Test
4. AfterEach
5. AfterAll

Assertions in Junit 5

In JUnit 5 all the assertions are present at org.junit.jupiter.api.Assertions and all the assertions methods are static.

fail(" failure message") :

fail() method fails the current 2test test case without checking for any conditions, this method will be useful incase where you have to fail a test case when an particular exception occurs.

assertTrue​(boolean condition, java.lang.String message) :

assertTrue method verifies whether given parameter is true/results in true or not, in case if the parameter is false then assertTrue method fails the testcase. We can also mention the reason for failure.

assertFalse :

assertFalse method verifies whether given parameter is false/results in false or not, in case if the parameter is true then assertFalse method fails the testcase. We can also mention the reason for failure.

assertNull :

verifies whether given object is null or not, in case if the object is not null then Junit fails the test case.

assertNotNull :

verifies whether given object is not null or not, in case if the object is null then Junit fails the test case.

assertEquals :

assertEquals method compares whether two give values are same or not, if the values are diffrent then Junit fails the testcase. This method is overloaded to accept all kind of values, from Byte to Object class.

assertArrayEquals :

assertArrayEquals method compares two given arrays, fails incase both arrays are different. This method is also overloaded to accept all the values in java.

assertIterableEquals :

assertIterableEquals method verifies whether given iterable are same are not, below example shos that same values stored in ArrayList and LinkedList, even though those are two different object, this method verifies whether values are in matching order or not.

assertNotEquals :

assertNotEquals method verifies given two object and fails if both object are same, assertNotEquals method is also overloaded to accept all the values in java.

assertAll :

assertAll method verifies all the assertions passed to this method.

assertThrows :

assertThrows method verfies whether given code throws exception or not, Junit fails the testcase incase if no exception occurs.

assertTimeout :

assertTimeout method asserts that execution of the supplied executable code completes before the given timeout is exceeded.

Hamcrest Matches in JUnit 5

Even though the assertion facilities provided by JUnit Jupiter are sufficient for many testing scenarios, there are times when more power and additional functionality such as matchers are desired or required.

In such cases, the JUnit team recommends the use of third-party assertion libraries

Till JUnit 4 developers were using assertThat() method present in the org.junit.Assert class but Junit 5 onwards Hamcrest provides its own assertThat() method.

Hamcrest allows checking for conditions in your code using matchers classes present hamcrest API.

Compare same or not :

Using hamcrest matchers we can compare two values are same or not, using equalTo, is methods.

										int i = 10;
										int j = 10;
										// all statements test the same
										assertThat(i, equalTo(j));
										assertThat(i, is(equalTo(j)));
										assertThat(i, is(j));
										

To get the same result as above wwe can use the Junit's assertEquals method.

containsString :

containsString method verifies whether Main string contains substring or not.

										assertThat("Chercher Tech", containsString("Tech")));
										

Tagging in Junit 5

In Junit we can tag a test using @Tag annotation, @Tag helps to identify a test. We can execute and filter the test based on the tages that we provide. Tagging similar to groups in TestNG, for Example if we wat to run only 'smoke' tests we can tag test which we want to execute as part of smoke test.

Test classes and methods can be tagged via the @Tag annotation. @Tag names should follow below conventions.

1. A tag must not be null or blank.

2. A trimmed tag must not contain whitespace. (Trimmed means whitespaces removed at ends)

3. Tag must not contain ISO control characters.

4. Tag must not contains special characters like : ',: comma', '(: left parenthesis', '): right parenthesis', '&: ampersand', '|: vertical bar', '!: exclamation point'

Single Inheritance in Selenium and java

Repeated Tests in Junit 5

We can execute a single testase multiple times, JUnit 5/Jupiter provides the ability to repeat a test a specified number of times simply by annotating a method with @RepeatedTest

Each invocation of a repeated test behaves like the execution of a regular @Test method When we are using @RepeatedTest annotations, we can avoid using the @Test annotations. When we use both of the annotations, the number of times the test case will be execute is repeatedTest + 1. below is the testcase with @RepeatedTest alone


										@RepeatedTest(3)
										void succeesTest() {
											System.out.println("This test will be executed 3 times");
										}
										

Output of Repeated test. repeatedtest-annotation-junit

Let's see what happens when we include @Test annotations


										@Test
										@RepeatedTest(3)
										void succeesTest() {
											System.out.println("Repeated test along with test");
										}
										

Output of @RepeatedTest along with @Test test-repeatedtest-junit-mockito

Parameterize in JUnit 5

@ParameterizedTest annotation allows user to achieve Parameterization, Parameterization is nothing but testing a method / test using multople data. Parameterized tests make it possible to run a test multiple times with different arguments.

In TestNG this is known as dataProvider, JUnit 5 provides much more options to test a method with multiple values

We will be using @ParameterizedTest instead of @Test annotations, along with @ParameterizedTest we also have to provide the source where to get the values

Different data sources :
1. @ValueSource
2. @EnumSource
3. @MethodSource
4. @CsvSource
5. @CsvFileSource
6. @ArgumentsSource

@ValueSource :

@ValueSource used for reading the data from a String array


										@ParameterizedTest
										@ValueSource(strings = {"one", "two", "three"})
										void testWithSimpleMethodSource(String value) {
											System.out.println(value);
										}
										

Output of the @ValueSource valuesource-junit-mockito

@EnumSource :

@EnumSource helps the user to read the data from the Enum, this annotation reads all the data from the Enum.


										// file 1
										public enum WeekDays {
											MONDAY,
											TUESDAY,
											WEDNESDAY,
											THURSDAY,
											FRIDAY;
										}
										
										// file 2
										@ParameterizedTest
										@EnumSource(WeekDays.class)
										void testWithSimpleEnumSource(WeekDays enus) {
											System.out.println(enus);
										}
										

Output of @EnumSource enumsource-parameterization-junit-mockito

We can also fetch only few values from the Enum instead of complete values. We have to set the names parameter as the values that we want to retrieve from the Enum.


										@ParameterizedTest
										@EnumSource(value = WeekDays.class, names = {"MONDAY", "FRIDAY"})
										void testWithSimpleFewEnumSource(WeekDays enus) {
											System.out.println(enus);
										}
										

Output of @EnumSource with few values. enumvalue-few-values-junit-mockito

@MethodSource :

@MethodSource allows you to refer to one or more factory methods of the test class. Such methods must return a Stream, Iterable, Iterator, or array of arguments.

In addition, such methods must not accept any arguments. By default such methods must be static unless the test class is annotated with @TestInstance(Lifecycle.PER_CLASS).


										@ParameterizedTest
										@MethodSource("stringProvider")
										void testWithSimpleMethodSource(String argument) {
											System.out.println(argument);
										}

										static Stream stringProvider() {
											return Stream.of("abc", "bcd", "xyz");
										}
										

Output of @MethodSource methodsource-junit-mockito

If you do not explicitly provide a factory method name via @MethodSource, JUnit Jupiter will search for a factory method that has the same name as the current @ParameterizedTest method by convention.

Note : This method is still in development mode so it will not work, When I was writing this tutorial. below method didnot work.


										@ParameterizedTest
										@MethodSource
										void testWithSimpleMethodSourceHavingNoValue(String argument) {
											assertNotNull(argument);
										}

										static Stream testWithSimpleMethodSourceHavingNoValue() {
											return Stream.of("foo", "bar");
										}
										

@CsvSource :

@CsvSource annotations allows user to read from the Comma seprated values as parameter (not as .csv file), With CSV values we can read more than one parameter and as different data type parameter.

In below example we are reading the String and int value.


										@ParameterizedTest
										@CsvSource({ "one, 1", "two, 2", "'three, tres', 3" })
										void testWithCsvSource(String first, int second) {
											System.out.println(first + " ::: "+ second);
										}
										

Output of the @CsvSource csvsource-junit5-mockito

Below table explains what happens when the Junit parses the CSV values.

Example Input Resulting Argument List

@CsvSource({ "foo, bar" })

"foo", "bar"

@CsvSource({ "foo, 'baz, qux'" })

"foo", "baz, qux"

@CsvSource({ "foo, ''" })

"foo", ""

@CsvSource({ "foo, " })

"foo", null

@CsvFileSource :

@CsvFileSource lets the user to read the data from the csv file rather than reading from program. Each line from a CSV file results in one invocation of the parameterized test.


		@ParameterizedTest
		@CsvFileSource(resources = "/h.csv")
		void testWithCsvFileSource(String first, int second) {
			System.out.println(first+ " :: "+second);
		}
		

About Author

Myself KarthiQ, I am the author of this blog, I know ways to write a good article but some how I donot have the skills to make it to reach people, would you like help me to reach more people By sharing this Article in the social media.

Share this Article Facebook
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions

Recent Addition

new tutorial Registrations for Selenium Online Training is Over.

Below are the training details:
Meeting link : https://zoom.us/j/737840591
Starting Time : 9:00PM 18th DEC 2018
 
Join My Facebook Group
Join Group