Selenium Webdriver实现BKredcoil website 自动登录测试、Single Sign On(TestNG+ANT+Excel数据驱动)

该博客旨在实现Selenium Webdriver自动化测试,包括BKredcoil网站的自动登录和Single Sign On功能。内容涉及如何通过TestNG和ANT配合Excel数据驱动进行测试,同时在登录失败时自动截图并生成详细的测试报告。测试用例存储在Excel文档中,执行后会在特定文件夹下生成测试报告和失败截图。

目标实现:

1.自动登录测试帐号

2.自动进行Single Sign On登录测试

3.登录失败的能够截图保存

4.测试报告中能够详尽展出测试数据以及测试结果

一、项目结构:

(1)base包:用来存放元素对象,将测试的元素对象插入数据库中保存,好用来做为测试用例维护。

ObjectTest.java

package com.annie.base;

import java.util.Date;

public class ObjectTest {
	private int id;
	private String website;
	private String page;
	private String area;
	private String object_type;
	private String object_key_type;
	private String object_pagename;
	private String object_key;
	private String description;
	private String status;
	private Date createtime;
	private String createuser;
	private Date updatetime;
	private String updateuser;
	private Date deletetime;
	private String deleteuser;
	//后面省去get/set方法
	

}

(2)util包:用来存放工具类,比如ExelData这样的工具类

(注意1.exel测试数据文档的路径;2.exel测试数据文档名;3.exel测试数据文档的testcase名,即sheet名)

package com.annie.util;

import java.io.File;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import jxl.*;

public class ExcelData implements Iterator<Object[]> {
	private Workbook book = null;
	private Sheet sheet = null;
	private int rowNum = 0;
	private int curRowNo = 0;
	private int columnNum = 0;
	private String[] columnnName;

