新手区 请教个问题,如何使用 testng.xml 实现多个测试用例的连续执行

董永 · 2016年03月09日 · 最后由 曾晖斌 回复于 2016年03月10日 · 2736 次阅读

1.现在有两个独立的测试用例 SkipTest 和 MoveScreenTest;我使用 testng.xml 单独执行每个用例都没有问题

2.如果在 testng.xml 中同时写入这 2 个测试用例,执行的时候就会报错**

info: [debug] Responding to client with error: {"status":33,"value":{"message":"A new session could not be created. (Original error: Requested a new session but one was in progress)","origValue":"Requested a new session but one was in progress"},"sessionId":"1d3cac22-fa5a-40e9-a86f-4b8d7eebef64"}

找到原因是由于 2 个 driver 同时启动导致的这个问题,在第二个执行的测试用例中把 driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities) 去掉;改为 driver.startActivity("com.qshealthcare.qshc", "com.qshealthcare.qshc.ui.activity.WelcomeActivity");再次执行,结果就是 APP 能启动起来但是哪个用例都不会执行。哪位大神能告诉我这个到底怎么解决呢?

3.下面贴出代码和报错信息

SkipTest

@Test
public class SkipTest{
    private AndroidDriver driver;  
    @BeforeSuite
    public void setUp() throws Exception {     
        driver.startActivity("com.qshealthcare.qshc", "com.qshealthcare.qshc.ui.activity.WelcomeActivity");
    }
    @AfterSuite
    public void tearDown() throws Exception{
        System.out.println("AfterSuite");
    }
    @Test
    public void swipe() throws InterruptedException {

        Set<String> contextNames = driver.getContextHandles();
        for (String contextName : contextNames) {
            System.out.println(contextName);
            if (contextName.contains("WEBVIEW")){
                driver=(AndroidDriver) driver.context(contextName);
            }else
            {
                System.out.println("no WEBVIEW");
            }
        }
        Thread.sleep(3000);
        for(int i=0;i<5;i++)
            {
            String demo="糖尿病患者可以有性生活吗?";
            System.out.println(i);
            WebElement result=driver.findElementByXPath("//android.widget.ListView/android.widget.RelativeLayout[contains(@index,3)]/android.widget.RelativeLayout[contains(@index,1)]/android.widget.RelativeLayout[contains(@index,1)]/android.widget.TextView[contains(@index,0)]");
            String resulttext=result.getAttribute("text");
            System.out.println( resulttext);
            if(!demo.equals(resulttext)){
                driver.swipe(702,1136,0,234,500);
                System.out.println("没找到");
                continue;
                }
            else{
                System.out.println("找到了");
                result.click();
                break;
                }
            }   
        System.out.println("push");
        Thread.sleep(5000);
    }
}



**MoveScreenTest**

public class MoveScreenTest{
    private AndroidDriver driver;  
    @BeforeSuite  
    public void setUp() throws Exception {  
        //set up appium  
        File classpathRoot = new File(System.getProperty("user.dir"));  
        //获取用户当前的工作目录
        File appDir = new File(classpathRoot, "apps");  
        File app = new File(appDir, "QSHealthMD.apk");  
        //File app = new File("D:\\QSHealthMD.apk")
        //或者可获取当前win系统中某路径下的apk
        DesiredCapabilities capabilities = new DesiredCapabilities();  
        //告诉appium启动的是浏览器还是移动设备,设备的名称、类型、版本等
        capabilities.setCapability(CapabilityType.BROWSER_NAME, "");  
        //定义移动浏览器的名称
        capabilities.setCapability("platformName", "Android");  
        capabilities.setCapability("deviceName","4d000e1544325027");  
        capabilities.setCapability("platformVersion", "5.0");
        //capabilities.setCapability("app", app.getAbsolutePath());  
        //安装绝对路径下的app到移动设备中
        capabilities.setCapability("appPackage", "com.qshealthcare.qshc");  
        capabilities.setCapability("appActivity", "com.qshealthcare.qshc.ui.activity.WelcomeActivity");  
        //获取app的首页,可通过appipum工具获取
        //capabilities.setCapability("unicodeKeyboard","True");
        //支持中文输入法
        //capabilities.setCapability("restKeyboard","True")
        //重置输入法为系统默认
        //capabilities.setCapability("noSign","True") 
        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);  
    }

    @AfterSuite
    public void tearDown() throws Exception{
        //driver.quit();
        Thread.sleep(3000);
    }

    @Test
    public void lockscreen() throws InterruptedException {

        //获取当前的混合应用类型,判断如果是webview就跳转进入webview
        Set<String> contextNames = driver.getContextHandles();
        for (String contextName : contextNames) {
            System.out.println(contextName);
            if (contextName.contains("WEBVIEW")){
                //driver.context(contextName);
                driver=(AndroidDriver) driver.context(contextName);
                //AndroidDriver adriver =(AndroidDriver) driver.context("NATIVE_APP");
            }else
            {
                System.out.println("no WEBVIEW");
            }
        }           
        Thread.sleep(20000);

        int width=driver.manage().window().getSize().width;
        int height=driver.manage().window().getSize().height;

        //指定一个滑动的x和y坐标
        driver.swipe(width*4/5, height/2, width/5, height/2, 1000);
        Thread.sleep(2000); 
        WebElement loginBtn=driver.findElementByName("社区");
        loginBtn.click();
        System.out.println("success");  
        Thread.sleep(5000);
    }
}

