【JAVA】关于自动化测试所需要学习的java基础知识笔记

文章目录

      • 1.JAVA相关
        • 1.1 java三大特性
        • 1.2 抽象类和接口的区别
        • 1.3 反射
          • 1.3.1 反射的思想
          • 1.3.2 什么是反射
          • 1.3.3 xml解析代码
          • 1.3.4 通过字节码可以使用的方法
        • 1.4 HashMap和HashSet
        • 1.5 File类和IO类
        • 1.6 log4j的使用
      • 2. 正则表达式
      • 3.XML
        • 3.1 dom4j
        • 3.2 dom4j解析技术
      • 4. JDBC
        • 4.1 什么是JDBC以及一些基础的SQL语句
          • 4.1.1 创建表
          • 4.1.2 插入行
          • 4.1.3 删除行
          • 4.1.4 更新数据
          • 4.1.5 查询数据
          • 4.1.6 连接
        • 4.2 工具 Navicat Premium 的下载与破解
        • 4.3 操作步骤
        • 4.4 写一个简单的DBUtil框架
      • 5.TestNG
        • 5.1 单元测试的概念
        • 5.2 TestNG的安装
        • 5.3 项目集成testNG
        • 5.4 testNG的书写和运行
        • 5.5 eclipse 乱码问题
        • 5.6 testNG中一些常用的注解
        • 5.7 TestNG 执行 junit 测试
        • 5.8 断言
        • 5.9 数据驱动(Data Provider)

1.JAVA相关

1.1 java三大特性

封装,继承,多态。
其中多态详解请看这篇博文:
https://www.cnblogs.com/chenssy/p/3372798.html
当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
其中有一个经典实例:
https://blog.csdn.net/thinkGhoster/article/details/2307001

1.2 抽象类和接口的区别

【JAVA】关于自动化测试所需要学习的java基础知识笔记_第1张图片
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第2张图片

1.3 反射

1.3.1 反射的思想

如果对象的属性值要支持可扩展,那么属性的值我们就不能够在代码中去指定,必须通过某种方法分离出来,反射其实也是一种解耦的思想。

1.3.2 什么是反射

java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用他的任意一个方法和属性;这种动态获取信息以及动态调用对象方法的功能成为java语言的反射机制。

想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属性,类名,父类名,实现的所有接口等等),每一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码文件对象。

获取字节码文件对象的三种方式:

  1. Class clazz1 = Class.forName("全限定类名");
    通过Class类中的静态方法forName,直接获取到一个类的字节码文件对象,此时该类还是源文件阶段,并没有变为字节码文件。
例如:
	Class clazz0=Class.forName("com.lemon.day13.section01.Student");
  1. Class clazz2 = 类名.class;
    当类被加载成.class文件时,此时这个类变成了.class,在获取该字节码文件对象,也就是获取自己, 该类处于字节码阶段。
例如:
	Class clazz=Student.class;
  1. Class clazz3 = p.getClass();
    通过类的实例获取该类的字节码文件对象,该类处于创建对象阶段。

有了字节码文件对象才能获得类中所有的信息,我们在使用反射获取信息时,也要考虑使用上面哪种方式获取字节码对象合理,视不同情况而定。

反射详解:https://www.cnblogs.com/whgk/p/6122036.html

1.3.3 xml解析代码

这里解析的是课程中关于调用student类,为其设置属性值的方法:
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第3张图片

1.3.4 通过字节码可以使用的方法

【JAVA】关于自动化测试所需要学习的java基础知识笔记_第4张图片
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第5张图片
以下方法比较重要,需掌握:
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第6张图片
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第7张图片

需掌握:
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第8张图片

【JAVA】关于自动化测试所需要学习的java基础知识笔记_第9张图片
具体使用:
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第10张图片

1.4 HashMap和HashSet

详见我的这篇博文:
https://blog.csdn.net/qq_34659777/article/details/87007252

1.5 File类和IO类

传送门:https://blog.csdn.net/qq_34659777/article/details/87100266

1.6 log4j的使用

传送门:https://blog.csdn.net/qq_34659777/article/details/83687434

2. 正则表达式

这个博客讲得很好:
https://baijiahao.baidu.com/s?id=1588848792548192879&wfr=spider&for=pc

