Appium @BeforeTest 方法里设定的值不能第二次使用

没头脑 · 2017年07月20日 · 最后由 没头脑 回复于 2017年07月25日 · 2466 次阅读

先看代码
testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="NotLogin" >
    <test name="Smoke">
        <classes>

            <class name="com.ty.cases.Class1">
                <methods>
                    <include  name="classOneMethod" />
                </methods>
            </class>

            <class name="com.ty.cases.Class2">
                <methods>
                    <include  name="classTwoMethod" />
                </methods>
            </class>

        </classes>
    </test>
</suite>

Init.java

public class Init {

    public int num = -1;

    @BeforeMethod
    public void setupA() throws MalformedURLException {
        System.out.println("setupA:" + num);
    }

    @BeforeMethod
    public void setupB() throws MalformedURLException {
        System.out.println("setupB:" + num);
    }

    @AfterMethod
    public void teardownA() {
        System.out.println("teardownA");
    }

    @AfterMethod
    public void teardownB() {
        System.out.println("teardownB");
    }

    @BeforeTest
    public void before() {
        num = 0;
    }

}

Class1.java

public class Class1 extends Init{
    @Test
    public void classOneMethod() {
        System.out.println("classOneMethod");
    }
}

Class2.java

public class Class2 extends Init{
    @Test
    public void classTwoMethod() {
        System.out.println("classTwoMethod");
    }
}

项目结构:

说明
Init.java 里分别有 2 个@BeforeMethod@AfterMethod方法,以及 1 个@BeforeTest。在@BeforeTest方法里,将 num 进行了初始化。
Class1.java 和 Class2.java 分别为两个测试类,都只包含 1 个测试方法,为了便于区分,将它们命名为 classOneMethod 和 classTwoMethod
testng.xml 里分别将两个测试类写入,然后运行。
以下是运行结果

问题出在红色框标示的地方
按照我的理解,@BeforeTest方法将 num 初始化后,classOneMethod 和 classTwoMethod 运行时,num 的值都应该保持,也就是说,classOneMethod 和 classTwoMethod 运行时,num 的值都为 0。但是实际运行结果是,classTwoMethod 运行时,num 的值为-1。
这一点我很不理解,请大神解答。

共收到 8 条回复 时间 点赞

如果你想在类内 Test 前初始化,请用@BeforeClass,因为@BeforeTest是只要@test就运行一遍 xml 中所有的@BeforeTest

白纸 回复

如果用@BeforeClass,那么在运行到第二个 class 时,仍然会弹出 JOptionPane 对话框让我操作 (我在 InitSetting 方法里写了一个弹窗用于选择不同的分支,请看我的 Java 代码),我期望的是只选择一次,所有的 class 都按照此操作进行

建议使用这个框架,省的自己封装 https://github.com/saikrishna321/AppiumTestDistribution

在你的 xml 中@BeforeTest只执行一次,把 xml 文件里的 classTwoMethod 放到新的一个 test 标签下即可,看楼上给的连接你就知道怎么回事了

null 回复

我在@BeforeClass里写了一个 JOptionPane 弹出框,选择 “是”,isLogin 为 0;选择 “否”,isLogin 为 1。然后在@BeforeMethod里将 isLogin 输出。由于 testng.xml 配置的关系,@BeforeClass会执行两遍。有没有一劳永逸的方法,就是 JOptionPane 只执行一遍,isLogin 两次输出的值都相同?

@BeforeClass
public void beforeClass() {
    isLogin = JOptionPane.showConfirmDialog(null, "是否测试登录/注册功能?", "选择", JOptionPane.YES_NO_OPTION);
}

@BeforeMethod
public void setupA() {
    System.out.println("setupA:" + isLogin);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="NotLogin" >
    <test name="Smoke">
        <classes>

            <class name="com.ty.cases.Class1">
                <methods>
                    <include  name="classOneMethod" />
                </methods>
            </class>

            <class name="com.ty.cases.Class2">
                <methods>
                    <include  name="classTwoMethod" />
                </methods>
            </class>

        </classes>
    </test>
</suite>
没头脑 回复

要是不考虑多线程你可以直接在父类 Init 中定义一个 static 类变量即可。考虑多线程的话通过 ITestListener 的回调方法拿到对应的类实例,通过 getter 和 setter 来设置唯一值。我也还没实践过,应该是可行的。

null 回复

多谢指导😀

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册