回答:
@assyliasに同意しますが、使用@BeforeClass
は古典的な解決策であり、常に便利であるとは限りません。アノテーションが付けられたメソッドは@BeforeClass
静的でなければなりません。テストケースのインスタンスを必要とする一部のテストでは、非常に不便です。たとえば、Spring @Autowired
コンテキストで定義されたサービスを操作するために使用するSpringベースのテスト。
この場合、私はsetUp()
注釈付きの通常のメソッドを個人的に使用し@Before
、カスタムstatic
(!) boolean
フラグを管理します。
private static boolean setUpIsDone = false;
.....
public void setUp() {
if (setUpIsDone) {
return;
}
// do the setup
setUpIsDone = true;
}
setUp()
メソッドがスーパークラスにある場合を除いて機能します- これを解決するために以下の回答を投稿しました。
あなたは使用することができ、注釈を。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
注釈すべての注入の値が利用可能であるインスタンスのコンテキストでテストクラスの任意の方法を実行することができます。
私の汚い解決策は:
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実行当たりの時間を。
Springの@PostConstructメソッドを使用してすべての初期化作業を行い、このメソッドは@Testが実行される前に実行されます