首页 > 软件测试

用XUnit框架编写数据驱动的Selenium2自动化测试程序

关键词:XUnit、Selenium2、数据驱动,自动化测试程序
作者:顾翔
啄木鸟软件测试咨询网
摘要:XUnit是单元测试框架体系。Selenium2又称第二代Selenium,即WebDriver+Selenium1,支持Python、Java等多种语言。数据驱动在自动化测试中扮演了重要的角色。本文以Python语言来进行详细介绍,最后给一个Java的案例。
1、XUnit介绍
首先我们先来介绍一下XUnit,XUnit是各种代码驱动测试框架的统称,这些框架可以测试软件的不同内容(单元),比如函数和类。XUnit框架的主要优点是,它提供了一个自动化测试的解决方案。没有必要多次编写重复的测试代码,也不必记住这个测试的结果应该是怎样的。XUnit的测试框架体系见图一。

图一 XUnit的测试框架体系
接下来我们介绍一下JUnit的四要素:
1,测试Fixtures:是一组认定被测对象或被测程序单元测试成功的预定条件或预期结果的设定。Fixture就是被测试的目标,可能是一个对象或一组相关的对象,甚至是一个函数。测试人员在测试前就应该清楚对被测对象进行测试的正确结果是什么,这样就可以对测试结果有一个明确的判断。
2,测试集:测试集就是一组测试用例,这些测试用例要求有相同的测试Fixture,以保证这些测试不会出现管理上的混乱。
3,测试执行:单个单元测试的执行可以按下面的方式进行:
setUp();/*首先,我们要建立针对被测程序单元的独立测试环境*/
……
/*然后,编写所有测试用例的测试体或测试程序*/
……
tearDown();/*最后,无论测试成功还是失败,都将环境进行清理,以免影响后继的测试*/
4,断言:断言实际上就是验证被测程序在测试中的行为或状态的一个宏或函数。断言失败实际上就是引发异常,终止测试的执行。
XUnit测试流程是:
1, 对Fixture 进行初始化,以及其他初始化操作;
2, 按照要测试的某个功能或流程对Fixture 进行操作;;
3, 验证结果是否正确;
4, 对Fixture的以及其他的资源释放等做清理工作。
XUnit支持多种语言,比如Junit(支持Java语言),NUnit(支持.NET语言),CPPUnit(支持C++语言),unittest(支持Python语言)等,下面我们来看一段unittest框架用来测试Python程序的代码:
#!/usr/bin/env python
#coding:utf-8
import unittest
from Calculator import calculator

class calculatortest(unittest.TestCase):
        def setUp(self):
                print "Test start!"
        
        def test_base(self):
                j=calculator(4,2)
                self.assertEqual(j.myadd(),6)
                self.assertEqual(j.mysubs(),2)
                self.assertEqual(j.mymultiply(),8)
                self.assertEqual(j.mydivide(),2)

        def test_subs(self):
                mydata = [[4,2,2],[2,4,-2],[4,-4,0]]
                for i in mydata:
                        n=0
                        j=calculator(mydata[n][0],mydata[n][1])
                        self.assertEqual(j.mysubs(),mydata[n][2])
                        n+=1

        def test_multiply(self):
                mydata = [[4,2,8],[4,-2,-8],[-4,2,-8],[-4,-2,8]]
                for i in mydata:
                        n=0
                        j=calculator(mydata[n][0],mydata[n][1])
                        self.assertEqual(j.mymultiply(),mydata[n][2])
                        n+=1

        def tearDown(self):
                print "Test end!"

if __name__=='__main__':
        #构造测试集
        suite=unittest.TestSuite()
        suite.addTest(calculatortest("test_base"))
        suite.addTest(calculatortest("test_subs"))
        suite.addTest(calculatortest("test_multiply"))
        #运行测试集合
        runner=unittest.TextTestRunner()
        runner.run(suite)
