TestNG+PO模式打造自动化测试框架教程详解

今天我们来讲一下TestNG+PO模式打造自动化测试框架,分为四小点跟大家来聊一聊:

1、Java+TestNG框架基本使用

2、web自动化测试PO模式与分层设计理念

3、PO模式与TestNG结合打造自动化测试框架

4、TestNG集成Allure自动化测试报告


1、Java+TestNG框架基本使用

一.testNG介绍

TestNG是Java中的一个测试框架, 类似于JUnit 和NUnit, 功能都差不多, 只是功能更加强大,使用也更方便

Java中已经有一个JUnit的测试框架了。 TestNG比JUnit功能强大的多。 测试人员一般用TestNG来写自动化测试。 开发人员一般用JUnit写单元测试。

官方网站: http://testng.org/doc/index.html

二. eclipse中安装testNG

1. 打开Eclipse Help ->Install New Software , 然后Add "http://beust.com/eclipse"

三. testNG最简单的测试

package TankLearn2.Learn;import org.junit.AfterClass;import org.junit.BeforeClass;import org.testng.annotations.Test; public class TestNGLearn1 {     @BeforeClass    public void beforeClass() {        System.out.println("this is before class");    }     @Test    public void TestNgLearn() {        System.out.println("this is TestNG test case");    }     @AfterClass    public void afterClass() {        System.out.println("this is after class");    }}

四.testNG最基本的注解

注解

描述

@BeforeSuite

注解的方法将只运行一次,运行在所有测试前此套件中。

@AfterSuite

注解的方法是将只运行一次此套件中的所有测试都运行之后。

@BeforeClass

注解的方法将只运行一次先行先试在当前类中的方法调用。

@AfterClass

注解的方法将只运行一次后已经运行在当前类中的所有测试方法。

@BeforeTest

注解的方法将被运行之前的任何测试方法属于内部类的 <test>标签的运行。

@AfterTest

注解的方法将被运行后,所有的测试方法,属于内部类的<test>标签的运行。

@BeforeGroups

组的列表,这种配置方法将之前运行。此方法是保证在运行属于任何这些组第一个测试方法,该方法被调用。

@AfterGroups

组的名单,这种配置方法后,将运行。此方法是保证运行后不久,最后的测试方法,该方法属于任何这些组被调用。

@BeforeMethod

注解的方法将每个测试方法之前运行。

@AfterMethod

被注释的方法将被运行后,每个测试方法。

@DataProvider

标志着一个方法,提供数据的一个测试方法。注解的方法必须返回一个Object[] [],其中每个对象[]的测试方法的参数列表中可以分配。

该@Test 方法,希望从这个DataProvider的接收数据,需要使用一个dataProvider名称等于这个注解的名字。

@Factory

作为一个工厂,返回TestNG的测试类的对象将被用于标记的方法。该方法必须返回Object[]。

@Listeners

定义为一个测试类的监听器。

@Parameters

介绍如何将参数传递给@Test方法。

@Test

标记一个类或方法作为测试的一部分。

五. testNG中如何执行测试

1.第一种直接执行:右键要执行的方法,点Run As ->TestNG Test

2. 第二种: 通过testng.xml文件来执行. 把要执行的case, 放入testng.xml文件中。 右键点击testng.xml, 点Run As

testng.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="Suite1">    <test name="test12">        <classes>            <class name="TankLearn2.Learn.TestNGLearn1" />        </classes>    </test></suite>

六.testNG按顺序执行case

1.在testng.xml中,可以控制测试用例按顺序执行。 当preserve-order="true"时,可以保证节点下面的方法是按顺序执行的

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="Suite1">    <test name="test12" preserve-order="true">        <classes>            <class name="TankLearn2.Learn.TestNGLearn1">                <methods>                    <include name="TestNgLearn3" />                    <include name="TestNgLearn1" />                    <include name="TestNgLearn2" />                </methods>            </class>        </classes>    </test></suite>

七. testNG异常测试

测试中,有时候我们期望某些代码抛出异常。

TestNG通过@Test(expectedExceptions) 来判断期待的异常, 并且判断Error Message

package TankLearn2.Learn; import org.testng.annotations.Test; public class ExceptionTest {        @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp="NullPoint")    public void testException(){        throw new IllegalArgumentException("NullPoint");    }}

八.testNG组测试

TestNG中可以把测试用例分组,这样可以按组来执行测试用例比如:

package TankLearn2.Learn; import org.testng.annotations.Test; public class GroupTest {        @Test(groups = {"systemtest"})    public void testLogin(){        System.out.println("this is test login");    }        @Test(groups = {"functiontest"})    public void testOpenPage(){        System.out.println("this is test Open Page");    }}

