TestNG 单元测试框架的入门与实践

大部分参考 TestNG学习链接 的文章,本文为个人笔记记录以及补充。


Java中的开源自动化测试框架,其灵感来自JUnit和NUnit,涵盖了JUnit4整个核心的功能,但引入了一些新的功能,使其功能更强大,使用更方便。

JUnit是ava语言的单元测试框架。Junit详解
灯泡:串起来的线 = Selenium编写的测试用例:JUnit管理用例

1 使用教程

1.1 创建 Maven 项目

![[Pasted image 20240727110549.png]]

1.2 pom.xml 引入依赖

<dependencies>  
    <dependency>
        <groupId>org.testng</groupId>  
        <artifactId>testng</artifactId>  
        <version>6.10</version>  
    </dependency>
</dependencies>

1.3 创建待测试类

public class Test_01 {  
    public static void main (String[] args) {  
        System.out.println("我是待测试组");  
    }  
}
  • 点击选中刚刚创建的类名,按Alt+Entet键,创建单元测试类

在这里插入图片描述

  • 勾选三个选项

![[Pasted image 20240803101843.png]]

  • 生成代码结构如下

![[Pasted image 20240803101931.png]]

  • 添加打印语句测试效果

![[Pasted image 20240803102205.png]]

2 TestNG 知识点

2.1 注释

注释描述运行次数运行顺序
@BeforeSuite所有测试方法运行之前11
@BeforeTestTest标签内的所有测试方法12
@BeforeClass调用当前类的第一个测试方法之前13
@BeforeGroups在组列表运行之前运行取决于组列表个数4
@BeforeMethod当前类中的每个测试方法之前取决于测试方法个数5
——测试方法——6
@AfterMethod当前类中的每个测试方法之后取决于测试方法个数7
@AfterGroups在组列表运行之前运行取决于组列表个数8
@AfterClass调用当前类的第一个测试方法之后19
@AfterTestTest标签内的所有测试方法110
@AfterSuite所有测试运行之后运行111

其中,组列表结构运行顺序如下

![[Group_TestNG.png]]

2.2 断言

1. 硬断言

  • 硬断言(‌Assert类)‌:提供了一系列静态方法,‌用于测试实际值与期望值是否相符。‌如果断言失败,‌即实际值与期望值不匹配,‌TestNG 会抛出异常并停止执行后续的代码。‌‌
   1、assertEqual (actual value,expected value )
   断言两个值相等。
   
   2、assertTrue(boolean condition)
   断言一个条件为真;
   
   3、assertFalse(boolean condition) 
   断言一个条件为假;
   
   4、assertNotNull(java.lang.Object object)
   断言一个对象不为空(null);
   
   5、assertNull(java.lang.Object object)
   断言一个对象为空(null);
   
   6、assertSame(java.lang.Object expected, java.lang.Object actual) 
   断言两个对象引用相同的对象;
   
   7、assertNotSame(java.lang.Object unexpected, java.lang.Object actual)
   断言两个对象不是引用同一个对象;
   
   8、assertArrayEquals(expectedArray, resultArray) 
   断言预期数组和结果数组相等。
  • 简单例子
	@Test  
	public void testAssert () throws Exception {  
	    Assert.assertEquals(4, 2 * 2);  
	    System.out.println("通过");  
	    Assert.assertEquals(5, 1+9);  
	}

运行结果

在这里插入图片描述

2. 软断言

  • 软断言(‌SoftAssert类)‌:‌软断言是TestNG提供的一种更灵活的断言方式,‌它允许在断言失败后继续执行测试。‌SoftAssert类允许开发者创建实例对象,‌并通过该对象调用相关的方法进行断言。‌这种机制适用于那些可以容忍一定错误率的测试场景,‌例如在测试大量数据时,‌部分测试用例失败不会影响整个测试套件的继续执行。
    • SoftAssert.java,软断言需要创建实例对象,才能调用相关实例方法进行软断言
    • assertAll()一定要放在该测试类的最后一个断言后面
	@Test 
	public void testSoftAssert(){ 
		//实例化SoftAssert 
		SoftAssert assertion = new SoftAssert(); 
		assertion.assertEquals(5, 6,"我俩不是一样大"); 
		//这个必须放到最后,没什么可说的 
		assertion.assertAll(); }
	}