显然这是一个测试加、减、乘、除四则运算程序的测试代码。
1,import unittest引入unittest测试包。
2,from Calculator import calculator 引入被测对象。
3,class calculatortest(unittest.TestCase):建立测试类。
4,def setUp(self):
                print "Test start!"
初始化测试用例程序,在这里只需要打印一个"Test start!"的字符串。
5,def test_base(self): 

开始书写每一个测试函数。
6,def tearDown(self):
                print "Test end!"
结束测试用例程序,在这里只需要打印一个"Test end!"的字符串。
7,if __name__=='__main__':

这一段为定义主函数。
2、Selenium2介绍
接下来我们介绍Selenium2,根据百度百科介绍:Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性――测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能――创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。下面是一段利用python书写的Selenium2测试代码。
#!/usr/bin/env python
#coding:utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest,time,re,os,time
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support import expected_conditions as EC

brower =""
def checkbrowser(brower):
        if brower=="IE":
                driver = webdriver.Ie()
                return driver
        if brower=="firefox":
                driver = webdriver.Firefox()
                return driver

def printlog(functionname,result):
        if(result):
                print "The testcase of "+functionname+" is Pass!"
        else:
                print "The testcase of "+functionname+" is not Pass!"

#判断body里面文字是否存在
def isTextPresent(what):
        mytext=driver.find_element_by_tag_name("body").text
        if what in mytext:
                print "body里不存在"+what
                return True
        else:
                return False

def CheckBaidu(driver,inputString):
        driver.get("http://www.baidu.com")
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_keys(inputString)
        driver.find_element_by_id("su").click()
        if driver.title==inputString+unicode('_百度搜索',encoding='utf-8'):
                print "The Result page Title is error"
                result=False
        else:
                result=True
        time.sleep(5)
        printlog("CheckBaidu()",result)

def Check3testing(driver,checktext,menu):
        driver.get("http://www.3testing.com")
        driver.switch_to.default_content()
        driver.switch_to.frame("head")
        driver.find_element_by_partial_link_text(menu).click()
        driver.switch_to.default_content()
        if isTextPresent(unicode('checktext',encoding='utf-8')):
                result=False
        else:
                result=True
        time.sleep(5)
        printlog("Check3testing()",result)

def Checktaobao(driver):
        driver.get("https:/www.taobao.com")
        driver.find_element_by_id("q").send_keys(unicode('巧克力',encoding='utf-8'))
        driver.find_element_by_class_name("btn-search").click()
        time.sleep(5)
        #当前窗口
        current_windows = driver.current_window_handle
        driver.find_element_by_class_name('J_ClickStat').click()
        time.sleep(10)
        all_handles = driver.window_handles
        for handle in all_handles:
                if handle != current_windows:
                        driver.switch_to.window(handle)
                        break
        time.sleep(10)
        element = WebDriverWait(driver,5,0.5).until(
EC.presence_of_element_located((By.ID,"J_LinkBasket"))
)
        element.click()
        time.sleep(5)
        element=driver.find_element_by_class_name("j_minilogin_iframe")
        driver.switch_to.frame(element)
        driver.find_element_by_class_name("J_Quick2Static").click()
        driver.find_element_by_id("TPL_username_1").send_keys("xianggu625@126.com")
        driver.find_element_by_id("TPL_password_1").send_keys("syz541522")
        driver.find_element_by_class_name("J_Submit").click()
        result=True

if __name__=="__main__":
        driver=checkbrowser("firefox")
        driver.implicitly_wait(10)
        CheckBaidu(driver,unicode('测试',encoding='utf-8'))
        Check3testing(driver,unicode('顾翔',encoding='utf-8'),unicode('我的介绍',encoding='utf-8'))
        Checktaobao(driver)
        driver.quit()
3、用unittest结合Selenium2来设置测试程序
3.1 抽象公共类
首先把一个公共函数抽取出来建立一个类。
mydriver.py
#!/usr/bin/env python
#coding:utf-8
from selenium import webdriver

