Answers:
尽管我同意@assylias的观点,即使用@BeforeClass
是经典的解决方案,但并不总是很方便。带有注释的方法@BeforeClass
必须是静态的。对于某些需要测试用例实例的测试来说,这非常不便。例如,基于Spring的测试可用于@Autowired
在Spring上下文中定义的服务。
在这种情况下,我个人使用setUp()
带有@Before
注释的常规方法并管理我的自定义static
(!) boolean
标志:
private static boolean setUpIsDone = false;
.....
@Before
public void setUp() {
if (setUpIsDone) {
return;
}
// do the setup
setUpIsDone = true;
}
您可以使用的BeforeClass
注释:
@BeforeClass
public static void setUpClass() {
//executed only once, before the first test
}
TheClassYouWant.class
而不是getClass()调用吗?这是实际的Java :String.class.getName()
。
JUnit 5现在具有@BeforeAll批注:
表示带注释的方法应该在当前类或类层次结构中的所有@Test方法之前执行;类似于JUnit 4的@BeforeClass。这样的方法必须是静态的。
JUnit 5的生命周期注释似乎终于正确了!您甚至不用看就能猜出可用的注释(例如@BeforeEach @AfterAll)
@BeforeClass
,那就是必须static
。IMO @AlexR的解决方案更好。
当setUp()
处于测试类的超类中时(例如,AbstractTestBase
下面),可以如下修改接受的答案:
public abstract class AbstractTestBase {
private static Class<? extends AbstractTestBase> testClass;
.....
public void setUp() {
if (this.getClass().equals(testClass)) {
return;
}
// do the setup - once per concrete test class
.....
testClass = this.getClass();
}
}
这应该适用于单一的非静态setUp()
方法,但是如果tearDown()
不深入复杂的思考世界,我将无法产生等效的结果……赏金指向任何可以的人!
编辑: 我只是在调试的时候才发现,该类也要在每次测试之前实例化。我猜@BeforeClass批注是最好的。
您也可以在构造函数上进行设置,毕竟测试类是一个类。我不确定这是否是一个不好的做法,因为几乎所有其他方法都带有注释,但是它可以工作。您可以创建一个类似的构造函数:
public UT () {
// initialize once here
}
@Test
// Some test here...
在测试之前将调用ctor,因为它们不是静态的。
尝试以下解决方案: https : //stackoverflow.com/a/46274919/907576:
使用@BeforeAllMethods
/ @AfterAllMethods
批注,您可以在实例上下文中执行Test类中的任何方法,在该实例上下文中,所有注入的值均可用。
我肮脏的解决方案是:
public class TestCaseExtended extends TestCase {
private boolean isInitialized = false;
private int serId;
@Override
public void setUp() throws Exception {
super.setUp();
if(!isInitialized) {
loadSaveNewSerId();
emptyTestResultsDirectory();
isInitialized = true;
}
}
...
}
我将其用作所有测试案例的基础。
如果您不想强制声明在每个子测试中设置并检查的变量,则可以将其添加到SuperTest中:
public abstract class SuperTest {
private static final ConcurrentHashMap<Class, Boolean> INITIALIZED = new ConcurrentHashMap<>();
protected final boolean initialized() {
final boolean[] absent = {false};
INITIALIZED.computeIfAbsent(this.getClass(), (klass)-> {
return absent[0] = true;
});
return !absent[0];
}
}
public class SubTest extends SuperTest {
@Before
public void before() {
if ( super.initialized() ) return;
... magic ...
}
}
我这样解决了这个问题:
将这部分代码添加到您的基本抽象类(我的意思是在setUpDriver()方法中初始化驱动程序的抽象类)中:
private static boolean started = false;
static{
if (!started) {
started = true;
try {
setUpDriver(); //method where you initialize your driver
} catch (MalformedURLException e) {
}
}
}
现在,如果你的测试类将从扩展基础抽象类- > setUpDriver()方法将被执行之前,首先@Test只ONE每次运行时间。