2.3 参数化测试

1. XML传参

  • 测试方法代码
public class 传参类名 {
 
    @Test(enabled=true)
    @Parameters({"param1", "param2"})
    public void A方法(String param1, int param2) {
        // 代码块
        Assert.assertFalse(false);
    }
}
  • XML配置
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
  <test name="Test">
    <parameter name="param1" value="1011111" />
    <parameter name="param2" value="10" />
    <classes>
      <class name="传参类名地址"/>
    </classes>
  </test>
</suite> 

2. 使用@DataProvider传递参数

  • 测试方法
public class 传参类名 {
 
    @DataProvider(name = "参数提供")
    public Object[][] provideData() {
        return new Object[][] { { 10, 20 }, { 100, 110 }, { 200, 210 } };
    }
    
    @Test(dataProvider = "参数提供")
    public void TestNgLearn1(int param1, int param2) {
        // 代码块
        Assert.assertFalse(false);
    }
    
}

2.4 常用的方法属性

以下不是完整类,只是各个属性的汇总(作用级别可能是类/方法体等等)

// 整个类之前添为组
@Test(groups= "组名")
public class 类名 {
}
	// 方法前添为组
	@Test(groups="组名")  
	public void 测试方法名() {  
	    // 测试方法
	}
	
    // 在指定组名前运行的方法
	@BeforeGroups(groups="组名")  
	public void 测试方法名() {  
	    // 代码块
    }
    
    // 忽略测试
	@Test(enabled=false)
    public void 测试方法名() {
	    // 代码块
    }
    
    // 超时测试
    @Test(timeOut = 5000) 
    public void testThisShouldPass() throws InterruptedException {
        Thread.sleep(4000);
    }
    
    // 异常测试
    @Test(expectedExceptions = ArithmeticException.class)
    public void divisionWithException() {
        int i = 1 / 0;
        System.out.println("After division the value of i is :"+ i);
    }
    
    // 依赖测试
    @Test(enabled=true)
    public void A方法() {
        // 代码块
        Assert.assertFalse(true);// 硬断言为假,则此方法为FALSE了导致不能被其他方法依赖
    }
    @Test(dependsOnMethods= {"A方法"})
    public void B方法() {
        // 代码块
        // 结果为不可依赖
    }

3 综合例子

3.1 测试类内运行

  • 完整代码如下
import org.testng.Assert;  
import org.testng.annotations.*;  
  
public class newTest {  
      
    @Test(groups="第一组")  
    public void test01() {  
        System.out.println("第一组测试方法test01");  
        Assert.assertTrue(true);  // 硬断言
    }  
      
    @Test(groups="第一组")  
    public void test02() {  
        System.out.println("第一组测试方法test02");  
        Assert.assertTrue(true);  
    }  
      
    @Test(groups="第二组")  
    public void test2()  
    {  
        System.out.println("第二组测试方法test2");  
        Assert.assertTrue(true);  
    }  
      
    @BeforeTest  
    public void beforeTest()  
    {  
        System.out.println("0_beforeTest");  
    }  
      
    @AfterTest  
    public void afterTest()  
    {  
        System.out.println("1_afterTest");  
    }  
      
    @BeforeClass  
    public void beforeClass()  
    {  
        System.out.println("0_beforeClass");  
    }  
      
    @AfterClass  
    public void afterClass()  
    {  
        System.out.println("1_afterClass");  
    }  
      
    @BeforeSuite  
    public void beforeSuite()  
    {  
        System.out.println("0_beforeSuite");  
    }  
      
    @AfterSuite  
    public void afterSuite()  
    {  
        System.out.println("1_afterSuite");  
    }  
      
    //只对第一组有效,即test01和test02  
    @BeforeGroups(groups="第一组")  
    public void beforeGroups()  
    {  
        System.out.println();  
        System.out.println("000_beforeGroups");  
        }  
      
    //只对第一组有效,即test01和test02  
    @AfterGroups(groups="第一组")  
    public void afterGroups()  
    {  
        System.out.println("111_afterGroups");  
        System.out.println();  
    }  
      
    @BeforeMethod  
    public void beforeMethod()  
    {  
        System.out.println("00_beforeMethod");  
    }  
      