class drivers:
        def __init__(self):
                f = open("info.txt","r")
                brower=f.readline()
f.close()
                if brower=="IE":
                        self.driver = webdriver.Ie()
                if brower=="firefox":
                        self.driver = webdriver.Firefox()
在mydriver.py中我们定义类drivers,初始化的时候我们打开一个名为info.txt的本地文件,根据文件内的内容来决定使用浏览器的类型。
3.2 建立测试类
然后我们把Checkbaidu,Check3testing,Checktaobao分别建立三个文件,并且使用unittest测试框架。下面是Checkbaidu.py的代码。
3.2.1 Checkbaidu.py
下面是Checkbaidu.py的代码。
#!/usr/bin/env python
#coding:utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import unittest
from mydriver import drivers

class Check3testing(unittest.TestCase):
def setUp(self):
d = drivers()
self.driver=d.driver
self.driver.implicitly_wait(5)
self.driver.get("http://www.3testing.com")

def test_check3testing(self):
checktext = "顾翔"
menu = "我的介绍"
time.sleep(5)
self.driver.switch_to.default_content()
time.sleep(5)
self.driver.switch_to.frame("head")
time.sleep(5)
self.driver.find_element_by_partial_link_text(menu).click()
time.sleep(5)
self.driver.switch_to.default_content()
time.sleep(5)
self.assertEqual(self.driver.title.encode('utf-8'),"啄木鸟软件测试咨询网-顾翔介绍",msg="Title is not right")

def tearDown(self):
self.driver.quit()

if __name__=="__main__":
unittest.main()
1,from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
引入selenium与webdriver所用的模块。
2,import unittest
引入unittest模块。
3,from mydriver import drivers
引入mydriver模块。
4,def setUp(self):
开始初始化。
5,d = drivers()
建立driver类。
6,self.driver=d.driver
建立本类的driver,即self.driver。
7,self.driver.implicitly_wait(5)
建立本类的隐式等待时间为5秒。
8,self.driver.get("http://www.3testing.com")
进入待测试的网页。
9,def test_check3testing(self):
从这里开始进行正式的测试代码。
10,def tearDown(self):
开始结束测试
11,self.driver.quit()
关闭driver
3.2.2 Check3testing.py
下面是Check3testing.py的代码。
#!/usr/bin/env python
#coding:utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import unittest,time
from mydriver import drivers

class Check3testing(unittest.TestCase):

def setUp(self):
d = drivers()
self.driver=d.driver
self.driver.implicitly_wait(5)
self.driver.get("http://www.3testing.com")

def test_check3testing(self):
checktext = "顾翔"
menu = "我的介绍"
time.sleep(5)
self.driver.switch_to.default_content()
time.sleep(5)
self.driver.switch_to.frame("head")
time.sleep(5)
self.driver.find_element_by_partial_link_text(menu).click()
time.sleep(5)
self.driver.switch_to.default_content()
time.sleep(5)
self.assertEqual(self.driver.title.encode('utf-8'),"啄木鸟软件测试咨询网-顾翔介绍",msg="Title is not right")

def tearDown(self):
self.driver.quit()

if __name__=="__main__":
unittest.main()
在这段代码中我们需要注意的是多 frame的切换。
self.driver.switch_to.default_content()
首先需要切换到主frame.
time.sleep(5)
self.driver.switch_to.frame("head")
由于要对frame为head中的元素进行操作,所以必须先切换到head的frame
self.driver.find_element_by_partial_link_text(menu).click()
time.sleep(5)
self.driver.switch_to.default_content()
最后需要验证主frame的 title,所以必须再切换回来。
time.sleep(5)
self.assertEqual(self.driver.title.encode('utf-8'),"啄木鸟软件测试咨询网-顾翔介绍",msg="Title is not right")
3.2.3 Checktaobao.py
下面是Checktaobao.py的代码。
#!/usr/bin/env python
#coding:utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support import expected_conditions as EC
import unittest,time
from mydriver import drivers

