Repository navigation
Expand file tree
/
Copy pathAnnotationOrderTest.java
More file actions
129 lines (114 loc) · 4.44 KB
/
Copy pathAnnotationOrderTest.java
File metadata and controls
129 lines (114 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Interview examples: TestNG
package com.automation.selenium.interview.testng;
// TestNG assertion
import static org.testng.Assert.assertEquals;
// The recorded calls, safe to add to from several threads
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
// The configuration annotations, in the order they run
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
// Marks a method (or every public method of a class) as a TestNG test
import org.testng.annotations.Test;
// Writes steps into the HTML report
import com.automation.selenium.utils.Steps;
/**
* Interview question: In what order do the TestNG annotations run?
* <p>
* Interview answer: From the outside in and back out: {@code @BeforeSuite},
* {@code @BeforeTest} (once per {@code <test>} tag), {@code @BeforeClass},
* {@code @BeforeMethod}, the {@code @Test}, then {@code @AfterMethod},
* {@code @AfterClass}, {@code @AfterTest} and {@code @AfterSuite}.
* Configuration methods need {@code alwaysRun = true} to run under a group
* filter.
* <p>
* Concept: from the outside in, then back out:
* <pre>
* @BeforeSuite once, before everything in the suite
* @BeforeTest once per <test> tag in testng.xml
* @BeforeClass once per class, before its first test
* @BeforeMethod before every test method
* @Test
* @AfterMethod after every test method
* @AfterClass after the class's last test
* @AfterTest after the <test> tag
* @AfterSuite once, at the very end
* </pre>
* Every method here records its name; the test checks the "before" half,
* and {@code @AfterSuite} prints the full list to the console.
* <p>
* Trap: configuration methods do not inherit the class-level
* {@code groups}. When the run filters by group ({@code -Dgroups=testng}),
* a configuration method without {@code alwaysRun = true} (or its own
* groups) is silently left out. That is why every one below has it, and
* why {@code BaseTest.startBrowser} has it.
* <p>
* No browser is needed, so this class does not extend {@code BaseTest}.
*/
@Test(groups = { "interview", "testng" })
public class AnnotationOrderTest {
// Every call, in the order it happened (synchronized: test classes run in parallel)
private static final List<String> CALLS = Collections.synchronizedList(new ArrayList<>());
/** Runs once, before any test of the suite. */
@BeforeSuite(alwaysRun = true)
public void beforeSuite() {
CALLS.add("@BeforeSuite");
}
/** Runs once per {@code <test>} tag (Maven without testng.xml makes one). */
@BeforeTest(alwaysRun = true)
public void beforeTest() {
CALLS.add("@BeforeTest");
}
/** Runs once, before the first test of this class. */
@BeforeClass(alwaysRun = true)
public void beforeClass() {
CALLS.add("@BeforeClass");
}
/** Runs before every test method of this class. */
@BeforeMethod(alwaysRun = true)
public void beforeMethod() {
CALLS.add("@BeforeMethod");
}
/**
* The only test: by the time it runs, the four "before" methods have
* run in order.
*/
@Test(description = "TestNG: configuration annotations run from suite down to method")
public void configurationMethodsRunInOrder() {
// The test itself
CALLS.add("@Test");
// Show the order in the report
Steps.log("Order so far: " + CALLS);
// Suite → test → class → method → the test
assertEquals(CALLS, List.of("@BeforeSuite", "@BeforeTest", "@BeforeClass", "@BeforeMethod", "@Test"), "Call order");
}
/** Runs after every test method of this class. */
@AfterMethod(alwaysRun = true)
public void afterMethod() {
CALLS.add("@AfterMethod");
}
/** Runs once, after the last test of this class. */
@AfterClass(alwaysRun = true)
public void afterClass() {
CALLS.add("@AfterClass");
}
/** Runs once per {@code <test>} tag, after all its classes. */
@AfterTest(alwaysRun = true)
public void afterTest() {
CALLS.add("@AfterTest");
}
/** Runs once, at the very end; prints the whole order to the console. */
@AfterSuite(alwaysRun = true)
public void afterSuite() {
CALLS.add("@AfterSuite");
// After the suite there is no test to attach a report step to, so print it
System.out.println("TestNG annotation order: " + CALLS);
}
}