    @AfterMethod  
    public void afterMethod()  
    {  
        System.out.println("11_afterMethod");  
    }  
      
}
  • 运行结果如下

![[Pasted image 20240803112228.png]]

3.2 XML方式运行

模板结构(参考理解)

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="套件名称" verbose="运行级别" >
  <test name="测试用例名A">
    <classes>
      <class name="类名1"/>
    </classes>
  </test>
  <!--    选中所有包    -->
   <test name = "allTestsInAPackage" >
    <packages>
		<package name = "whole.path.to.package.*" />
    </packages>
   </test>
   
  <!--  选择一个包的部分组      -->
  <test name = "测试用例名X" >
   <groups>
      <run>
         <include name = "includedGroup" />
      </run>
    </groups>
    <packages>
      <package name = "whole.path.to.package.*" />
    </packages>
   </test>
   
  <!--  排除一个包的部分组      -->
  <test name = "测试用例名X" >
   <groups>
      <run>
         <exclude name = "includedGroup" />
      </run>
    </groups>
    <packages>
      <package name = "whole.path.to.package.*" />
    </packages>
   </test>
   
  <!--   选中类的某个用例     -->
  <test name = "测试用例名X" >
   <classes>
	   <class name="类路径" >
	       <methods>
	         <include name = "方法A" />
	         <include name = "方法B" />
		   </methods>
	  </class>
   </classes>
  </test>

</suite>
  • 标签说明
<suite>  套件,根标签,通常由几个<test组成>
  属性:
  name            套件的名称,必须属性;
  verbose         运行的级别或详细程度,,从0开始到10,其中10为最详细;
  parallel        是否运行多线程来运行这个套件,默认为none;
  thread-count    如果启用多线程,用于指定开户的线程数(parallel参数非none时);
      1)methods:方法层级,测试用例级别的多线程。
      2)tests:每个<test>标签都将处于一个单独的线程中(包含不是线程安全的所有类分组)
      3)classes:类级别并发;
      4)instances:实例级别,同一实例中的所有方法,
  annotations     在测试中使用的注释类型;
  time-out        使用的默认超时时间; 
--------------------------分割线--------------------------
<test>   测试用例,name为必须属性;

<classes>  用例中包含的类,子标签为<class>;
<class>    测试类,name为必须属性;

<packages> 用例中包含的包,包中所有的方法都会执行,子标签为<package>;
<package>  测试包,name为必须属性;

<methods>  指定测试类中包含或排除的方法,子类为<include>,<exclude>;
<include>  指定需要测试的方法,name为必须属性;
<exclude>  指定类中不需要测试的方法,name为必须属性;

<groups>   指定测试用例中要运行或排除运行的分组,子标签为<run>,<run>下包含<include>,<exclude>标签,<include>,<exclude>的name指定运行、不运行的分组;
<test name = "aFewTestsFromAClass" >
   <classes>
   <class name="whole.path.to.package.className" >
      <methods>
         <include name = "firstMethod" />
         <include name = "secondMethod" />
         <include name = "thirdMethod" />
      </methods>
   </class>
   </classes>
</test>
<test name = "测试名" >
   <groups>
      <run>
         <include name = "includedGroup" />
      </run>
   </groups>
   <packages>
      <package name = "whole.path.to.package.*" />
   </packages>
</test>

还是以前面的测试为例:

  • 右键项目,创建XML文件,直接输入testng.xml(博主一时没找着能直接创建xml格式的选项,于是直接创建普通文件,加上.xml限定名也一样)
    ![[Pasted image 20240803135847.png]]

  • 代码如下

    • 技巧:在输入要测试的用例类名时,IDEA会自动提示,直接选中目标类就好。
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >  
  
<suite name="Suite" parallel="none">  
    <test name="Test">  
        <classes>  
            <class name="newTest"/>  
        </classes>  
    </test> 
  
    <test name="Test2">  
        <classes>
            <class name="Test_01Test"/>  
        </classes>
	</test> 
</suite> 
  • 右键点击运行即可

4 美化输出结果

  • 编辑运行方式

![[Pasted image 20240803160617.png]]

  • 美化后的输出结果文件位置

![[Pasted image 20240803161004.png]]

  • 浏览器打开效果

![[Pasted image 20240803161048.png]]

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值