3

Can anyone help me to rerun failed features in karate. below are the cucumber options and runner test which is using for parallel -

@CucumberOptions(features = "classpath:features/xxxxx/crud_api",
        format = {"pretty", "html:target/cucumber","json:target/cucumber/report.json", "rerun:target/rerun/rerun.txt" })



@Test
    public void  test() throws IOException {
        Results results = KarateRunnerTest.parallel(getClass(), threadCount, karateOutputPath);
        assertTrue("there are scenario failures", results.getFailCount() == 0);
    }
Mr. Venkat
  • 101
  • 1
  • 8

3 Answers3

2

Here is my reusable implementation using karate-1.0#retry-framework-experimental,

Results retryFailedTests(Results results) {
        System.out.println("======== Retrying failed tests ========");

        Results initialResults = results;
        List<ScenarioResult> retryResult = results.getScenarioResults().filter(ScenarioResult::isFailed)
                .parallel()
                .map(scenarioResult -> initialResults.getSuite().retryScenario(scenarioResult.getScenario()))
                .collect(Collectors.toList());
        for (ScenarioResult scenarioResult : retryResult) {
            results = results.getSuite().updateResults(scenarioResult);
        }
        return results;
    }

This java function takes care of retrying failed scenarios in parallel. You can check karate-timeline.html report to verify if the failed scenarios are retried in parallel.

Karthik P
  • 481
  • 5
  • 9
1

Sharing my solution for when using the standalone JAR, implemented as a RuntimeHook (requires Karate 1.0+):

package retries;

import com.intuit.karate.core.Tag;
import com.intuit.karate.RuntimeHook;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.core.ScenarioResult;
import com.intuit.karate.core.FeatureRuntime;
import com.intuit.karate.core.Scenario;
import com.intuit.karate.core.StepResult;
import com.intuit.karate.core.Step;
import java.util.HashSet;
import java.util.List;

/**
 * RuntimeHook that implements @retries tag.
 *
 * Usage:
 *   - compile this into a jar with:
 *       javac --release 8 -cp path/to/karate.jar *.java
 *       jar cvf retries-hook.jar *.class
 *   - tag your tests like @retries=3 to retry e.g. 3 times (4 total attempts)
 *   - invoke karate tests with:
 *       java -cp path/to/karate.jar:retries-hook.jar:path/to/java" com.intuit.karate.Main path/to/tests/dir --hook retries.RetriesHook
 */
public class RetriesHook implements RuntimeHook {

    private static final HashSet<Scenario> RETRIES_ATTEMPTED = new HashSet<Scenario>();
    private static final HashSet<ScenarioResult> RETRIES_SUCCEEDED = new HashSet<ScenarioResult>();

    @Override
    public void afterScenario(ScenarioRuntime sr) {
        if (!sr.isFailed()) {
            return;
        }

        int configuredRetries = 0;
        for (Tag tag : sr.tags) {
            if ("retries".equals(tag.getName())) {
                configuredRetries = Integer.parseInt(tag.getValues().get(0));
                break;
            }
        }
        if (configuredRetries <= 0) {
            return;
        }

        for (Scenario s : RETRIES_ATTEMPTED) {
            if (s.isEqualTo(sr.scenario)) {
                // we've already kicked off retries for this Scenario
                return;
            }
        }
        String scenarioName = sr.scenario.toString();

        RETRIES_ATTEMPTED.add(sr.scenario);
        int retryAttempt = 1;
        while (retryAttempt <= configuredRetries) {
            System.out.println("Scenario " + scenarioName + " failed, attempting retry #" + retryAttempt);
            ScenarioResult retrySr = sr.featureRuntime.suite.retryScenario(sr.scenario);
            if (!retrySr.isFailed()) {
                System.out.println("Scenario " + scenarioName + " passed after " + retryAttempt + " retries");
                // Mark the original ScenarioResult as passed on retry, so it can get filtered out later in afterFeature.
                RETRIES_SUCCEEDED.add(sr.result);
                sr.featureRuntime.result.getScenarioResults().add(retrySr);
                return;
            }
            retryAttempt++;
        }
        System.out.println("Scenario " + scenarioName + " failed all " + configuredRetries + " retries");
    }

    @Override
    public void afterFeature(FeatureRuntime fr) {
        // afterScenario is called before the original ScenarioResult is saved,
        // so we can't use Suite.updateResults() :/
        // Instead, we add the passed ScenarioResult above and then filter out the
        // failed one here.
        if (fr.result.isFailed()) {
            List<ScenarioResult> scenarioResults = fr.result.getScenarioResults();
            scenarioResults.removeIf(sr -> RETRIES_SUCCEEDED.contains(sr));
            fr.result.sortScenarioResults();
        }
    }
}
mariaines
  • 497
  • 1
  • 5
  • 17
0

This is not something that Karate supports, but in dev mode (using the IDE for example) you can always re-run the failed tests manually.

You seem to be using annotation options not supported by Karate, e.g. format. Read the docs for what is supported it is limited to features and tags.

EDIT - Karate 1.0 has experimental support for this: https://github.com/intuit/karate/wiki/1.0-upgrade-guide#retry-framework-experimental

Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
  • Hi @peter-thomas, is it possible to use this retry framework when using the standalone JAR? I imagine I have to implement a custom Runner somehow, but not seeing any examples of how to do that. – mariaines Nov 12 '21 at 21:09
  • 1
    @mariaines - ideally you should use the Java / Maven option, because you need to write code and compile it. but with the standalone JAR you can if you know what you are doing, refer: https://stackoverflow.com/a/56458094/143475 – Peter Thomas Nov 13 '21 at 02:33
  • 1
    8 months later and I finally took the time to figure something out Shared an answer below in case useful -- it is a little hacky but works https://stackoverflow.com/a/72890664/2034082 – mariaines Jul 06 '22 at 23:10
  • 1
    @mariaines sorry for not seeing this earlier, thanks so much for sharing, it will really help others – Peter Thomas Jan 26 '23 at 02:56
  • @PeterThomas : Is there a way Self Healing on change of locators is implemented in Karate, we have Helenium IO in selenium for self healing locators similarly is there anything available in Karate on healing the xpath in run time – Dinesh Tejaj Apr 07 '23 at 06:56
  • @DineshTejaj no. we invite code contributions – Peter Thomas Apr 07 '23 at 07:22