3.XML

  1. xml:可扩展标记语言,在项目中的使用更多的是作为数据载体出现。
  • xml和json都是一种数据交互格式。
  • 所有元素有开始就有结束
  • 大小写敏感
  • 嵌套使用
  • 更多的作为数据载体而出现。
  • 非常适合万维网数据传输,提供统一方法描述和交换结构化数据
  1. xml声明:
  1. xml 中必须包含根元素,他是其他元素的父类型,下列实例中students就是一个根元素:

	
		honghong1
		20
		java82
		
	

  1. xml文档结构:
  • 和HTML类似,是一种树形结构从上至下扩展。
  • 使用父、子、同胞等术语来表示元素之间的关系。
  • 所有的元素都可以有文本内容和属性
  1. xml的语法和注释
  • 属性必须用双引号“” 引起来
  • 注释: 选中要注释的内容,然后点击

3.1 dom4j

dom4j是一个Java的XML API。
我们打开maven 中央仓库,在其中搜索dom4j,选择1.6.1版本。
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第11张图片

3.2 dom4j解析技术

用来解析xml中的数据,例如:


	
		honghong1
		20
		java82
		
	

将这个xml中的数据进行解析,使用方法:

		//new一个工具类
		SAXReader saxReade=new SAXReader();
		//读取这个文件-->文档-->提取信息
		Document document = saxReade.read(XmlReader.class.getResourceAsStream("/students.xml"));//类路径下根路径
		//获得根元素
		Element rootelement = document.getRootElement();
		//获得根节点的所有子节点
		List elements = rootelement.elements();
		for (Element element : elements) {
			//获得student子元素的id属性
			Attribute idattribute = element.attribute("id");
			//获得student元素的所有子元素
			List stuSubElements=element.elements();
			for (Element stuSubElement : stuSubElements) {
				//获得每个标签的名称
				System.out.println(stuSubElement.getName());
				//获得每个标签中的值
				System.out.println(stuSubElement.getText());
			}
		}

4. JDBC

4.1 什么是JDBC以及一些基础的SQL语句

JDBC:Java数据库连接(Java DataBase Connectivity)
用于执行SQL语句的Java API,Java语言编写的类和接口,为多种关系数据库提供统一访问。

4.1.1 创建表
// id、user_name,phone,pwd  -- sql 大小写不区分--》弱语法
create table member(
	id in(10),
	user_name varchar(20),
	phone char(11),
	pwd varchar(40)
);
4.1.2 插入行
insert into 表名(需要添加值的字段) values(每个字段的值);

insert INTO test(name,phone,sex) VALUES ("enna",MD5("13111111"),"nan")
4.1.3 删除行
  1. 删除表的所有记录

    delete from 表名;

  2. 删除部分记录

    delete from 表名 where 指定的条件;

  3. 删除整个表的记录(删除所有记录,而且会把自增长恢复到默认值)

    truncate table member;

  4. 删除表(破坏性,谨慎操作,删除结构)

    drop table member;

4.1.4 更新数据
update member set 字段1='新的值',字段2='新值'
4.1.5 查询数据
select 检索的字段 from 表名;
4.1.6 连接
-- 多表查询
-- 查询出来45条记录,叫做笛卡尔积
SELECT * FROM t_user,t_lover_info;
-- 想要筛选出有意义的记录
-- 等值连接
SELECT * FROM t_lover_info as t1,t_user as t2 WHERE t1.u_id=t2.id  
SELECT * FROM t_lover_info as t1 JOIN t_user as t2 ON t1.u_id=t2.id  
-- 内连接或等值连接,可以获取两个表中字段匹配关系的记录
SELECT * FROM t_lover_info as t1 INNER JOIN t_user as t2 ON t1.u_id=t2.id  
SELECT * FROM t_lover_info as t1 CROSS JOIN t_user as t2 ON t1.u_id=t2.id

--左连接,会读取左表的全部数据,即使右表没有对应数据。左连接从左表(A)产生一套完整的记录和右表匹配的记录,如果右表没有匹配记录,右侧结果集字段将为null
SELECT * FROM t_lover_info as t1 LEFT JOIN t_user as t2 ON t1.u_id=t2.id  
-- 右连接是以右表为基础,与LEFT JOIN相反
SELECT * FROM t_lover_info as t1 RIGHT JOIN t_user as t2 ON t1.u_id=t2.id  