XML


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="test" verbose="10" >
  <test name="testcase1" >
    <classes>
        <class name="MoveScreenTest"/>
        <class name="SkipTest"/>
    </classes>
  </test>
</suite>   

appium 服务器没有报任何错误,eclipse 的控制台报错内容为
java.lang.NullPointerException
at SkipTest.setUp(SkipTest.java:21)
21 行的代码为 driver.startActivity("com.qshealthcare.qshc", "com.qshealthcare.qshc.ui.activity.WelcomeActivity");
我就想实现一个用 xml 执行多个测试用例,请大神们帮帮忙,多谢!

共收到 14 条回复 时间 点赞

MD 格式......

新人请阅读:https://testerhome.com/topics/982
学会如何合理提问,请阅读:https://testerhome.com/topics/587

#1 楼 @anikikun MD 格式是什么意思?能说的详细点吗?

@monkey 猴哥,看看这个格式行吗?

#4 楼 @511594204 我能删除你帖子么。。。你真的看了我给你的链接么。。。。

#5 楼 @monkey 那你删了吧,不好意思。

#6 楼 @511594204 我帮你大概改了下,你看看

#7 楼 @monkey 代码要用高亮模式来表现?我刚刚没有找到那个高亮模式的按钮,不好意思。

给两个建议调试下试试:
1、XML 中类名带上包名,如:
2、XML 中两个测试类在一个 suite 里,为何在两个类里面都有 beforesuite 和 aftersuite,两个类需要降级为 beforetest 或 beforemethod

董永 #10 · 2016年03月09日 Author

#9 楼 @qiaoyeye 我现在搞定可以连续跑 2 个用例了,但是跑完第一个用例后 app 会结束进程;跑第二个的时候需要重新启动一次 app,我想一直就启动一次 app,不要每次都结束进程后再重新启动一次,你知道解决方法吗?

给你写了 3 个类,按照下面的模式你套下你的代码:

1、你的 driver 启动和停止类

package testng;
/** 
 * @author QiaoJiafei 
 * @version 创建时间:2016年3月9日 下午4:12:49 
 * 类说明 
 */
public class TestTTT {
    static int driverstart = 0;
    static int driverstop = 1;
}

2、你的测试用例 1 类

package testng;

import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;

/** 
 * @author QiaoJiafei 
 * @version 创建时间:2016年3月9日 下午4:10:43 
 * 类说明 
 */
public class TestClass1 {
    @BeforeSuite
    public void bfs() {
        System.out.println("beforesuite:"+TestTTT.driverstart);
    }
    @AfterSuite
    public void afs() {
        System.out.println("aftersuite:"+TestTTT.driverstop);
    }

    @Test
    public void testfun() {
        System.out.println("TestClass1's test");
    }
}

3、你的测试用例 2 类

package testng;

import org.testng.annotations.Test;

/** 
 * @author QiaoJiafei 
 * @version 创建时间:2016年3月9日 下午4:16:01 
 * 类说明 
 */
public class TestClass2 {

    @Test
    public void testfun() {
        System.out.println("TestClass2's test");
    }
}

4、XML 文件

<classes>
  <class name="testng.TestClass1"/>
  <class name="testng.TestClass2"/>
</classes>

5、输出结果:

beforesuite:0
TestClass1's test
TestClass2's test
aftersuite:1

董永 #12 · 2016年03月09日 Author

#11 楼 @qiaoyeye 多谢了,问题已经解决了

董永 #13 · 2016年03月09日 Author

问题已经解决,把代码和大家共享一下,希望可以帮助到其他人。

MoveScreenTest

import io.appium.java_client.android.AndroidDriver;  
import org.openqa.jetty.jetty.servlet.SessionManager;
import org.openqa.selenium.WebElement;  
import org.openqa.selenium.remote.CapabilityType;  
import org.openqa.selenium.remote.DesiredCapabilities;  
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import org.testng.annotations.AfterSuite;
import java.io.File;  
import java.net.URL;  
import java.util.Set;

