Oke, saya tahu Anda mungkin menginginkan beberapa properti mudah yang dapat Anda tentukan di @BeforeClass Anda atau sesuatu seperti itu, tetapi kami mungkin harus menunggu untuk diimplementasikan. Setidaknya aku juga tidak bisa menemukannya.
Berikut ini adalah jelek sekali tetapi saya pikir itu melakukan pekerjaan, setidaknya dalam skala kecil, dibiarkan untuk melihat bagaimana berperilaku dalam skenario yang lebih kompleks. Mungkin dengan lebih banyak waktu, ini bisa diperbaiki menjadi sesuatu yang lebih baik.
Oke, jadi saya membuat Kelas Tes yang serupa dengan Anda:
public class RetryTest extends TestConfig {
public class RetryTest extends TestConfig {
Assertion assertion = new Assertion();
@Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
ignoreMissingDependencies = false)
public void testStep_1() {
}
@Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
dependsOnMethods = "testStep_1",
ignoreMissingDependencies = false)
public void testStep_2() {
if (fail) assertion.fail("This will fail the first time and not the second.");
}
@Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
dependsOnMethods = "testStep_2",
ignoreMissingDependencies = false)
public void testStep_3() {
}
@Test( enabled = true)
public void testStep_4() {
assertion.fail("This should leave a failure in the end.");
}
}
Saya memiliki Listener
kelas super hanya dalam kasus saya ingin memperluas ini ke kelas lain, tetapi Anda juga dapat mengatur pendengar di kelas tes Anda.
@Listeners(TestListener.class)
public class TestConfig {
protected static boolean retrySuccessful = false;
protected static boolean fail = true;
}
Tiga dari 4 metode di atas memiliki a RetryAnalyzer
. Saya meninggalkan testStep_4
tanpa itu untuk memastikan bahwa apa yang saya lakukan selanjutnya tidak mengacaukan sisa eksekusi. Said RetryAnalyzer
tidak akan benar-benar mencoba lagi (perhatikan bahwa metode kembali false
), tetapi akan melakukan hal berikut:
public class TestRetry implements IRetryAnalyzer {
public static TestNG retryTestNG = null;
@Override
public boolean retry(ITestResult result) {
Class[] classes = {CreateBookingTest.class};
TestNG retryTestNG = new TestNG();
retryTestNG.setDefaultTestName("RETRY TEST");
retryTestNG.setTestClasses(classes);
retryTestNG.setGroups("retryTest");
retryTestNG.addListener(new RetryAnnotationTransformer());
retryTestNG.addListener(new TestListenerRetry());
retryTestNG.run();
return false;
}
}
Ini akan membuat eksekusi di dalam eksekusi Anda. Itu tidak akan mengacaukan laporan, dan segera setelah selesai, itu akan melanjutkan dengan eksekusi utama Anda. Tetapi itu akan "mencoba kembali" metode dalam grup itu.
Ya saya tahu, saya tahu. Ini berarti bahwa Anda akan menjalankan suite pengujian Anda selamanya dalam lingkaran yang abadi. Itu sebabnya RetryAnnotationTransformer
. Di dalamnya, kami akan menghapus RetryAnalyzer dari eksekusi kedua tes tersebut:
public class RetryAnnotationTransformer extends TestConfig implements IAnnotationTransformer {
@SuppressWarnings("rawtypes")
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
fail = false; // This is just for debugging. Will make testStep_2 pass in the second run.
annotation.setRetryAnalyzer(null);
}
}
Sekarang kita memiliki yang terakhir dari masalah kita. Rangkaian uji asli kami tidak tahu tentang eksekusi "coba lagi" di sana. Di sinilah ia menjadi sangat jelek. Kita perlu memberi tahu Reporter kita apa yang baru saja terjadi. Dan ini adalah bagian yang saya anjurkan agar Anda tingkatkan. Saya kekurangan waktu untuk melakukan sesuatu yang lebih baik, tetapi jika saya bisa, saya akan mengeditnya di beberapa titik.
Pertama, kita perlu tahu apakah eksekusi retryTestNG berhasil. Mungkin ada sejuta cara untuk melakukan ini dengan lebih baik, tetapi untuk sekarang ini berfungsi. Saya mengatur pendengar hanya untuk eksekusi ulang. Anda dapat melihatnya di TestRetry
atas, dan terdiri dari yang berikut ini:
public class TestListenerRetry extends TestConfig implements ITestListener {
(...)
@Override
public void onFinish(ITestContext context) {
if (context.getFailedTests().size()==0 && context.getSkippedTests().size()==0) {
successful = true;
}
}
}
Sekarang Pendengar dari suite utama, yang Anda lihat di atas di kelas super TestConfig
akan melihat apakah itu terjadi dan jika berjalan dengan baik dan akan memperbarui laporan:
public class TestListener extends TestConfig implements ITestListener , ISuiteListener {
(...)
@Override
public void onFinish(ISuite suite) {
if (TestRetry.retryTestNG != null) {
for (ITestNGMethod iTestNGMethod : suite.getMethodsByGroups().get("retryTest")) {
Collection<ISuiteResult> iSuiteResultList = suite.getResults().values();
for (ISuiteResult iSuiteResult : iSuiteResultList) {
ITestContext iTestContext = iSuiteResult.getTestContext();
List<ITestResult> unsuccessfulMethods = new ArrayList<ITestResult>();
for (ITestResult iTestResult : iTestContext.getFailedTests().getAllResults()) {
if (iTestResult.getMethod().equals(iTestNGMethod)) {
iTestContext.getFailedTests().removeResult(iTestResult);
unsuccessfulMethods.add(iTestResult);
}
}
for (ITestResult iTestResult : iTestContext.getSkippedTests().getAllResults()) {
if (iTestResult.getMethod().equals(iTestNGMethod)) {
iTestContext.getSkippedTests().removeResult(iTestResult);
unsuccessfulMethods.add(iTestResult);
}
}
for (ITestResult iTestResult : unsuccessfulMethods) {
iTestResult.setStatus(1);
iTestContext.getPassedTests().addResult(iTestResult, iTestResult.getMethod());
}
}
}
}
}
}
Laporan tersebut harus menunjukkan sekarang 3 tes lulus (karena mereka coba lagi) dan satu gagal karena itu bukan bagian dari 3 tes lainnya:
Saya tahu itu bukan apa yang Anda cari, tetapi saya membantu ini melayani Anda sampai mereka menambahkan fungsionalitas ke TestNG.