TestNG父类中的注解方法为何能随子类测试一同执行?
Great question! Let me break down exactly what's happening here—this is a super common (and really smart) pattern in TestNG test frameworks, so it’s worth understanding the "why" and "how" behind it.
How TestNG Handles Inheritance for Annotations
TestNG is built to recognize and execute annotations across the entire inheritance hierarchy of your test class. That means when you run your LoginTest (which extends TestCore), TestNG doesn’t only look at annotations directly in LoginTest—it scans every parent class (and even grandparent classes, if you have them) to find methods marked with TestNG annotations like @BeforeMethod, @AfterMethod, @Test, etc.
This intentional behavior is designed to make code reuse easier. Your TestCore class holds all the common setup/cleanup logic (like initializing a WebDriver, loading configs, or setting up test data) that every test class will need. Instead of copying that code into every single test class, you can just have your test classes inherit from TestCore and let TestNG handle running those shared methods automatically.
Example to Illustrate the Flow
Let’s map this to your exact scenario with code snippets:
Parent Class: TestCore
import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; public class TestCore { @BeforeMethod public void setUp() { // Initialize driver, variables, or other test dependencies System.out.println("Running @BeforeMethod from TestCore"); } @AfterMethod public void tearDown() { // Clean up resources like closing the driver System.out.println("Running @AfterMethod from TestCore"); } }
Child Class: LoginTest
import org.testng.annotations.Test; public class LoginTest extends TestCore { @Test public void testValidLogin() { // Your actual login test logic here System.out.println("Running testValidLogin from LoginTest"); } @Test public void testInvalidLogin() { // Another login test case System.out.println("Running testInvalidLogin from LoginTest"); } }
What Happens When You Run LoginTest?
For each @Test method in LoginTest, TestNG will execute this sequence:
- Run
TestCore's@BeforeMethod(setUp) - Run the
@Testmethod fromLoginTest - Run
TestCore's@AfterMethod(tearDown)
Your output would look like this:
Running @BeforeMethod from TestCore Running testValidLogin from LoginTest Running @AfterMethod from TestCore Running @BeforeMethod from TestCore Running testInvalidLogin from LoginTest Running @AfterMethod from TestCore
Bonus: What If Child Class Has Its Own Annotations?
If you add a @BeforeMethod or @AfterMethod directly in LoginTest, TestNG follows a specific execution order:
- For
@BeforeMethod: Parent class methods run first, then child class methods - For
@AfterMethod: Child class methods run first, then parent class methods
You can override this default order using the priority parameter (e.g., @BeforeMethod(priority = 1)), but the inheritance-based execution is the out-of-the-box behavior.
Under the Hood: How TestNG Does This
TestNG uses Java’s reflection API to inspect your test class and all its parent classes. It collects all methods annotated with TestNG’s annotations, sorts them according to built-in rules (like priority, inheritance order), and then executes them in the correct sequence.
内容的提问来源于stack exchange,提问作者user9134826

