Java 依赖注入在cucumber项目中初始化驱动程序并使用钩子而不终止会话

Java 依赖注入在cucumber项目中初始化驱动程序并使用钩子而不终止会话,java,selenium,cucumber,testng,appium,Java,Selenium,Cucumber,Testng,Appium,我试图用页面对象模型实现cucumber,我遇到了两个问题,还有很多问题 我的iOS应用程序并没有那么复杂,但我仍然想组织所有的stepdef和功能,以符合POM的页面。因此,我将有多个STEPDEF和跑步者。组织所有这些活动的最佳实践是什么?我尝试了Pico DI,但甚至无法通过它传递我的驱动程序实例。(如果可以,请提供结构解决方案) 因为它是本机iOS-I,所以我不会在每一个场景后都关闭这个应用程序(这将花费永远的时间)。但我仍然希望保持功能干燥,以实现可重用性 创建一个appium驱动程序

我试图用页面对象模型实现cucumber,我遇到了两个问题,还有很多问题

  • 我的iOS应用程序并没有那么复杂,但我仍然想组织所有的stepdef和功能,以符合POM的页面。因此,我将有多个STEPDEF和跑步者。组织所有这些活动的最佳实践是什么?我尝试了Pico DI,但甚至无法通过它传递我的驱动程序实例。(如果可以,请提供结构解决方案)

  • 因为它是本机iOS-I,所以我不会在每一个场景后都关闭这个应用程序(这将花费永远的时间)。但我仍然希望保持功能干燥,以实现可重用性 创建一个appium驱动程序实例并在执行功能之前从不创建另一个实例的最佳方法是什么?我知道我只需要在最后一步添加driver.quit。我的缺点是在整个项目中使用相同的驱动程序(页面,Stepdefs)(参见代码)

  • 我将用TestNg运行测试,并想知道@Before@After注释是否仍能在stepdefs中工作,还是最好避免它们

  • 主要问题:使用pico进行依赖注入。由于我所有的测试都是可接受的(端到端的特性测试),我想知道创建一个包含我所有页面和驱动程序的InjectionSetUp类是否是个好主意

  • 司机经理

    公共类IOSDriverManager{
    public static ThreadLocal webDriver=new ThreadLocal();
    公共静态所需功能getIOSCapsLocal(){
    DesiredCapabilities=新DesiredCapabilities();
    //我的帽子
    返回盖;
    公共静态void createThreadLocalWebDriver(){
    IOSDriver-driver=null;
    //试一试
    driver=newiosdriver(新URL(APPIUM_SERVER_URL),getIOSCapsLocal());
    //试一试
    webDriver.set(driver);
    }
    公共静态IOSDriver getThreadLocalDriver(){
    IOSDriver=webDriver.get();
    if(驱动程序==null){
    createThreadLocalWebDriver();
    driver=webDriver.get();
    }
    返回驱动器;
    }
    
    基本页

    公共类基页{
    驱动程序;
    公共基本页(IOSDriver驱动程序){
    initElements();
    司机=司机;
    }
    私有void initElements(){
    initElements(新的AppiumFieldDecorator(getDriver()),这个);
    }
    受保护的IOSDriver getDriver(){
    返回IOSDriverManager.getThreadLocalDriver();
    }
    }
    
    任意页

    公共类BiosurveyPage扩展了BasePage{
    公共生物调查页(IOSDriver){
    super(driver);//Appiumfield decorator由BasePage构造函数应用
    //在所有页面中使用getDriver()方法而不是再次声明驱动程序是否更好?
    }
    
    最后一步

    公共类newSignUpFlowTest{
    受保护的IOSDriver getDriver(){
    返回IOSDriverManager.getThreadLocalDriver();
    }
    LoginPage poLogin=newloginpage(getDriver());
    SignUpPage poSignup=newsignuppage(getDriver());
    //10多页
    @给定(“我在登录页面上”)
    公共无效iAmOnLoginPage(){
    断言(“在登录页面上”,poLogin.isLoginScreen(),equalTo(true));
    }
    @当(“我点击注册链接”)
    公共无效iTapsOnSignUpLink(){
    poLogin.clickSignUp();
    }
    //此功能的20多种方法
    
    更新
    我修复了所有问题并能够运行测试。现在我的问题是-我的框架看起来像样吗?在此之前我没有任何实际生活经验。所以有人能批准我并建议改进以跟上行业最佳实践吗?我知道这篇文章可能会激怒一些人,但我不知道还有什么地方可以传达这一点s因为我在QA领域没有任何朋友,并且在远程工作

    当使用依赖项注入时,您希望让您的DI系统完成所有繁重的工作。因此,您的步骤定义对页面对象具有构造函数依赖性

    public class NewSignUpFlowStepDefinitions {
    
        private final LoginPage poLogin;
        private final SignUpPage poSignup;
    
        NewSignUpFlowStepDefinitions(LoginPage poLogin, SignUpPage poSignup) {
            this.poLogin = poLogin;
            this.poSignup = poSignup;
        }
    
        @Given("I am on Login Page")
        public void iAmOnLoginPage() {
            assertThat("ON LOGIN PAGE", poLogin.isLoginScreen(), equalTo(true));
        }
    
        @When("I tap on Sign Up Link")
        public void iTapsOnSignUpLink() {
            poLogin.clickSignUp();
        }
    
    }
    
    页面对象不能对
    IOSDriver
    具有构造函数依赖关系,因为PicoContainer只能创建不以空构造函数结尾的依赖链。因此,我们在此处使用
    IOSDriverManager

    public class BiosurveyPage extends BasePage {
        public BiosurveyPage(IOSDriverManager driverManager) {
            super(driverManager);
        }
    }
    
    public class IOSDriverManager implements Disposable{
        private IOSDriver<IOSElement> webDriver;
    
        private DesiredCapabilities getIOSCapsLocal() {
            DesiredCapabilities caps = new DesiredCapabilities();
            return caps;
        }
    
        private void createWebDriver() {
            webDriver = new IOSDriver<IOSElement>(new URL(APPIUM_SERVER_URL), getIOSCapsLocal());
        }
    
        public IOSDriver<IOSElement> getDriver() {
            if (webDriver == null) {
                createThreadLocalWebDriver();
            }
            return webDriver;
        }
    
        @Override
        public void dispose() {
            // Stop webdriver ehre
        }
    }
    
    BasePage
    中,然后从驱动程序管理器中解包webdriver

    public abstract class BasePage {
        private IOSDriverManager driverManager;
    
        public BasePage(IOSDriverManager driverManager) {
            this.driverManager = driverManager;
            initElements();
        }
    
        private void initElements() {
            PageFactory.initElements(new AppiumFieldDecorator(driverManager.getDriver()), this);
        }
    
        protected IOSDriver<IOSElement> getDriver() {
            return driverManager.getDriver();
    
        }
    }
    
    请注意,
    Disposable
    添加了dispose方法,该方法将允许您在每个场景后清理驱动程序a。可以完全处置驱动程序a,也可以将其重置为某个已知状态


    您的更新听起来像是在要求代码审查。为此,我推荐review.stackexchange.com非常感谢您提供了这么好的答案。我最不愿意做的事情是如何将我的WaitUtils和AssertUtils添加到BasePage构造函数中。如果我只是将其保持为“public BasePage”(IODriverManager driverManager){this.driverManager=driverManager;initElements();asrt=new AssertUtils;}“我遇到了一些PICOCONTAINER异常,我试图创建第二个构造函数,但是为所有使用WaitUtilS的方法获取nullPointer可能更容易创建一个新问题来共享所有细节。很难说这里出了什么问题。不知怎么修复了它,甚至不知道如何修复。