class Checktaobao(unittest.TestCase):

def setUp(self):
d = drivers()
self.driver=d.driver
self.driver.implicitly_wait(5)
self.driver.get("https:/www.taobao.com")

def test_Checktaobao(self):
self.driver.find_element_by_id("q").send_keys(unicode('巧克力',encoding='utf-8'))
self.driver.find_element_by_class_name("btn-search").click()
time.sleep(5)
#当前窗口
            current_windows = self.driver.current_window_handle
            self.driver.find_element_by_class_name('J_ClickStat').click()
            time.sleep(5)
            all_handles = self.driver.window_handles
            for handle in all_handles:
                 if handle != current_windows:
                      self.driver.switch_to.window(handle)
                      break
            time.sleep(5)
            for handle in all_handles:
                 if handle == current_windows:
                       self.driver.switch_to.window(handle)
                       self.driver.close()
                       break
            time.sleep(5)
            for handle in all_handles:
                 if handle != current_windows:
                       self.driver.switch_to.window(handle)
                       break
time.sleep(5)
element = WebDriverWait(self.driver,5,0.5).until(
EC.presence_of_element_located((By.ID,"J_LinkBasket"))
)
time.sleep(5)
self.assertIn("巧克力",self.driver.title.encode('utf-8'),msg="没有找到巧克力")


def tearDown(self):
self.driver.quit()

if __name__=="__main__":
unittest.main()
在这段代码中我们需要注意的是多窗口的切换。
1,current_windows = self.driver.current_window_handle
current_windows为当前窗口的句柄,
2,all_handles = self.driver.window_handles
all_handles位所有的句柄
3,for handle in all_handles:
   if handle != current_windows:
       self.driver.switch_to.window(handle)
        break
查看是否存在其他窗口,并进入。
4,for handle in all_handles:
       if handle == current_windows:
       self.driver.switch_to.window(handle)
       self.driver.close()
       break,
返回当前窗口,通过self.driver.close()语句把它关闭。
5,for handle in all_handles:
       if handle != current_windows:
       self.driver.switch_to.window(handle)
        break,
进入打开的新窗口
3.2.4 测试集脚本
最后我们建立测试集脚本。
runtest.py
#!/usr/bin/env python
#coding:utf-8
import unittest
from HTMLTestRunner import HTMLTestRunner

test_dir='./'
discover=unittest.defaultTestLoader.discover(test_dir,pattern="Check*.py")

if __name__=='__main__':
runner=unittest.TextTestRunner()
在这段脚本中我们调用HTMLTestRunner测试模块
1,test_dir='./'
定义测试脚本目录
2,discover=unittest.defaultTestLoader.discover(test_dir,pattern="Check*.py")
测试脚本的满足条件,pattern="Check*.py"为测试脚本目录下,以Check开头的py文件为测试文件。
4、数据驱动
数据驱动在当前的自动化测试中的功能是十分强大的,测试人员只需要改变数据文件中的数据就可以改变测试的一些条件,利用更少的代码来达到更高的测试覆盖率。在python中我们通过调用from xml.dom import minidom来对xml文件进行读写。
4.1 建立数据驱动文件
在这里我们用xml文件作为数据驱动文件。
config.xml
<config>
<base>
<browser>firefox</browser>
</base>
<baidu>
<words>软件测试</words>
<words>大数据</words>
<words>软件工程</words>
<words>云计算</words>
</baidu>
<testing>
<menu>introduce</menu>
<title>顾翔介绍</title>
<menu>class</menu>
<title>课程介绍</title>
<menu>paper</menu>
<title>我的文章</title>
<menu>pictures</menu>
<title>上课图片</title>
<menu>video</menu>
<title>讲课视频</title>
</testing>
<taobao>
<food>糖</food>
<food>花生</food>
<food>巧克力</food>
</taobao>
</config>
1,<browser>firefox</browser>定义所使用的浏览器
2,<baidu>
<words>软件测试</words>
<words>大数据</words>
<words>软件工程</words>
<words>云计算</words>
</baidu>
测试百度所需要测试的查询关键字。
3,<testing>
<menu>introduce</menu>
<title>顾翔介绍</title>
<menu>class</menu>
<title>课程介绍</title>
<menu>paper</menu>
<title>我的文章</title>
<menu>pictures</menu>
<title>上课图片</title>
<menu>video</menu>
<title>讲课视频</title>
</testing>
测试啄木鸟测试培训网的所需要测试的菜单名称。
注:在这里标签不能为数字开头,比如<3testing>,</3testing>。
4,<taobao>
<food>糖</food>
<food>花生</food>
<food>巧克力</food>
</taobao>
测试淘宝所需要测试的查询食品关键字。
4.3测试脚本
Check3testing.py
#!/usr/bin/env python
#coding:utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support import expected_conditions as EC
import unittest,time
from mydriver import drivers
from xml.dom import minidom