然后在testng.xml中 按组执行测试用例

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="Suite1">    <test name="test1">        <groups>        <run>        <include name="functiontest" />        </run>    </groups>    </test></suite>

九.testNG参数化测试

软件测试中,经常需要测试大量的数据集。 测试代码的逻辑完全一样,只是测试的参数不一样。 这样我们就需要一种 “传递测试参数的机制”。 避免写重复的测试代码

TestNG提供了2种传递参数的方式。

第一种: testng.xml 方式使代码和测试数据分离,方便维护

第二种:@DataProvider能够提供比较复杂的参数。 (也叫data-driven testing)

方法一: 通过testng.xml 传递参数给测试代码

package TankLearn2.Learn;import org.testng.annotations.Parameters;import org.testng.annotations.Test;    public class ParameterizedTest1 {        @Test    @Parameters("test1")    public void ParaTest(String test1){        System.out.println("This is " + test1);    }}
testng.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="Suite1">        <parameter name="test1" value="Tank" />        <parameter name="test1" value="Xiao" />    <test name="test12">        <classes>            <class name="TankLearn2.Learn.ParameterizedTest1" />        </classes>    </test></suite>

方式二: 通过DataProvider传递参数

package TankLearn2.Learn; import org.testng.annotations.DataProvider;import org.testng.annotations.Test; public class DataProviderLearn {        @DataProvider(name="user")    public Object[][] Users(){        return new Object[][]{                {"root","passowrd"},                {"cnblogs.com", "tankxiao"},                {"tank","xiao"}        };    }        @Test(dataProvider="user")    public void verifyUser(String userName, String password){        System.out.println("Username: "+ userName + " Password: "+ password);    }}

十.testNG忽略测试

有时候测试用例还没准备好, 可以给测试用例加上@Test(enable = false), 来禁用此测试用例

package TankLearn2.Learn; import org.testng.annotations.Test; public class TesgNGIgnore {        @Test(enabled = false)    public void testIgnore(){        System.out.println("This test case will ignore");    }}

十一.testNG依赖测试

有时候,我们需要按顺序来调用测试用例, 那么测试用例之间就存在依赖关系。 TestNG支持测试用例之间的依赖

package TankLearn2.Learn; import org.testng.annotations.Test; public class DependsTest {        @Test    public void setupEnv(){        System.out.println("this is setup Env");    }        @Test(dependsOnMethods = {"setupEnv"})    public void testMessage(){        System.out.println("this is test message");    }}

十二.testNG测试报告结果

测试报告是测试非常重要的部分.

TestNG默认情况下,会生产两种类型的测试报告HTML的和XML的。 测试报告位于 "test-output" 目录下.

当然我们也可以设置测试报告的内容级别.

verbose="2" 标识的就是记录的日志级别,共有0-10的级别,其中0表示无,10表示最详细

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="Suite1">    <test name="test12" verbose="2">        <classes>            <class name="TankLearn2.Learn.TestNGLearn1" />        </classes>    </test></suite>

web自动化测试PO模式与分层设计理念

一、什么是PO模式

全称:page object model 简称:POM/PO

PO模式最核心的思想是分层,实现松耦合!实现脚本重复使用,实现脚本易维护性!

主要分三层:

1.基础层BasePage:封装一些最基础的selenium的原生的api方法,元素定位,框架跳转等。

2.PO层:元素定位、获得元素对象,页面动作

3.测试用例层:业务逻辑,数据驱动!

三者的关系:PO层继承继承层,测试用例层调用PO层!

二、什么是自动化测试框架

说到自动化框架,我相信很多人应该都听过这个词,但是不知其到底是个什么东西,为什么要用自动化框架。有很多人堆自动化框架都是懵懵懂懂,就跟谈恋爱一样,朦胧美!

一个好的自动化测试框架是可以让不那么懂技术的人也可以写自动化测试脚本的,

一个好的自动化测试框架可以减少自动化测试中脚本管理和维护当中的人力物力和财力。

其实自动化框架的一个最大的意义在于可重用性。因为在框架里,你可以实现很多的通用功能来简化整个脚本的开发过程。并且生成美观的测试报告。

三、非PO模式和PO模式优缺点对比

非PO模式

PO模式

面向过程的线性脚本

POM把页面元素定位和业务操作流程分开。实现松耦合。

复用性差

UI元素的改变不需要修改业务逻辑代码。只需要找到对应的PO页修改定位即可,数据代码分离

维护性差

PO能使我们的测试代码提高代码的可读性,高复用性,可维护性。

四、如何从0到1搭建PO模型

