---
description: Annotations are introduced in Junit4. we will learn Annotations like @Before, @BeforeClass, @After, @AfterClass, @Test, @Ignores etc.
title: JUnit Annotations Tutorial with Example: What is @Test and @After
image: https://www.guru99.com/images/junit-annotations-tutorial.png
---

 

[Skip to content](#main) 

**⚡ Smart Summary**

JUnit annotations are a form of syntactic metadata added to Java source code so a test runner knows which methods to execute, when to run them, and how long each may take.

* 🔘 **@Test:** Marks a public void method that JUnit executes as a single test case.
* ☑️ **Lifecycle:** @Before and @After wrap every test, while @BeforeClass and @AfterClass wrap the class.
* ✅ **Control:** @Ignore skips a test, @Test(timeout) caps runtime, @Test(expected) asserts a thrown exception.
* 🧪 **Assertions:** org.junit.Assert supplies assertEquals, assertTrue, assertNull, assertSame and fail().
* 🛠️ **Legacy:** TestCase, TestResult and TestSuite belong to the older junit.framework package.
* 📊 **JUnit 5:** Jupiter renames these to @BeforeEach, @AfterEach, @BeforeAll, @AfterAll and @Disabled.

[ Read More ](javascript:void%280%29;) 

![JUnit annotations tutorial covering @Test, @Before and @After]() 

## What is JUnit Annotations?

**JUnit annotations** are a special form of syntactic meta-data that can be added to Java source code for better code readability and structure. Variables, parameters, packages, methods and classes can be annotated. Annotations were introduced in JUnit 4, which makes Java code more readable and simple. This is the big difference between JUnit 3 and JUnit 4: JUnit 4 is annotation based.

With a working knowledge of these annotations, one can easily learn and implement a [JUnit](https://www.guru99.com/junit-tutorial.html) test. Below is the important and frequently used JUnit annotations list, with the JUnit 5 (Jupiter) equivalent beside each one:

| S.No. | Annotations                                    | Description                                                                                                                                                                                                      | JUnit 5 equivalent            |
| ----- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
| 1.    | @Test                                          | This annotation is a replacement of junit.framework.TestCase, and indicates that the public void method to which it is attached can be executed as a test case.                                                  | @Test (org.junit.jupiter.api) |
| 2.    | @Before                                        | This annotation is used if you want to execute some statement such as preconditions before each test case.                                                                                                       | @BeforeEach                   |
| 3.    | @BeforeClass                                   | This annotation is used if you want to execute some statements before all the test cases, for example a test connection that must be opened before all the test cases.                                           | @BeforeAll                    |
| 4.    | @After                                         | This annotation can be used if you want to execute some statements after each [Test Case](https://www.guru99.com/test-case.html), for example resetting variables or deleting temporary files.                   | @AfterEach                    |
| 5.    | @AfterClass                                    | This annotation can be used if you want to execute some statements after all test cases, for example releasing resources after executing all test cases.                                                         | @AfterAll                     |
| 6.    | @Ignore                                        | This annotation can be used if you want to ignore some statements during test execution, for example disabling some test cases during test execution.                                                            | @Disabled                     |
| 7.    | @Test(timeout=500)                             | This annotation can be used if you want to set some timeout during test execution, for example if you are working under an SLA (service level agreement) and tests need to be completed within a specified time. | @Timeout or assertTimeout     |
| 8.    | @Test(expected=IllegalArgumentException.class) | This annotation can be used if you want to handle some exception during test execution. For example, if you want to check whether a particular method is throwing a specified exception or not.                  | assertThrows                  |

## JUnit Annotations Example

Let’s create a class covering important JUnit annotations with simple print statements and execute it with a test runner class:

**Step 1)** Consider the below Java class having various methods which are attached to the above-listed annotations:

### JunitAnnotationsExample.java

package guru99.junit;		

import static org.junit.Assert.assertEquals;				
import static org.junit.Assert.assertFalse;				

import java.util.ArrayList;		

import org.junit.After;		
import org.junit.AfterClass;		
import org.junit.Before;		
import org.junit.BeforeClass;		
import org.junit.Ignore;		
import org.junit.Test;		

public class JunitAnnotationsExample {				

    private ArrayList<String> list;					

    @BeforeClass		
    public static void m1() {							
        System.out.println("Using @BeforeClass , executed before all test cases ");					
    }		

    @Before		
    public void m2() {					
        list = new ArrayList<String>();					
        System.out.println("Using @Before annotations ,executed before each test cases ");					
    }		

    @AfterClass		
    public static void m3() {							
        System.out.println("Using @AfterClass ,executed after all test cases");					
    }		

    @After		
    public void m4() {					
        list.clear();			
        System.out.println("Using @After ,executed after each test cases");					
    }		

    @Test		
    public void m5() {					
        list.add("test");					
        assertFalse(list.isEmpty());			
        assertEquals(1, list.size());			
    }		

    @Ignore		
    public void m6() {					
        System.out.println("Using @Ignore , this execution is ignored");					
    }		

    @Test(timeout = 10)			
    public void m7() {					
        System.out.println("Using @Test(timeout),it can be used to enforce timeout in JUnit4 test case");					
    }		

    @Test(expected = NoSuchMethodException.class)					
    public void m8() {					
        System.out.println("Using @Test(expected) ,it will check for specified exception during its execution");					

    }		

}		

**Step 2)** Let’s create a test runner class to execute the above test:

### TestRunner.java

package guru99.junit;		

import org.junit.runner.JUnitCore;		
import org.junit.runner.Result;		
import org.junit.runner.notification.Failure;		

public class TestRunner {				
			public static void main(String[] args) {									
      Result result = JUnitCore.runClasses(JunitAnnotationsExample.class);					
			for (Failure failure : result.getFailures()) {							
         System.out.println(failure.toString());					
      }		
      System.out.println("Result=="+result.wasSuccessful());							
   }		
}      	

### Expected Result

* All the test cases will be executed one by one, and all print statements can be seen on a console.
* As discussed in the above table, @Before and @BeforeClass in JUnit \[ methods m2() and m1() \] will be executed before each test case and before all test cases respectively.
* In the same way @After and @AfterClass in JUnit (methods m4() and m3()) will be executed after each test case and after all test cases respectively. @Ignore (method m6()) will be treated as ignoring the test.

Let’s analyse the test cases used in the above Java class in detail:

1. Consider method m5() as given below:

	@Test		
    public void m5() {					
        list.add("test");					
        assertFalse(list.isEmpty());			
        assertEquals(1, list.size());			
    }		

In the above method, as you are adding a string to the variable “list”:

* **list.isEmpty()** will return false.
* **assertFalse(list.isEmpty())** must return true.
* As a result, the test case will **pass**.

As you have added only one string to the list, the size is one.

* **list.size()** must return the int value “1”.
* So **assertEquals(1, list.size())** must return true.
* As a result, the test case will **pass**.
1. Consider method m7() as given below:

@Test(timeout = 10)		
    public void m7() {					
        System.out.println("Using @Test(timeout),it can be used to enforce timeout in JUnit4 test case");					
    }		

As discussed above, **@Test(timeout = 10)** is used to enforce a timeout in the test case. The value is in milliseconds, so m7() must finish within 10 ms.

1. Consider method m8() as given below:

@Test(expected = NoSuchMethodException.class)				
    public void m8() {					
        System.out.println("Using @Test(expected) ,it will check for specified exception during its execution");					
    
    }		

As discussed above, **@Test(expected)** will check for the specified exception during its execution, so method m8() will throw “No Such Method Exception.” As a result, the test will be executed with an exception.

**Accuracy note:** m8() only prints a line, so the declared exception is never actually thrown and JUnit 4 reports the test as failed. Align the expected type with what the method really throws. JUnit 5 writes this with **assertThrows**.

As all test cases are passed, this results in a successful test execution.

### Actual Result

As there are three test cases in the above example, all test cases will be executed one by one. See the console screenshot below:

[](https://www.guru99.com/images/junit/052416%5F0549%5FJUnitAnnota1.png)

Console output produced by JunitAnnotationsExample

**See below print statements which can be seen on console:**

Using @BeforeClass , executed before all test cases

Using @Before annotations, executed before each test cases

Using @After, executed after each test cases

Using @Before annotations, executed before each test cases

Using @Test(timeout),it can be used to enforce timeout in JUnit4 test case

Using @After, executed after each test cases

Using @Before annotations, executed before each test cases

Using @Test(expected) ,it will check for specified exception during its execution

Using @After, executed after each test cases

Using @AfterClass, executed after all test cases

### RELATED ARTICLES

* [Junit Assert & AssertEquals with Example ](https://www.guru99.com/junit-assert.html "Junit Assert & AssertEquals with Example")
* [Create JUnit Test Suite with Example: @RunWith @SuiteClasses ](https://www.guru99.com/create-junit-test-suite.html "Create JUnit Test Suite with Example: @RunWith @SuiteClasses")
* [JUnit @Ignore Test Annotation with Example ](https://www.guru99.com/junit-ignore-test.html "JUnit @Ignore Test Annotation with Example")
* [JUnit Expected Exception Test: @Test(expected) ](https://www.guru99.com/junit-exception-test.html "JUnit Expected Exception Test: @Test(expected)")

## JUnit Assert Class

The annotations decide when a method runs; the assert methods decide whether it passes.

This class provides a bunch of assertion methods useful in writing a test case. If all assert statements are passed, test results are successful. If any assert statement fails, test results are failed. The dedicated [JUnit assert](https://www.guru99.com/junit-assert.html) tutorial covers each method in depth.

As you have seen earlier, the below table describes important Assert methods and their description:

| S.No. | Method                                              | Description                                                                                     |
| ----- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| 1.    | void assertEquals(boolean expected, boolean actual) | It checks whether two values are equal, similar to the equals method of the Object class.       |
| 2.    | void assertFalse(boolean condition)                 | Functionality is to check that a condition is false.                                            |
| 3.    | void assertNotNull(Object object)                   | “assertNotNull” functionality is to check that an object is not null.                           |
| 4.    | void assertNull(Object object)                      | “assertNull” functionality is to check that an object is null.                                  |
| 5.    | void assertTrue(boolean condition)                  | “assertTrue” functionality is to check that a condition is true.                                |
| 6.    | void fail()                                         | If you want to throw an assertion error, fail() always results in a fail verdict.               |
| 7.    | void assertSame(\[String message\]                  | “assertSame” functionality is to check that the two objects refer to the same object.           |
| 8.    | void assertNotSame(\[String message\]               | “assertNotSame” functionality is to check that the two objects do not refer to the same object. |

## JUnit Test Cases Class

To run multiple tests, the TestCase class is available in the **junit.framework** package. The @Test annotation tells JUnit that this public void method (a test case here) to which it is attached can be run as a test case.

**Version note:** **TestCase**, **TestResult** and **TestSuite** belong to the legacy **junit.framework** package from JUnit 3\. They still ship inside the junit 4.x artifact, but annotation-based tests do not extend TestCase.

The below table shows some important methods available in the **junit.framework.TestCase** class:

| S.No. | Method                      | Description                                                                                                                               |
| ----- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| 1.    | int countTestCases()        | This method is used to count how many test cases are executed by the **run(TestResult tr)** method.                                       |
| 2.    | TestResult createResult()   | This method is used to create a **TestResult** object.                                                                                    |
| 3.    | String getName()            | This method returns a string which is nothing but a **TestCase** name.                                                                    |
| 4.    | TestResult run()            | This method is used to execute a test, which returns a **TestResult** object.                                                             |
| 5.    | void run(TestResult result) | This method is used to execute a test having a **TestResult** object, which does not return anything.                                     |
| 6.    | void setName(String name)   | This method is used to set the name of a **TestCase.**                                                                                    |
| 7.    | void setUp()                | This method is used to write resource association code, for example creating a database connection.                                       |
| 8.    | void tearDown()             | This method is used to write resource release code, for example releasing a database connection after performing a transaction operation. |

## JUnit TestResult Class

When you execute a test, it returns a result (in the form of a **TestResult** object). This TestResult object can be used to analyse the resultant object. This test result can be either failure or successful.

See the below table for important methods used in the junit.framework.TestResult class:

| S.No. | Method                                             | Description                                                                      |
| ----- | -------------------------------------------------- | -------------------------------------------------------------------------------- |
| 1.    | void addError(Test test, Throwable t)              | This method is used if you require to add an error to the test.                  |
| 2.    | void addFailure(Test test, AssertionFailedError t) | This method is used if you require to add a failure to the list of failures.     |
| 3.    | void endTest(Test test)                            | This method is used to notify that a test is performed (completed).              |
| 4.    | int errorCount()                                   | This method is used to get the errors detected during test execution.            |
| 5.    | Enumeration<TestFailure> errors()                  | This method simply returns a collection (an Enumeration here) of errors.         |
| 6.    | int failureCount()                                 | This method is used to get the count of failures detected during test execution. |
| 7.    | void run(TestCase test)                            | This method is used to execute a test case.                                      |
| 8.    | int runCount()                                     | This method simply counts the executed tests.                                    |
| 9.    | void startTest(Test test)                          | This method is used to notify that a test is started.                            |
| 10.   | void stop()                                        | This method is used to make the test run stop.                                   |

## JUnit Test Suite Class

If you want to execute multiple tests in a specified order, it can be done by combining all the tests in one place. This place is called a test suite, and the [JUnit test suite](https://www.guru99.com/create-junit-test-suite.html) tutorial walks through a full example.

See the below table for important methods used in the **junit.framework.TestSuite** class:

| S.No. | Method                                                 | Description                                                                                   |
| ----- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
| 1.    | void addTest(Test test)                                | This method is used if you want to add a test to the suite.                                   |
| 2.    | void addTestSuite(Class<? extends TestCase> testClass) | This method is used if you want to specify the class while adding a test to the suite.        |
| 3.    | int countTestCases()                                   | This method is used if you want to count the number of test cases.                            |
| 4.    | String getName()                                       | This method is used to get the name of the test suite.                                        |
| 5.    | void run(TestResult result)                            | This method is used to execute a test and collect the test result in a **TestResult** object. |
| 6.    | void setName(String name)                              | This method is used to set the name of the **TestSuite**.                                     |
| 7.    | Test testAt(int index)                                 | This method is used if you want to return the test at a given index.                          |
| 8.    | int testCount()                                        | This method is used if you want to return the number of tests in the suite.                   |
| 9.    | static Test warning(String message)                    | This method returns a test which will fail and log a warning message.                         |

## FAQs

🚦 Can one method carry more than one JUnit annotation?

Yes. A method commonly carries @Test together with @Ignore, or @Test with both a timeout and an expected exception. You cannot stack two lifecycle annotations, such as @Before and @After, on one method.

🚫 Why does @Ignore on its own never appear in the report?

@Ignore only suppresses a method JUnit already recognises as a test. Without @Test beside it the runner never collects the method, so it is neither run nor listed as skipped.

⏱️ What happens when a @Test(timeout) value is exceeded?

JUnit runs the method on a separate thread and fails it with a TestTimedOutException once the budget elapses. The thread is interrupted, not killed, so a blocking call may keep running.

🔀 Do JUnit 4 annotations still work under JUnit 5?

Only through the vintage engine. Adding junit-vintage-engine lets the JUnit Platform run existing org.junit tests unchanged, but Jupiter tests must import org.junit.jupiter.api. Mixing both import sets in one class fails.

📚 Is it still worth learning the junit.framework classes?

Only for maintenance. Legacy suites that extend TestCase and build TestSuite objects remain common in older codebases, so recognising the API helps. New tests should be annotation based.

🧷 Why must @BeforeClass be declared static?

JUnit builds a new instance of the test class for every test method, so none exists when class-level setup must run. A static method needs no instance, and JUnit rejects a non-static declaration.

🤖 How can AI help pick the right JUnit annotation?

AI assistants read the method under test and suggest whether setup belongs in @Before or @BeforeClass, and whether a failure path needs @Test(expected) or assertThrows. Treat every suggestion as a draft.

💡 Does GitHub Copilot add lifecycle annotations correctly?

[GitHub Copilot](https://github.com/features/copilot) usually places setup and teardown correctly, but it frequently mixes JUnit 4 and Jupiter imports in one file. Check the import block before running the suite.

#### Summarize this post with:

ChatGPT Perplexity Grok Google AI 

**Stay Updated on AI** **Get Weekly AI Skills, Trends, Actionable Advice.** 

##### Sign up for the newsletter

Subscribe for Free 

You have successfully subscribed.  
Please check your inbox. 

![AI-Newsletter]() Chosen by over **350,000+** professionals 

[Scroll to top ](#wrapper)Scroll to top 

× 

Toggle Menu Close 

Search for: 

Search

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://www.guru99.com/#organization","name":"Guru99","sameAs":["https://www.facebook.com/Guru99Official","https://twitter.com/guru99com"],"logo":{"@type":"ImageObject","@id":"https://www.guru99.com/#logo","url":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","contentUrl":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","caption":"Guru99","inLanguage":"en-US"}},{"@type":"WebSite","@id":"https://www.guru99.com/#website","url":"https://www.guru99.com","name":"Guru99","publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https://www.guru99.com/images/junit-annotations-tutorial.png","url":"https://www.guru99.com/images/junit-annotations-tutorial.png","width":"700","height":"250","caption":"JUnit Annotations Tutorial","inLanguage":"en-US"},{"@type":"BreadcrumbList","@id":"https://www.guru99.com/junit-annotations-api.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":"1","item":{"@id":"https://www.guru99.com","name":"Home"}},{"@type":"ListItem","position":"2","item":{"@id":"https://www.guru99.com/junit","name":"JUnit"}},{"@type":"ListItem","position":"3","item":{"@id":"https://www.guru99.com/junit-annotations-api.html","name":"JUnit Annotations Tutorial with Example: What is @Test and @After"}}]},{"@type":"WebPage","@id":"https://www.guru99.com/junit-annotations-api.html#webpage","url":"https://www.guru99.com/junit-annotations-api.html","name":"JUnit Annotations Tutorial with Example: What is @Test and @After","dateModified":"2026-07-29T17:17:53+05:30","isPartOf":{"@id":"https://www.guru99.com/#website"},"primaryImageOfPage":{"@id":"https://www.guru99.com/images/junit-annotations-tutorial.png"},"inLanguage":"en-US","breadcrumb":{"@id":"https://www.guru99.com/junit-annotations-api.html#breadcrumb"}},{"@type":"Person","@id":"https://www.guru99.com/author/thomas","name":"Thomas Hamilton","description":"I am Thomas Hamilton, a seasoned professional in software testing, specializing in crafting comprehensive guides to help you master your software testing skills.","url":"https://www.guru99.com/author/thomas","image":{"@type":"ImageObject","@id":"https://www.guru99.com/images/thomas-hamilton-author-v2-120x120.png","url":"https://www.guru99.com/images/thomas-hamilton-author-v2-120x120.png","caption":"Thomas Hamilton","inLanguage":"en-US"},"worksFor":{"@id":"https://www.guru99.com/#organization"}},{"articleSection":"JUnit","headline":"JUnit Annotations Tutorial with Example: What is @Test and @After","description":"Annotations are introduced in Junit4. we will learn Annotations like @Before, @BeforeClass, @After, @AfterClass, @Test, @Ignores etc.","keywords":"junit","speakable":{"@type":"SpeakableSpecification","cssSelector":[".entry-title",".summary"]},"@type":"Article","author":{"@id":"https://www.guru99.com/author/thomas","name":"Thomas Hamilton"},"dateModified":"2026-07-29T17:17:53+05:30","image":{"@id":"https://www.guru99.com/images/junit-annotations-tutorial.png"},"copyrightYear":"2026","name":"JUnit Annotations Tutorial with Example: What is @Test and @After","subjectOf":[{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"Can one method carry more than one JUnit annotation?","acceptedAnswer":{"@type":"Answer","text":"Yes. A method commonly carries @Test together with @Ignore, or @Test with both a timeout and an expected exception. You cannot stack two lifecycle annotations, such as @Before and @After, on one method."}},{"@type":"Question","name":"Why does @Ignore on its own never appear in the report?","acceptedAnswer":{"@type":"Answer","text":"@Ignore only suppresses a method JUnit already recognises as a test. Without @Test beside it the runner never collects the method, so it is neither run nor listed as skipped."}},{"@type":"Question","name":"What happens when a @Test(timeout) value is exceeded?","acceptedAnswer":{"@type":"Answer","text":"JUnit runs the method on a separate thread and fails it with a TestTimedOutException once the budget elapses. The thread is interrupted, not killed, so a blocking call may keep running."}},{"@type":"Question","name":"Do JUnit 4 annotations still work under JUnit 5?","acceptedAnswer":{"@type":"Answer","text":"Only through the vintage engine. Adding junit-vintage-engine lets the JUnit Platform run existing org.junit tests unchanged, but Jupiter tests must import org.junit.jupiter.api. Mixing both import sets in one class fails."}},{"@type":"Question","name":"Is it still worth learning the junit.framework classes?","acceptedAnswer":{"@type":"Answer","text":"Only for maintenance. Legacy suites that extend TestCase and build TestSuite objects remain common in older codebases, so recognising the API helps. New tests should be annotation based."}},{"@type":"Question","name":"Why must @BeforeClass be declared static?","acceptedAnswer":{"@type":"Answer","text":"JUnit builds a new instance of the test class for every test method, so none exists when class-level setup must run. A static method needs no instance, and JUnit rejects a non-static declaration."}},{"@type":"Question","name":"How can AI help pick the right JUnit annotation?","acceptedAnswer":{"@type":"Answer","text":"AI assistants read the method under test and suggest whether setup belongs in @Before or @BeforeClass, and whether a failure path needs @Test(expected) or assertThrows. Treat every suggestion as a draft."}},{"@type":"Question","name":"Does GitHub Copilot add lifecycle annotations correctly?","acceptedAnswer":{"@type":"Answer","text":"GitHub Copilot usually places setup and teardown correctly, but it frequently mixes JUnit 4 and Jupiter imports in one file. Check the import block before running the suite."}}]}],"@id":"https://www.guru99.com/junit-annotations-api.html#schema-1154867","isPartOf":{"@id":"https://www.guru99.com/junit-annotations-api.html#webpage"},"publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US","mainEntityOfPage":{"@id":"https://www.guru99.com/junit-annotations-api.html#webpage"}}]}
```