public  class MoveScreenTest{  
    public static AndroidDriver driver;
    @BeforeTest 
    public static  void setUp() throws Exception {  
        //set up appium  
        File classpathRoot = new File(System.getProperty("user.dir"));  
        //获取用户当前的工作目录
        File appDir = new File(classpathRoot, "apps");  
        File app = new File(appDir, "QSHealthMD.apk");  
        //File app = new File("D:\\QSHealthMD.apk")
        //或者可获取当前win系统中某路径下的apk
        DesiredCapabilities capabilities = new DesiredCapabilities();  
        //告诉appium启动的是浏览器还是移动设备,设备的名称、类型、版本等
        capabilities.setCapability(CapabilityType.BROWSER_NAME, "");  
        //定义移动浏览器的名称
        capabilities.setCapability("platformName", "Android");  
        capabilities.setCapability("deviceName","4d000e1544325027");  
        capabilities.setCapability("platformVersion", "5.0");
        //capabilities.setCapability("app", app.getAbsolutePath());  
        //安装绝对路径下的app到移动设备中
        capabilities.setCapability("appPackage", "com.qshealthcare.qshc");  
        capabilities.setCapability("appActivity", "com.qshealthcare.qshc.ui.activity.WelcomeActivity");  
        //获取app的首页,可通过appipum工具获取
        //capabilities.setCapability("unicodeKeyboard","True");
        //支持中文输入法
        //capabilities.setCapability("restKeyboard","True")
        //重置输入法为系统默认
        //capabilities.setCapability("noSign","True") 
        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);  
    }

    @AfterTest
    public void tearDown() throws Exception{
        System.out.println(driver);
        //driver.quit();
        Thread.sleep(3000);
    }

    @Test
    public void lockscreen() throws InterruptedException {
        //获取当前的混合应用类型,判断如果是webview就跳转进入webview
        Set<String> contextNames = driver.getContextHandles();
        for (String contextName : contextNames) {
            System.out.println(contextName);
            if (contextName.contains("WEBVIEW")){
                //driver.context(contextName);
                driver=(AndroidDriver) driver.context(contextName);
                //AndroidDriver adriver =(AndroidDriver) driver.context("NATIVE_APP");
            }else
            {
                System.out.println("no WEBVIEW");
            }
        }           
        Thread.sleep(20000);

        int width=driver.manage().window().getSize().width;
        int height=driver.manage().window().getSize().height;
        //指定一个滑动的x和y坐标
        driver.swipe(width*4/5, height/2, width/5, height/2, 1000);
        Thread.sleep(2000); 
        WebElement loginBtn=driver.findElementByName("社区");
        loginBtn.click();
        System.out.println("跳转界面"); 
        Thread.sleep(5000);
    }
}

SkipTest


import org.testng.annotations.Test;

import io.appium.java_client.android.AndroidDriver;  

import org.openqa.selenium.WebElement;  
import org.openqa.selenium.remote.CapabilityType;  
import org.openqa.selenium.remote.DesiredCapabilities;  

import java.io.File;  
import java.net.MalformedURLException;
import java.net.URL;    
import java.util.Set;

import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;


public class SkipTest{  
    @BeforeTest
    public void setUp() throws Exception {     

    }

    @AfterTest
    public void tearDown() throws Exception{
        MoveScreenTest.driver.quit();
    }

    @Test
    public void swipe() throws InterruptedException {

        Set<String> contextNames = MoveScreenTest.driver.getContextHandles();
        for (String contextName : contextNames) {
            System.out.println(contextName);
            if (contextName.contains("WEBVIEW")){
                MoveScreenTest.driver=(AndroidDriver) MoveScreenTest.driver.context(contextName);
            }else
            {
                System.out.println("no WEBVIEW");
            }
        }
        Thread.sleep(3000);

        WebElement loginBtn=MoveScreenTest.driver.findElementByName("首页");
        loginBtn.click();
        System.out.println("跳转界面"); 
        Thread.sleep(3000);

        for(int i=0;i<10;i++)
        {
        String demo="向红丁教授的“三五”防糖法";
        System.out.println(i);
        Thread.sleep(3000);
        WebElement result=MoveScreenTest.driver.findElementByXPath("//android.widget.ListView/android.widget.RelativeLayout[contains(@index,3)]/android.widget.RelativeLayout[contains(@index,1)]/android.widget.RelativeLayout[contains(@index,1)]/android.widget.TextView[contains(@index,0)]");     
        String resulttext=result.getAttribute("text");
        System.out.println( resulttext);

        if(!demo.equals(resulttext)){

            MoveScreenTest.driver.swipe(702,1136,702,1090,500);
            System.out.println("没找到");
            continue;
            }
        else{
            System.out.println("找到了");
            result.click();
            break;
            }
        }   
        System.out.println("退出");
        Thread.sleep(5000);
    }
}

XML


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="test" verbose="10" >
  <test name="testcase1" >
    <classes>
        <class name="MoveScreenTest"/>
        <class name="SkipTest"/>
    </classes>
  </test>
</suite>   

那个 driver 多次初始化,有两种解决方式,一种是单例模式,一种是在下次初始化前 close 之前初始化的 driver。

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