非PO模式举个栗子:有如下百度搜索脚本:

import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
 
class Test(unittest.TestCase):
    def test01(self):
        # 打开浏览器
        driver = webdriver.Chrome()
        # 加载百度首页
        driver.get('http://www.baidu.com')
        # 在百度搜索栏中输入软件测试
        driver.find_element(By.ID, 'kw').send_keys('软件测试')
        # 点击百度一下按钮
        driver.find_element(By.ID, 'su').click()
 
    def test02(self):
        # 打开浏览器
        driver = webdriver.Chrome()
        # 加载百度首页
        driver.get('http://www.baidu.com')
        # 在百度搜索栏中输入软件测试
        driver.find_element(By.ID, 'kw').send_keys('硬件测试')
        # 点击百度一下按钮
        driver.find_element(By.ID, 'su').click()

如何把上述栗子改成PO模式呢?

1、基础层BasePage

from selenium import webdriver
 
class BasePage:
    #构造方法
    def __init__(self):
        # 打开浏览器
        self.driver = webdriver.Chrome()  # Alt+Enter
        # 加载百度首页
        self.driver.get('http://www.baidu.com')
 
    #封装定位元素
    def find_ele(self,*args):
        ele = self.driver.find_element(*args)
        return ele

2、PO层:封装百度页面元素定位,元素对象以及页面操作

from selenium.webdriver.common.by import By
from base.base_page import BasePage
 
class BaiduPage(BasePage):
    #元素定位,
    baidu_text_loc = (By.ID, 'kw')
    baidu_submit_loc = (By.ID, 'su')
    #获得元素对象,
    def get_text_obj(self):
        ele = self.find_ele(*BaiduPage.baidu_text_loc)
        return ele
    def get_submit_obj(self):
        ele = self.find_ele(*BaiduPage.baidu_submit_loc)
        return ele
    #页面操作
    def search(self,search_string):
        self.get_text_obj().send_keys(search_string)
        self.get_submit_obj().click()

3、测试用例层:业务逻辑和数据驱动

from ddt import ddt, data
from po.baidu_page import BaiduPage
 
@ddt
class BaiduTest(unittest.TestCase):
 
    @data('软件测试','硬件测试')
    def test01(self,seaString):
        BaiduPage().search(seaString)
        time.sleep(5)
 
if __name__ == '__main__':
    unittest.main()

从上面的PO案例:让我们更加了解清晰PO的优点在于:

1.POM把页面元素定位和业务操作流程分开。实现松耦合。
2.UI元素的改变不需要修改业务逻辑代码。只需要找到对应的PO页修改定位即可,数据代码分离
3.PO能使我们的测试代码提高代码的可读性,高复用性,可维护性。

五、自动化测试框架和PO的关系

自动化框架=po+各种封装(日志处理封装,全局配置文件的封装,数据库连接的封装,excel操作封装,数据驱动封装等)

其实想要胜任UI自动化测试岗位还需要掌握以下内容:

1.python或java

2.selenium的API

3.unittest/pytest单元测试框架

4.htmltestrunner/allure测试报告

5.数据驱动dtt(excel,yaml,mysql)或pytest中的fixtrue

6.关键字驱动:公共类,方法封装,随机数,数据库连接,全局登录

7.全局配置文件处理

8.日志处理

9.断言

10.第三方库

11.git和github或码云集成开发!

12.jenkins持续集成

3、PO模式与TestNG结合打造自动化测试框架

TestNG应该是程序员和测试人员一个比较好的选择,这里就不说在这个基础上衍生的自动化测试框架了,只是说程序员怎么借助TestNG来更好的方便我们做单元测试,一次性搞定各种情况。

一、IDEA+SpringBoot+TestNG

1、依赖

        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>7.0.0</version>
            <scope>test</scope>
        </dependency>

2、IDEA下载插件

二、代码演示

1、创建测试类

public class TeatNGTest {
    @Test(groups = "test1")
    @Parameters({"param1","param2"})
    public void test1(String param1,String param2){
        System.out.println("test1 ceshi");
        System.out.println("param1="+param1+",param2="+param2);
    }
 
    @Test(groups = "test2")
    @Parameters({"param1","param2"})
    public void test2(String param1,String param2){
        System.out.println("test2 ceshi");
        System.out.println("param1="+param1+",param2="+param2);
    }
 
    @Test(groups = "test3")
    @Parameters({"param1","param2"})
    public void test3(String param1,String param2){
        System.out.println("test3 ceshi");
        System.out.println("param1="+param1+",param2="+param2);
    }
 
 
}

2、点击需要测试的类右键选择Create TestNG XML