class Check3testing(unittest.TestCase):
        def setUp(self):
                d = drivers()
                self.driver=d.driver
                self.driver.implicitly_wait(20)

        def test_check3testing(self):
                dom =  minidom.parse('config.xml')
                root = dom.documentElement
                menus = root.getElementsByTagName('menu')
                titles = root.getElementsByTagName('title')
                i=0
                for title in titles:
                        self.driver.get("http://www.3testing.com")
                        menu = menus[i].firstChild.data
                        title = titles[i].firstChild.data
                        time.sleep(5)
                        self.driver.switch_to.default_content()
                        self.driver.switch_to.frame("head")
                        time.sleep(5)
                        self.driver.find_element_by_id(menu).click()
                        time.sleep(5)
                        self.driver.switch_to.default_content()
                        time.sleep(5)
                        self.assertEqual(self.driver.title.encode('utf-8'),"啄木鸟软件测试咨询网-"+title.encode('utf-8'),msg="Title is not right")
                        i=i+1

        def tearDown(self):
                self.driver.quit()

if __name__=="__main__":
        unittest.main()
Checktaobao.py
#!/usr/bin/env python
#coding:utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support import expected_conditions as EC
import unittest,time
from mydriver import drivers
from xml.dom import minidom

class checkbaidu(unittest.TestCase):
        def setUp(self):
                d = drivers()
                self.driver=d.driver
                self.driver.implicitly_wait(10)

        def test_CheckBaidu(self):
                dom =  minidom.parse('config.xml')
                root = dom.documentElement
                words = root.getElementsByTagName('words')
                i=0
                for word in words:
                        self.driver.get("https://www.baidu.com")
                        inputstring=words[i].firstChild.data
                        self.driver.find_element_by_id("kw").clear()
                        time.sleep(5)
                        self.driver.find_element_by_id("kw").send_keys(inputstring)
                        time.sleep(5)
                        self.driver.find_element_by_id("su").click()
                        time.sleep(5)
                        self.assertEqual(self.driver.title.encode('utf-8'),inputstring.encode('utf-8')+"_百度搜索",msg="Title is not right")
                        i=i+1

        def tearDown(self):
                self.driver.quit()

if __name__=="__main__":
        unittest.main()
Checkbaidu.py
#!/usr/bin/env python
#coding:utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support import expected_conditions as EC
import unittest,time
from mydriver import drivers
from xml.dom import minidom