	public ExcelData(String filepath, String casename) {
		try {
			File directory = new File(".");
			String ss = "open.anniewang.exceldata.";
			book = Workbook.getWorkbook(new File(directory.getCanonicalPath()
					+ "\\resources\\"
					+ ss.replaceAll("\\.", Matcher.quoteReplacement("\\"))
					+ filepath + ".xls"));
			this.sheet = book.getSheet(casename);
			this.rowNum = sheet.getRows();

			Cell[] c = sheet.getRow(0);
			this.columnNum = c.length;
			columnnName = new String[c.length];
			for (int i = 0; i < c.length; i++) {
				columnnName[i] = c[i].getContents().toString();
			}
			this.curRowNo++;

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean hasNext() {

		if (this.rowNum == 0 || this.curRowNo >= this.rowNum) {
			try {
				book.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			return false;
		} else
			return true;
	}

	@Override
	public Object[] next() {

		Cell[] c = sheet.getRow(this.curRowNo);
		Map<String, String> s = new TreeMap<String, String>();
		for (int i = 0; i < this.columnNum; i++) {
			String temp = "";
			try {
				temp = c[i].getContents().toString();
			} catch (ArrayIndexOutOfBoundsException ex) {
				temp = "";
			}
			s.put(this.columnnName[i], temp);
		}

		Object r[] = new Object[1];
		r[0] = s;
		this.curRowNo++;
		return r;
	}

	@Override
	public void remove() {
		throw new UnsupportedOperationException("remove unsupported.");
	}
}

(3)testng包:用来存放公共的方法实现“高内聚,低耦合”的初衷(需要后面完善)

package com.annie.testng;

import java.util.Iterator;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import com.annie.util.ExcelData;

;

public class TestNG {
	private WebDriver driver;

	@Parameters({ "browser" })
	@BeforeTest
	public void setupBrowser(String browser) {
		if (browser.equals("firefox")) {
			driver = new FirefoxDriver();
		} else {

			driver = new ChromeDriver();
		}

	}

	@Parameters({ "url", "keyword" })
	@Test
	public void search(String url, String keyword) {
		driver.get(url);
		WebElement element = driver.findElement(By.name("q"));
		element.sendKeys(keyword);
		element.submit();
		Assert.assertTrue(driver.getTitle().contains(keyword),
				"Title is  wrong!");
	}

	// 传入登录用户名、密码,获取元素,验证空用户/密码登录
	@Parameters({ "url", "login_name_txtUserName", "login_name_txtPwd",
			"login_name_btnLogin" })
	// 参数: URL、用户名name、密码name、登陆按钮name
	@Test(groups = { "login" })
	public void login_username_empty(String login_name_txtUserName,
			String login_name_txtPwd, String login_name_btnLogin)
			throws Exception {
		System.out.print("login_username_empty");
		driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
		driver.findElement(By.name(login_name_txtUserName)).clear();
		driver.findElement(By.name(login_name_txtPwd)).clear();
		driver.findElement(By.name(login_name_txtUserName)).sendKeys("");
		driver.findElement(By.name(login_name_txtPwd)).sendKeys("");
		driver.quit();
	}


}

(4)testcase包:用来存放编写的测试用例

LoginTest.java

package com.annie.testcase;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import com.annie.testng.TestNG;
import com.annie.util.ExcelData;
import com.annie.util.ScreenShot;

public class LoginTest {

    private WebDriver driver;
    private String username = "";
    private String password = "";
    private String URL = "http://10.0.0.88:8080/bkredcoil/web/index.html";

    TestNG tn = new TestNG();

    @DataProvider(name = "accounts")
    // 登录用户的账户Excel,返回的是Object数组
    public Iterator<Object[]> data() throws Exception {
        return (Iterator<Object[]>) new ExcelData("accounts_login", "testA");

    }

    public void prmap(Map<String, String> arr) throws Exception {
        driver = new FirefoxDriver();
        // driver.get("http://redcoil.technologystudios.com/index.html");

        driver.get("http://10.0.0.88:8080/bkredcoil/index.html");
        // driver.get("http://10.0.0.88:8080/bkredcoil/controller/security/signon?sid=");

        driver.manage().timeouts().implicitlyWait(500, TimeUnit.SECONDS);
        driver.findElement(By.id("username")).clear();
        driver.findElement(By.id("password")).clear();

        Set<String> set = arr.keySet();
        Iterator<String> it = set.iterator();

        while (it.hasNext()) {
            String s = (String) it.next();
            if (s.equals("Email")) {
                username = arr.get(s);
                password = "";

            } else {
                password = arr.get(s);

            }

            if ((username.length() > 0) && (password.length() > 0)) {
                System.out.println("username:" + username);
                System.out.println("password:" + password);
                if (driver.findElement(By.id("username")).getText().length() == 0) {
                    driver.findElement(By.id("username")).clear();
                    driver.findElement(By.id("username")).sendKeys(username);
                }
                if (driver.findElement(By.id("password")).getText().length() == 0) {
                    driver.findElement(By.id("password")).clear();
                    driver.findElement(By.id("password")).sendKeys(password);
                }
                driver.findElement(By.id("btn-login")).click();
                Thread.sleep(500);
                 //登录成功后页面跳转,需要判断是否跳转到成功页面
                String current_url = driver.getCurrentUrl();
                System.out.println(current_url);
                if (current_url.equals(URL)) {
               //如果成功,则点击登录并退出driver
                    driver.get(URL);
                    System.out.println(driver.getCurrentUrl());
                    Thread.sleep(500);
                    System.out.println("Login Success!");
                /*    System.out.println(driver.findElement(By.id("button-1016"))
                            .getTagName());*/
                    driver.findElement(By.id("button-1016")).click();
                    driver.close();

                } else {
                   
                    // Thread.sleep(500);
                    //如果Login失败, 判断登录失败的对话框是否出现,如果出现warning则截图保存至screenpic文件夹下
                    if (driver.findElement(By.className("toast-item-wrapper"))
                            .isEnabled()) {
                        System.out.println("login_warning is show!");
                        ScreenShot ss = new ScreenShot();
                        ss.cutshot(driver);
                         driver.quit();

                    }
                    // 登录成功后跳转,重新获取URL

                }
            }
        }

    }

    // 写一个类似prmap的方法,将Map类型的exel数据传入,并在指定的URL进行登录,将Map中的Email和password 做参数传入登陆即可

    @Test(dataProvider = "accounts")
    public void ts(Map<String, String> data) throws Exception {

        this.prmap(data);

        // 每次打印一组account,则调用登录用例

        System.out.println("=====over=====");
        System.out.println("");
    }

}

Single Sign On 只需更改testng.xml

LoginTestURL.java

package com.annie.testcase;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import com.annie.testng.TestNG;
import com.annie.util.ExcelData;
import com.annie.util.ScreenShot;

public class LoginTestURL {

	private WebDriver driver;
	// private String username, password;
	private String sid,url;

	TestNG tn = new TestNG();

	@DataProvider(name = "accounts")
	// 登录用户的账户Excel,返回的是Object数组
	public Iterator<Object[]> data() throws Exception {
		return (Iterator<Object[]>) new ExcelData("accounts_login",
				"BKID");

	}

	public void prmap(Map<String, String> arr) throws Exception {
		driver = new FirefoxDriver();
		// driver.get("http://redcoil.technologystudios.com/index.html");

		// driver.get("http://10.0.0.88:8080/bkredcoil/index.html");
	
		/*
		 * driver.findElement(By.id("username")).clear();
		 * driver.findElement(By.id("password")).clear();
		 */

		Set<String> set = arr.keySet();
		Iterator<String> it = set.iterator();

		while (it.hasNext()) {
			String sid = (String) it.next();
			/*
			 * if (s.equals("Email")) { username = arr.get(s); } else { password
			 * = arr.get(s); }
			 */
			System.out.println(arr.get(sid));
			url="http://10.0.0.88:8080/bkredcoil/controller/security/signon?sid="+arr.get(sid);
			System.out.println(url);
			
			driver.get(url);

			driver.manage().timeouts().implicitlyWait(500, TimeUnit.SECONDS);

			/*
			 * if (driver.findElement(By.id("username")).getText().length()==0)
			 * { driver.findElement(By.id("username")).clear();
			 * driver.findElement(By.id("username")).sendKeys(username); } if
			 * (driver.findElement(By.id("password")).getText().length()==0) {
			 * driver.findElement(By.id("password")).clear();
			 * 
			 * 
			 * 
			 * driver.findElement(By.id("btn-login")).click();
			 */

			driver.manage().timeouts().implicitlyWait(500, TimeUnit.SECONDS);
			Thread.sleep(500);
			driver.findElement(By.id("button-1056-btnInnerEl")).click();
			
			driver.close();
			// ScreenShot ss = new ScreenShot();
			// try{
			// ss.cutshot(driver);
			// }
			// catch(Exception e){
			// e.printStackTrace();
			//
			// }

		}

	}

	// 写一个类似prmap的方法,将Map类型的exel数据传入,并在指定的URL进行登录,将Map中的Email和password 做参数传入登陆即可

	@Test(dataProvider = "accounts")
	public void ts(Map<String, String> data) throws Exception {

		this.prmap(data);

		// 每次打印一组account,则调用登录用例

		System.out.println("=====over=====");
		System.out.println("");
	}

}

 

testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
   <test name="LoginTest" preserve-order="true">
    <classes>
      <class name="com.annie.testcase.LoginTest"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

build.xml

<project name="TestNGTest" default="testoutput" basedir=".">  
        <!-- Define <testng> task -->  
        <taskdef name="testng" classname="org.testng.TestNGAntTask">  
            <classpath>  
                <pathelement location="lib/testng-6.8.jar" />  
            </classpath>  
        </taskdef>  
        <property name="testoutputdir" location="test-output" />  
        <property name="srcdir" location="src" />  
        <property name="libdir" location="lib" />  
        <property name="full-compile" value="true" />  
        <property name="basedir" value="D:/workspace/BKRedcoil_TestCase/" />  
      
        <path id="classpath.test">  
            <fileset dir="${libdir}">  
                <include name="**/*.jar" />  
            </fileset>  
            <pathelement location="${testoutputdir}" />  
            <pathelement location="${srcdir}" />  
      
        </path>  
        <target name="clean">  
            <delete dir="${basedir}/bin" />  
      
        </target>  
      
        <target name="compile" depends="clean">  
            <mkdir dir="${basedir}/bin" />  
            <javac srcdir="${srcdir}" encoding="UTF-8" destdir="${basedir}/bin" verbose="${full-compile}" classpathref="classpath.test" includeantruntime="off" debug="on" debuglevel="lines,vars,source" />  
      
        </target>  
      
    <path id="classes">  
        <fileset dir="${libdir}" includes="*jar"/>  
        <fileset dir="${libdir}" includes="*zip"/>  
        <pathelement location="${basedir}/bin/"/>  
      
    </path>  
      
        <target name="runtest" depends="compile">  
            <testng outputdir="${testoutputdir}" classpathref="classes" delegateCommandSystemProperties="true">  
                <xmlfileset dir="${srcdir}" includes="testng.xml" />  
            </testng>  
        </target>  
      
        <target name="testoutput" depends="runtest">  
            <xslt in="${testoutputdir}/testng-results.xml" style="${testoutputdir}/testng-results.xsl" out="${testoutputdir}/index.html ">  
      
                <param name="testNgXslt.outputDir" expression="D:/workspace/BKRedcoil_TestCase/test-output/" />  
      
                <classpath refid="classpath.test" />  
      
            </xslt>  
      
        </target>  
    </project>  

则执行后,会不断打开页面进行exel表格中的账户登录accounts_login.xls(sheet name is testA )

cc

aa

测试报告在test-output文件夹中生成

打开默认生成的测试报告(后面会美化测试报告步骤)

bb

screenpic文件夹下自动保存登录失败的截图:

dd

未完待续

需要解决:

1.登录失败如何设计测试用例,以及在report中展现fail的个例

2.如何维护测试用例(面向对象的设计)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值