【JAVA】关于自动化测试所需要学习的java基础知识笔记_第12张图片
其他sql语句的应用可以参考此前的博客:https://blog.csdn.net/qq_34659777/article/details/78225522

4.2 工具 Navicat Premium 的下载与破解

Navicat Premium v12.1.9破解版_x86_x64:
软件破解补丁:https://www.lanzous.com/i1v0ywd
12.x最新版本:http://download.navicat.com/download/navicat121_premium_cs_x64.exe

为了防止其中的软件及补丁分享失效,我在csdn上也已经上传了这两个软件的打包,链接:
https://download.csdn.net/download/qq_34659777/10968094

破解过程:卸载掉早期版本,卸载干净,然后安装最新版navicat,安装完成后将破解补丁复制到安装目录下,运行破解补丁,先patch;【JAVA】关于自动化测试所需要学习的java基础知识笔记_第13张图片
然后选择版本和语言;
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第14张图片
运行navicat,弹出注册界面,如果没有弹出注册界面,手动在菜单打开:帮助->注册,然后点击注册机的generate按钮,注册码会自动填写到navicat;点击navicat注册界面的激活按钮,提示手动激活;
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第15张图片
点击手动激活。
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第16张图片
然后将得到的RequestCode复制到注册机;
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第17张图片
点击注册机左下方的Generate按钮,生成ActivationCode,复制粘贴到navicat的激活码框,完成激活;
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第18张图片
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第19张图片

4.3 操作步骤

  1. 注册一个驱动
	//这一步首先要在maven或者程序中引入mysql-connector.jar
	Class.forName("com.mysql.jdbc.Driver");

注意:
如果你在这里使用的是最新的mysql 连接驱动,那么驱动这里需要修改一下,否则会报异常:

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

解决方法:
将以上代码改为:

Class.forName("com.mysql.cj.jdbc.Driver");
  1. 连接数据库
		String user = "futurevistor";
		String password = "123456";
		//jdbc是指使用mysql连接数据库,各个数据库管理工具使用的语法各不相同
		String url = "jdbc:mysql://120.78.128.25:3306/future";
		//DriverManager:负责访问数据库的驱动管理
		//Connection:与数据库进行连接的连接对象,所有与数据库的通信都是通过连接对象
		Connection conn = DriverManager.getConnection(url, user, password);
  1. 准备一个sql语句(这里以一个select语句为例)
	String sql = "select * from member;";
  1. 使用一个对象来封装SQL并执行
	PreparedStatement pstmt = conn.prepareStatement(sql);
  1. 执行这个sql语句,得到一个结果集
		ResultSet resultSet=pstmt.executeQuery();
		while (resultSet.next()) {
			String id=resultSet.getString(1);
			String regName=resultSet.getString(2);
			String pwd1=resultSet.getString(3);
			String phone=resultSet.getString(4);
			System.out.println(id+" , "+regName+" , "+pwd1+" , "+phone);
		}
  1. 关闭连接
		pstmt.close();
		conn.close();

注: 其中PreparedStatement处理的步骤:
【JAVA】关于自动化测试所需要学习的java基础知识笔记_第20张图片
代码如下:

		String sql = "select * from member_water where mmobilephone=? and pwd=?;";
		PreparedStatement pstmt = conn.prepareStatement(sql);
		//对占位符对应的参数进行设值,mobilePhone和pwd为传入的参数
		pstmt.setString(1, mobilePhone);
		pstmt.setString(2, pwd);

4.4 写一个简单的DBUtil框架

/**
 * JDBC工具类,提供增删改查
 * @author mayn
 *
 */
public class DBUtil {

	/**
	 * 0.注册驱动、连接数据库的而字符串代码冗余 1)只注册一遍 2)连接数据库的信息值声明一遍 1.重复的数据库的创建和关闭,形成资源的浪费
	 * 2.增删改查语法不具备通用性(没办法适用所有表、所有的增删改查数据)
	 * 
	 * @param args
	 * @throws Exception
	 */

	private static String user;
	private static String password;
	private static String url;
	private static String driver;

	/**
	 * 静态代码块,只运行一次,用于编写一些只需要运行一边的代码逻辑 通过静态库,保证注册驱动,以及读取数据库连接信息的操作只运行一遍
	 */
	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			Properties properties = new Properties();
			properties.load(DBUtil.class.getResourceAsStream("/jdbc.properties"));