class Checktaobao(unittest.TestCase):
        def setUp(self):
                d = drivers()
                self.driver=d.driver
                self.driver.implicitly_wait(10)
        
        def test_Checktaobao(self):
                dom =  minidom.parse('config.xml')
                root = dom.documentElement
                foods = root.getElementsByTagName('food')
                i=0
                for food in foods:
                                self.driver.get("https://www.taobao.com")
                                inputstring=foods[i].firstChild.data
                                self.driver.find_element_by_id("q").send_keys(inputstring)
                                self.driver.find_element_by_class_name("btn-search").click()
                                time.sleep(5)
                                #当前窗口
                                current_windows = self.driver.current_window_handle
                                self.driver.find_element_by_class_name('J_ClickStat').click()
                                time.sleep(5)
                                all_handles = self.driver.window_handles
                                for handle in all_handles:
                                        if handle != current_windows:
                                                        self.driver.switch_to.window(handle)
                                                        break
                                time.sleep(5)
                                for handle in all_handles:
                                        if handle == current_windows:
                                                        self.driver.switch_to.window(handle)
                                                        self.driver.close()
                                                        break
                                time.sleep(5)
                                for handle in all_handles:
                                        if handle != current_windows:
                                                        self.driver.switch_to.window(handle)
                                                        break
                                time.sleep(5)
                                element = WebDriverWait(self.driver,5,0.5).until(
                                EC.presence_of_element_located((By.ID,"J_LinkBasket"))
                                )
                                time.sleep(5)
                                self.assertIn(inputstring.encode('utf-8'),self.driver.title.encode('utf-8'),msg="没有找到")
                                i=i+1


        def tearDown(self):
                        self.driver.quit()

if __name__=="__main__":
                        unittest.main()
5、建立HTML格式的测试报告
建立HTML格式的测试报告,只需要在测试脚本机里面加上一些代码
runtest.py
#!/usr/bin/env python
#coding:utf-8
import unittest
from HTMLTestRunner import HTMLTestRunner

test_dir='./'
discover=unittest.defaultTestLoader.discover(test_dir,pattern="Check*.py")

if __name__=='__main__':
runner=unittest.TextTestRunner()
#以下用于生成测试报告
fp=open("result.html","wb")
runner =HTMLTestRunner(stream=fp,title=unicode('测试报告',encoding='utf-8'),description=unicode('测试用例执行报告',encoding='utf-8'))
runner.run(discover)
fp.close()
1,fp=open("result.html","wb")
打开测试报告文件
2,runner =HTMLTestRunner(stream=fp,title=unicode('测试报告',encoding='utf-8'),description=unicode('测试用例执行报告',encoding='utf-8'))
定义测试报告格式,标题和简介
3,runner.run(discover)
运行并且生成HTML报告文件
4,fp.close()
关闭测试报告
6、发送测试报告
测试报告建立成功,我们就可以把这份测试报告作为附件进行发送了,代码如下。
SendMail.py
#!/usr/bin/env python
#coding:utf-8
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

#发送邮箱服务器
smtpserver = 'smtp.126.com'
#发送邮箱
sender = 'xianggu625@126.com'
#接受邮箱
receiver = 'xianggu625@126.com'
#发送邮箱用户名、密码
username = 'xianggu625@126.com'
password = '123456'
#邮件主题
subject = 'Python send email'
#发送的附件
sendfile = open('C:\\Users\\Jerry\\Desktop\\python\\WebDriver\\DataDriver\\result.html').read()

att = MIMEText(sendfile,'base64','utf-8')
att["content-Type"] = 'application/octest-stream'
att["content-Disposition"] = 'attachment; filename="result.html"' 

msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = subject
msgRoot.attach(att)