3、编辑TestNG.xml文件

三、配置文件

1、需要测试的类需要加上TestNG的注解

2、TestNG.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
    <!--分组对应测试方法上的分组,name属性对应测试方法上定义的group名,
    如果包含就是include,不包含就是exclude,如果添加分组了,下面的
    methods就不需要了,直接通过分组来控制粒度,如果不需要分组就不需要groups
    标签,直接放开methods标签,指定执行的方法,同时该可以传简单的参数,
    但是复杂的参数不行,parameter标签的参数与方法上的注解属性相同,
    如果有不同的案例,那就新建不同的test标签-->
    <groups>
        <run>
            <include name="test1"/>
            <exclude name="test2"/>
            <exclude name="test3"/>
        </run>
    </groups>
 
    <test verbose="2" preserve-order="true"
          name="测试用例1">
        <parameter name="param1" value="1"/>
        <parameter name="param2" value="2"/>
        <classes>
            <class name="测试类的全限定名">
                <!--<methods>-->
                    <!--<include name="test1"/>-->
                    <!--<include name="test2"/>-->
                    <!--<include name="test3"/>-->
                <!--</methods>-->
            </class>
        </classes>
    </test>
 
    <test verbose="2" preserve-order="true"
          name="测试用例2">
        <parameter name="param1" value="1"/>
        <parameter name="param2" value="2"/>
        <classes>
            <class name="测试类的全限定名">
                <!--<methods>-->
                    <!--<include name="test1"/>-->
                    <!--<include name="test2"/>-->
                    <!--<include name="test3"/>-->
                <!--</methods>-->
            </class>
        </classes>
    </test>
</suite>

四、执行

1、点击testNG.xml,右键执行

2、结果

Connected to the target VM, address: '127.0.0.1:52363', transport: 'socket'
test1 ceshi
param1=1,param2=2
Disconnected from the target VM, address: '127.0.0.1:52363', transport: 'socket'
test1 ceshi
param1=1,param2=2
 
===============================================
All Test Suite
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
===============================================

3、导出文件

4、TestNG集成Allure自动化测试报告

1、在项目中导入 testng 和 allure2 坐标和对应设置

<properties>

<maven.compiler.target>1.8</maven.compiler.target>

<maven.compiler.source>1.8</maven.compiler.source>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<maven.compiler.encoding>UTF-8</maven.compiler.encoding>

<aspectj.version>1.9.2</aspectj.version>

</properties>

<dependency>

<groupId>org.testng</groupId>

<artifactId>testng</artifactId>

<version>6.14.3</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>io.qameta.allure</groupId>

<artifactId>allure-testng</artifactId>

<version>2.6.0</version>

</dependency>

2、加入 maven-surefire-plugin 插件并进行配置

<build>

<plugins>

<plugin>

<!-- maven-surefire-plugin 配合testng/junit执行测试用例的maven插件 -->

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-surefire-plugin</artifactId>

<version>2.22.1</version>

<configuration>

<!-- 测试失败后,是否忽略并继续测试 -->

<testFailureIgnore>true</testFailureIgnore>

<suiteXmlFiles>

<!-- testng配置文件名称 -->

<suiteXmlFile>testng.xml</suiteXmlFile>

</suiteXmlFiles>

<!--设置参数命令行 -->

<argLine>

<!-- UTF-8编码 -->

-Dfile.encoding=UTF-8

<!-- 配置拦截器 -->

-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"

</argLine>

<systemProperties>

<property>

<!-- 配置 allure 结果存储路径 -->

<name>allure.results.directory</name>

<value>${project.build.directory}/allure-results</value>

</property>

</systemProperties>

</configuration>

<dependencies>

<!-- aspectjweaver maven坐标 -->

<dependency>

<groupId>org.aspectj</groupId>

<artifactId>aspectjweaver</artifactId>

<version>${aspectj.version}</version>

</dependency>

</dependencies>

</plugin>

</plugins>

</build>

3.在idea中执行maven命令

3.1 点击 maven -->3.2 点击 m --->3.3 弹框输入命令io.qameta.allure:allure-maven:serve 命令启动 allure 内置服务,运行完成之后就会弹出 allure 页面

4. 自动在浏览器弹出allure报告

5. 选择graphs查看图形结构


6. 选择 Behaviors 查看每个用例的详情信息

希望本文对你有所帮助~~如果对软件测试、接口测试、自动化测试、面试经验交流感兴趣可以私聊我或关注公众号“特斯汀软件测试”。免费领取最新软件测试大厂面试资料和Python自动化、接口、框架搭建学习资料!技术大牛解惑答疑,同行一起交流。

举报
评论 0