복붙노트

[SPRING] 단계 정의 파일간에 동일한 셀레늄 WebDriver 공유

SPRING

단계 정의 파일간에 동일한 셀레늄 WebDriver 공유

현재 우리는 Cucumber를 채택하여 Java8 / Spring 애플리케이션에서 기능 테스트를 수행하고 있습니다. 우리는 단계 정의 파일을 최대한 DRY 상태로 유지하고 다른 기능 파일에서 동일한 단계 정의를 사용하는 계획을 원합니다. 테스트를 진행하기 위해 셀레늄 WebDriver를 사용하기 때문에 단계 정의간에 동일한 드라이버를 공유해야합니다.

여러 드라이버를 사용하는 것이 왜 우리에게 중요한지를 보여주기 위해 페이지로 이동하는 방법과 해당 페이지에 줄이 표시되도록하는 방법의 두 단계로 정의 된 기능 파일을 생각해보십시오. 두 단계가 별도의 파일로 정의되는 경우 첫 번째 단계 정의는 드라이버를 사용하여 페이지를 탐색합니다. 두 번째 단계 정의가 해당 드라이버에 대해 어설 션을 실행하는 시점까지는 해당 페이지로 이동하지 않았으므로 (해당 작업이 다른 드라이버로 넘어 갔기 때문에) 테스트가 실패합니다.

각 단계 정의 파일이 확장 할 기본 클래스 (드라이버가 포함되어 있음)를 구현하려고했습니다. 결국 Cucumber는 각 단계 정의 클래스의 인스턴스를 인스턴스화하므로 서로 다른 WebDriver 인스턴스가있는 각 단계 정의로 끝납니다.

Spring을 사용하여 각 단계 정의 파일에 WebDriver의 인스턴스를 삽입하는 방법에 대해 생각했지만 위에서 설명한 것과 같은 문제가 발생할 것으로 생각됩니다.

싱글 톤 패턴이이를 달성하는 데 사용될 수 있다는 것을 알고 있지만, 우리는 그러한 공통적 인 문제처럼 보입니다. 싱글 톤 패턴은 과도한 느낌입니다. 실제로 이것이 올바른 접근 방법입니까? 또는 나는 정말 명백한 것을 놓치고 있는가?

당신의 도움에 미리 감사드립니다!

해결법

  1. ==============================

    1.cucumber-jvm과 함께 사용하기 위해 의존성 주입 프레임 워크로 pico-container를 사용하는 것이 좋습니다.

    cucumber-jvm과 함께 사용하기 위해 의존성 주입 프레임 워크로 pico-container를 사용하는 것이 좋습니다.

    PicoContainer를 사용하면 WebDriver 인스턴스로 '기본'클래스를 가질 수 있으며이 기본 클래스를 다른 클래스에 자동으로 전달할 수 있습니다. 또는 원하는 경우 직접 웹 드라이버를 전달할 수도 있습니다.

    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-picocontainer</artifactId>
        <version>1.2.3</version>
        <scope>test</scope>
    </dependency>
    

    예:

    WebDriver의 인스턴스가있는 기본 클래스 :

    public class ContextSteps {
    
       private static boolean initialized = false;
    
       private WebDriver driver;
    
       @Before
       public void setUp() throws Exception {
          if (!initialized) {
             // initialize the driver
             driver = = new FirefoxDriver();
    
             initialized = true;
          }
       }
    
       public WebDriver getDriver() {
          return driver;
       }
    }
    

    피코 컨테이너 DI를 통해 webDriver에 액세스하는 다른 클래스.

    public class OtherClassSteps {
    
       private ContextSteps contextSteps;
    
       // PicoContainer injects class ContextSteps
       public OtherClassSteps (ContextSteps contextSteps) {
          this.contextSteps = contextSteps;
       }
    
    
       @Given("^Foo step$")
       public void fooStep() throws Throwable {
          // Access WebDriver instance
          WebDriver driver = contextSteps.getDriver();
       }
    }
    

    희망이 도움이됩니다.

  2. ==============================

    2.이 질문은 오래되었고, 나는이 질문을 한 직후에 프로젝트를 떠났지만, 다시 돌아가서 싱글 톤 패턴을 사용하여 코드를 살펴 보았다. 왜 우리가 피코 컨테이너를 사용할 수 없었는지 정확히 잊어 버렸습니다 (아마도 조직적인 제약이었을 것입니다).하지만 추가 라이브러리를 사용할 수 있다면 솔루션이 잘 작동한다는 것을 기억합니다.

    이 질문은 오래되었고, 나는이 질문을 한 직후에 프로젝트를 떠났지만, 다시 돌아가서 싱글 톤 패턴을 사용하여 코드를 살펴 보았다. 왜 우리가 피코 컨테이너를 사용할 수 없었는지 정확히 잊어 버렸습니다 (아마도 조직적인 제약이었을 것입니다).하지만 추가 라이브러리를 사용할 수 있다면 솔루션이 잘 작동한다는 것을 기억합니다.

    나는 이것을 받아 들인 대답으로 남겨 둘 것이지만,이 솔루션은 몇 년 전 비슷한 위치에있는 사람들에게 유용 할 것입니다.

    public class TestingBase {
    
        private static TestingBase instance;
        private static WebDriver driver;
        private static Thread CLOSE_DRIVER = new Thread() {
            @Override
            public void run() {
                driver.close();
            }
    
        };
    
        static {
            Runtime.getRuntime().addShutdownHook(CLOSE_DRIVER);
        }
    
        private TestingBase() {
            DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
            desiredCapabilities.setJavascriptEnabled(true);
            desiredCapabilities.setCapability("takesScreenshot", false);
            desiredCapabilities.setCapability("handlesAlerts", true);
    
            desiredCapabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, new String[]{
                    "--web-security=false",
                    "--ssl-protocol=TLSv1",
                    "--ignore-ssl-errors=true",
                    "--webdriver-loglevel=ERROR",
                    "--webdriver-logfile=/var/log/phantomjs/ghostrdriver.log"
            });
            desiredCapabilities.setCapability("elementScrollBehavior",true);
            driver = new PhantomJSDriver(desiredCapabilities);
        }
    
        public static TestingBase getTestingBase() {
            if (instance == null) {
                instance = new TestingBase();
            }
            return instance;
    
        }
    
        public static WebDriver getDriver() {
            return getTestingBase().driver;
        }
    }
    
  3. from https://stackoverflow.com/questions/31573676/sharing-same-selenium-webdriver-between-step-definition-files by cc-by-sa and MIT license