smtp = smtplib.SMTP()
smtp.connect(smtpserver)
smtp.login(username,password)
smtp.sendmail(sender,receiver,msgRoot.as_string())
smtp.quit()
在这里password = '123456'是为了保护隐私我随便设置的。在这里其实也可以对“发送邮箱服务器”、“发送邮箱”、“接受邮箱”、“发送邮箱用户名,密码”、“邮件主题”和“发送的附件”进行数据参数化。有兴趣的读者可以自行完成。
7、用Junit+ Selenium2来完成自动化测试
在这里我仅给出代码,如果你仔细阅读了本书前面的部分,并且了解Java,应该很容易读懂的,另外在这里我没有实现数据驱动,有兴趣的同学可自己实现。
7.1 check.java
package com.jerry;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
public class check {
//构造函数
check(){

}
//判断元素是否存在
public Boolean isWebElementExist(WebDriver driver,By selector) {
        try {
           driver.findElement(selector);
            return true;
        } catch(Exception e) {
         e.printStackTrace();
         driver.quit();
            return false;
        }
    }

//判断采用什么WebBrowse
public WebDriver checkBrower(String s)
{
WebDriver driver = null;
if (s.equals("Firefox")){
driver = new FirefoxDriver();
}else if(s.equals("HTML")){
driver = new HtmlUnitDriver();
}else if(s.equals("IE")){
System.setProperty("webdriver.ie.driver", "C:\\Program Files\\Internet Explorer\\IEDriverServer.exe");
driver = new InternetExplorerDriver();
}
return driver;
}

//判断body里面文字是否存在
public boolean isTextPresent(WebDriver driver,String what) {
try{
return driver.findElement(By.tagName("body")).getText().contains(what);
}
catch (Exception e){
e.printStackTrace();
return false;// 返回 false
}
}
}
7.2 myWebTestUnit.java
public class myWebTestUnit {
public static WebDriver driver=null;
public static check mycheck=new check();
public static String browser="Firefox";
@Before
public void setUp() throws Exception {
driver=mycheck.checkBrower(browser);
}

@Test
public void testBaidu() {
String inputString="软件测试";
// 进入Baidu
        driver.get("https://www.baidu.com");
        // 通过 id 找到 input 的 DOM
        WebElement element = driver.findElement(By.id("kw"));
        element.clear();
        // 输入关键字
        element.sendKeys(inputString);
        //提交 input 所在的  form
    element.submit();
        //显示搜索结果页面的 title
    try {
     Thread.sleep(2000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
        assertEquals(inputString+"_百度搜索",driver.getTitle());
}

@Test
public void test3testing() {
String menu="我的介绍";
String checktext="顾翔";
driver=mycheck.checkBrower(browser);
driver.get("http://www.3testing.com");
driver.switchTo().defaultContent();
driver.switchTo().frame("head");
        WebElement myinfomation =driver.findElement(By.linkText(menu));
        myinfomation.click();
        driver.switchTo().defaultContent();
        assertEquals(true,mycheck.isTextPresent(driver,checktext));
}

@After
public void teardown() throws Exception {
driver.close();
}
}
其中check.java是公共封装类,myWebTestUnit.java为测试类。
7.3 MyTestSuite.java
package com.jerry;

import  org.junit.runner.RunWith;
import  org.junit.runners.Suite;

@RunWith(Suite. class )
@Suite.SuiteClasses( {
myWebTestUnit.class, 
        } )

public class MyTestSuite  {
}
7.4 HTML格式的报告
对于HTML格式的报告,可以通过Ant+Junit来实现,大家可以通过百度去查找。最后我给出用java来生成的带附件的Email代码。
7.5 EmailSender.java
package com.jerry;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.AuthenticationFailedException;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

/**
 * 实现邮件发送功能
 * @author Administrator
 *
 */
public class EmailSender {
private static final Logger logger = LogManager.getLogger(EmailSender.class);

private String host; // 服务器地址
private String from; // 发件人
private String to; // 收件人 多个收件人以,分隔
private String title; // 主题
private String content; // 内容
private List<File> attachmentlist ; //附件集
private String username; // 用户名
private String password; // 密码
private String sendEmployeeId;
public String getSendEmployeeId() {
return sendEmployeeId;
}
public void setSendEmployeeId(String sendEmployeeId) {
this.sendEmployeeId = sendEmployeeId;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List<File> getAttachmentlist() {
return attachmentlist;
}
public void setAttachmentlist(List<File> attachmentlist) {
this.attachmentlist = attachmentlist;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}

private String port;

public EmailSender(String host, String from, String to, String title,
String content, List attachmentlist, String username, String password,String port) {
this.host = host;
this.from = from;
this.to = to;
this.title = title;
this.content = content;
this.attachmentlist = attachmentlist;
this.username = username;
this.password = password;
this.port=port;
}

public EmailSender(String to, String title,
String content, List attachmentlist) {
this.to = to;
this.title = title;
this.content = content;
this.attachmentlist = attachmentlist;
}

/**
 * 发送邮件
 * @return 发送状态信息 index0:状态 0成功 1失败;index1:描述错误信息
 */
public String[] sendMail(){
String[] result=new String[2];

Session session=null;
Properties props = System.getProperties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.sendpartial", "true");
props.put("mail.smtp.port", port);

if(StringUtils.isBlank(username)){//不需要验证用户名密码
session = Session.getDefaultInstance(props, null);
}else{
props.put("mail.smtp.auth", "true");
EmailAuthenticator auth = new EmailAuthenticator(username, password);
session = Session.getInstance(props, auth); 
}

//设置邮件发送信息
try{
// 创建邮件
MimeMessage message = new MimeMessage(session);
// 设置发件人地址
message.setFrom(new InternetAddress(from));
// 设置收件人地址(多个邮件地址)
InternetAddress[] toAddr = InternetAddress.parse(to);
message.addRecipients(Message.RecipientType.TO, toAddr);
// 设置邮件主题
message.setSubject(title);
// 设置发送时间
message.setSentDate(new Date());
// 设置发送内容
Multipart multipart = new MimeMultipart();
MimeBodyPart contentPart = new MimeBodyPart();
contentPart.setText(content);
multipart.addBodyPart(contentPart);
//设置附件
if(attachmentlist!=null && attachmentlist.size()>0){
for(int i = 0 ; i < attachmentlist.size();i++){
MimeBodyPart attachmentPart = new MimeBodyPart();

FileDataSource source = new FileDataSource(attachmentlist.get(i));
attachmentPart.setDataHandler(new DataHandler(source));
attachmentPart.setFileName(MimeUtility.encodeWord(attachmentlist.get(i).getName(), "gb2312", null));
multipart.addBodyPart(attachmentPart);

}
message.setContent(multipart);

//登录SMTP服务器
if (StringUtils.isBlank(username)) {
// 不需验证
Transport.send(message);
} else {
// 需要验证
Transport transport = session.getTransport("smtp");
transport.connect();
transport.sendMessage(message, message.getAllRecipients());
transport.close(); 
}

result[0]="0";
result[1]="发送成功";

logger.info("邮件发送成功!发送人:"+from);

}catch(MessagingException mex){
result[0]="1";
result[1]="邮件服务器发生错误";

if(mex instanceof AuthenticationFailedException){
result[1]="用户名或密码错误";
}
} catch (Exception e) {
result[0]="1";
result[1]="系统异常";
}
return result;
}

public static void main(String[] args){
String SNMPTServer = "smtp.126.com";
String from="xianggu625@126.com";
String to="xianggu625@126.com";
String title="发送测试报告";
String content="附件为测试报告";
String username="xianggu625@126.com";
String password="123456";
String port="25";
List list=new ArrayList();
list.add(new File("C:\\Myproject\\WebDemo\\junit.rar"));
EmailSender sender=new EmailSender(SNMPTServer,from,to,title,content,list,username,password,port); 
String [] result = sender.sendMail();
System.out.println(result[1]+"ffffffffffffffff");
}
}
/**
 * class MyAuthenticator用于邮件服务器认证 构造器需要用户名、密码作参数
 */
class EmailAuthenticator extends Authenticator {
private String username = null;
private String password = null;
public EmailAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}

软件测试

  

   

投稿关闭窗口打印