			driver = properties.getProperty("jdbc.driver");
			user = properties.getProperty("jdbc.user");
			password = properties.getProperty("jdbc.password");
			url = properties.getProperty("jdbc.url");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception {
		// insert("kaibin", "hhhh", "13255555555");
	}

	private static Connection getConnection() throws SQLException {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url, user, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}

	/**
	 * 不确定参数的类型和个数
	 */
	public static void execute(String sql, Object... params) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		try {
			conn = getConnection();
			pstmt = conn.prepareStatement(sql);

			int length = params.length;
			for (int i = 0; i < length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}
			pstmt.execute();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			close(conn, pstmt);

		}
	}

	/**
	 * 
	 * @param sql
	 *            要执行的sql语句
	 * @param params
	 *            占位符对应的参数
	 * @return
	 * @throws Exception
	 */
	public static List> select(String sql, Object... params){
		Connection conn=null;
		PreparedStatement pstmt =null;
		List> datalist =null;
		ResultSet resultSet = null;
		try {
			conn = getConnection();
			pstmt = conn.prepareStatement(sql);
			// 进行占位符的设值
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}
			resultSet = pstmt.executeQuery();

			// 获得结果集的元数据
			ResultSetMetaData metaData = resultSet.getMetaData();
			// 获得列数,就是字段的数量
			int columnCount = metaData.getColumnCount();
			// 创建一个list存放所有的记录
			datalist = new ArrayList>();
			while (resultSet.next()) {
				// 创建一个mao对象,保存每一行数据
				Map rowDataMap = new HashMap();
				for (int i = 0; i < columnCount; i++) {
					// 获得每一列的值
					String value = resultSet.getString(i + 1);
					// 获得字段名使之为key
					String columnName = metaData.getColumnName(i + 1);
					rowDataMap.put(columnName, value);
				}
				// 此时每一行的数据已经保存完毕,将这个hashmap放到list中
				datalist.add(rowDataMap);
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			close(conn, pstmt, resultSet);
		}
		return datalist;
	}

	private static void close(Connection conn, PreparedStatement pstmt, ResultSet resultSet) {
		if(resultSet!=null){
			try {
				resultSet.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		close(conn, pstmt);
	}
	/**
	 * 关闭资源
	 * @param conn   连接
	 * @param pstmt   陈述对象
	 */
	private static void close(Connection conn, PreparedStatement pstmt) {
		if (pstmt != null) {
			try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

其中还包含一个jdbc.properties:

jdbc.url=jdbc:mysql://120.78.128.25:3306/future
jdbc.user=futurevistor
jdbc.password=123456
jdcc.driver=com.mysql.cj.jdbc.Driver

写完之后,只需要传入sql语句和可变参数就可以直接调用并进行增删改查操作了,例:

//新建了一个DBTest类用来测试框架是否可用
public class DBTest {

	public static void main(String[] args) throws Exception {
		//1.测试插入:
//		String sql="insert into member_water(regname,mobilephone,pwd,leaveamount) value(?,?,?,?);";
//		DBUtil.execute(sql, "kaibin","13212575740","123456",100.0);
		
		//修改
//		String sql="update member_water set leaveamount=? where id=?";
//		DBUtil.execute(sql,10.0,41);
		
		//删除
//		String sql="delete from member_water where id=?";
//		DBUtil.execute(sql, 41);
		
		//查询
		String sql="select * from member_water ";
		List> data=new ArrayList>();
		data=DBUtil.select(sql);
		for (Map map : data) {
			System.out.println(map);
		}
	}

}

5.TestNG

5.1 单元测试的概念

  • 单元测试(unit testing),是指对软件中的最小可测试单元(方法、函数)进行检查和验证。
  • 单元测试是开发者编写的一小段代码,用于检测被测代码的一个很小的、很明确的功能(方法、函数)是否正确
  • 单元测试是由程序员自己来完成,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试
  • 通常而言,一个单元测试适用于判断某个特定条件下某个特定函数的行为。
  • 执行单元测试就是为了证明这段代码的行为和我们的预期一致

5.2 TestNG的安装

Testing Next Generation,下一代测试技术。
利用注解来强化测试功能的测试框架,可以用来做单元测试和集成测试。
首先将testNG插件放到eclipse对应的文件夹下,testNG插件下载:
链接:https://pan.baidu.com/s/1VxctS80R7ckuEscZE-e3ZA
提取码:waob

将插件安装成功后,右键就能够在菜单中看见testNG。【JAVA】关于自动化测试所需要学习的java基础知识笔记_第21张图片

5.3 项目集成testNG

  • 项目集成testNG,加入依赖库

    org.testng
    testng
    6.8.8
    test

  • 选中testNG.xml执行测试套件时,可能会碰到ElementTravelsal找不到的问题:

    xml-apis
    xml-apis
    1.4.01

5.4 testNG的书写和运行

testNG的两种执行方式:

  1. 书写单独的测试类
    我们可以书写单独的测试类,然后右键–>Run As–>TestNG Test,然后在下面的Results中查看运行结果。
  2. 书写一个TestNG Suite
    例如:



  
    
      
      
    
   
  
  
    
      
      
    
   
 

然后右键testng.xml–>Run As–>TestNG Suite,然后可以在控制台和Results of running suite中分别查看结果。

5.5 eclipse 乱码问题

如果遇到eclipse乱码的问题,在eclipse.ini文件中添加:-Dfile.encoding=UTF-8

5.6 testNG中一些常用的注解

  1. 忽略测试
    当我们在测试的过程中,因为某些方面的原因,比如测试方法没有写完,或者是有问题,我们暂时希望它不执行,我们就可以添加忽略标签来跳过此方法的运行。
@Test(enable=false)
  1. 超时测试
    表示如果单元测试花费的时间超过制定的毫秒数,那么testNG将会中止它并将其标记为失败。这样在某些业务场景之下,我们认为一个请求时间过长就可以直接宣判他因为超时而失败。
@Test(timeOut=1000)
  1. 异常测试(使用较少)
    测试代码中有没有抛出我预测的这个异常。如果没有expectedExceptions列表中的异常抛出,或者抛出的异常不属于列表中的异常都无法通过。
@Test(expectedExceptions={NullPointerException.class,ClassNotFoundException.class})
  1. 依赖测试
    dependsOnMethods:这个的测试方法依赖于某些方法
@Test(dependsOnMethods={"e","d"})

方法的执行顺序:

  • 先执行被依赖的方法
  • 在依次执行没配置依赖的方法
  • 最后执行需要依赖的测试方法

dependsOnGroups:这个的测试方法依赖于某些组

  1. 分组测试
    只想执行某一部分或者个别的测试用例
  • 测试用例方法指定所属分组:groups
  • 在testng.xml的test中指定相应的测试类
  • 在test的groups里面指定run下要执行的分组
  • 当测试用例越来越多,某些分组不想执行,设置的方法也一样:在test的groups里面指定run选不需要执行的分组

语法:
测试方法属于哪一个分组:

@Test(groups={"g1,g2"})

此测试方法属于g1分组,但是依赖于g2分组:

@Test(dependsOnGroups={"g2"},groups={"g1"})

只会执行g1组的测试方法,其他测试方法都不会执行:(写在.xml文件中)


  	
  		
  		
  		
  		
  	
  
  1. 优先级设置
    后面的整数数字越低,优先级越高。
@Test(priority=1)

还要在.xml文件中开启


5.7 TestNG 执行 junit 测试

testNG提供了一种配置方式使得我们不需要去重构已经写好的junit单元测试类:
在testNG.xml中添加一个test,将junit属性设置为true即可:


  	
  		
  	
  

5.8 断言

【JAVA】关于自动化测试所需要学习的java基础知识笔记_第22张图片

5.9 数据驱动(Data Provider)

public class DataProviderTest {
	//表示由方法“dp”来注入数据,也叫数据驱动
	@Test(dataProvider = "dp")
	public void f(Integer n, String s,String name) {
		System.out.println(n+","+s+","+name);
	}

	//下面的这个方法是为测试单元测试方法提供数据的
	@DataProvider
	public Object[][] dp() {
		return new Object[][] {
			new Object[] { 1, "a","tom" },
			new Object[] { 2, "b" ,"jack"},
			new Object[] { 3, "a" ,"kaibin"},
			new Object[] { 4, "b" ,"honghong"},
		};
	}
}

你可能感兴趣的:(#,基于Java的自动化测试学习,#,Java)