Tuesday, 4 June 2013

BDD: Running Twist Features Inside Unit Tests

The following code is a work around to support running Twist features within Unit Test through any IDE.

It's quite useful when debugging scenarios and you've just had enough of the Eclipse Plugin or would just prefer to use something else! :-)

I hope it proves useful to other Twist users out there.

package com.test.twist.runner;

import com.thoughtworks.twist.core.execution.ant.ScenarioExecutorAntMain;
import org.springframework.test.util.ReflectionTestUtils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import static com.thoughtworks.twist.core.execution.ant.ScenarioExecutorAntMain.*;

public abstract class AbstractTwistScenarioRunner {

    private static final String PROJECT_FOLDER = "integrationtest";

    enum TwistScenarioResult{

        PASS(PASS_EXIT_CODE),
        FAILURE(FAILURE_EXIT_CODE),
        ERROR(ERROR_EXIT_CODE),
        FAILURE_AND_ERROR(FAILURE_AND_ERROR_EXIT_CODE),
        UNKNOWN(-1);

        private int exitCode;

        TwistScenarioResult(int exitCode){
            this.exitCode = exitCode;
        }

        public static TwistScenarioResult fromExitCode(int exitCode){
            for(TwistScenarioResult result : TwistScenarioResult.values()){
                if (result.exitCode == exitCode){
                    return result;
                }
            }
            return UNKNOWN;
        }
    }

    protected ScenarioExecutorAntMain initExecutor(String reportsDirectory, String configurationDirectory, String         scenariosDirectory){
        Map parameters = new HashMap(6);
        parameters.put("reportsDir", new File(PROJECT_FOLDER + reportsDirectory));
        parameters.put("confDir", new File(PROJECT_FOLDER + configurationDirectory));
        parameters.put("scenarioDir", new File(PROJECT_FOLDER + scenariosDirectory));
        parameters.put("tags", "ignored");
        parameters.put("numberOfThreads", 1);
        parameters.put("scenariosListFile", null);
        return new ScenarioExecutorAntMain(parameters);
    }

    protected TwistScenarioResult executeScenarios(ScenarioExecutorAntMain executor, String tags){
    
    ReflectionTestUtils.setField(executor, "tags", tags);
        ScenarioExecutorAntMain.ExitCodeListener exitCodeListener = executor.start();
        int twistExitCode = executor.exitCode(exitCodeListener);
            return TwistScenarioResult.fromExitCode(twistExitCode);
        }
}

And the test implementation:

package com.test.twist.runner;

import com.thoughtworks.twist.core.execution.ant.ScenarioExecutorAntMain;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.fest.assertions.Assertions.assertThat;

/**
* Allows Twist Tests to be run inside Intellij and makes use of Intellij debugging!
*/
public class TwistScenarioRunner extends AbstractTwistScenarioRunner {

  private ScenarioExecutorAntMain scenarioExecutor;

  @BeforeMethod
  public void setUp(){
      String reportsDirectory = "/target/surefire-reports";
      String configurationDirectory = "/twist-conf";
      String scenariosDirectory = "/scenarios";
      scenarioExecutor = initExecutor(reportsDirectory, configurationDirectory, scenariosDirectory);
  }

  @Test
  public void shouldExecuteSpecificScenarios() throws Exception {
      assertThat(executeScenarios(scenarioExecutor, "my-scenario,!in-progress,!ignore")).as("My Scenarios").isEqualTo(TwistScenarioResult.PASS);
  }

}

No comments:

Post a Comment