自动化测试脚本实践:基于 Bash 的模块化测试框架

前言

  在现代软件开发中,测试自动化是确保软件质量和稳定性的核心手段之一。随着开发周期的缩短和功能模块的增多,手动测试逐渐无法满足高效性和准确性的需求。因此,测试人员需要依赖自动化工具来提升测试效率,减少人为干预和错误。

  本文将介绍一款基于 Bash 脚本的简单自动化测试工具,它旨在帮助测试人员高效地管理和执行多种测试任务。这个脚本不仅能在命令行下交互式地进行模块选择,还能根据实际测试结果显示通过或失败的状态,方便测试人员快速识别问题。

一、目录结构

test/
├── config.conf
├── scripts/
│   └── eth.sh
└── tools/
└── xxx_test_scripts.sh

eth.sh: 当前示例脚本,一个sh脚本写一个测试功能,所有测试脚本都放在scripts目录下;
xxx_test_scripts.sh: 这是框架的主脚本,包含多个可选的测试模块,用户可以根据需要选择并执行某个具体的功能测试;
config.conf: 配置文件,用于存储全局配置、测试项启用状态以及其他参数;
tools/: 存放工具或素材,用于扩展框架的功能。

二、代码

1、config.conf

# ====== 0 代表启用测试项,1 代表不启用测试项 ======
example1_activation=0
example2_activation=0
example3_activation=0

# ====== 其它功能配置 ======
test=888


2、eth.sh

#!/bin/bash

# 获取当前脚本所在的目录
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
echo "Current script directory: ${SCRIPT_DIR}"

# 返回到上级目录
PARENT_DIR=$(dirname "$SCRIPT_DIR")
echo "Parent directory: ${PARENT_DIR}"

# 加载上级目录中的配置文件
source ${PARENT_DIR}/config.conf
echo "${test}"


test_eth() {
	eth_status="$1"
	if ! ip link show "$eth_status" | grep -q "state UP"; then
		exit 1 # 失败时退出,返回 1
	else
		exit 0 # 成功时退出,返回 0
	fi
}

test_eth "$1"

3、xxx_test_scripts.sh

#!/bin/bash

# 获取当前脚本所在的目录
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)

# 检查 config.conf 是否存在
if [[ ! -f "${SCRIPT_DIR}/config.conf" ]]; then
	echo "config.conf not found!"
	exit 1
fi

# 加载配置文件
source ${SCRIPT_DIR}/config.conf


EXAMPLE1_RESULT=0
EXAMPLE2_RESULT=0
EXAMPLE3_RESULT=0


# 依赖软件安装
install() {
	if ! command -v figlet > /dev/null 2>&1; then
		echo "Writing the installation method."
	fi
}


test_example1() {
	read -p "example1 test results(y: pass - n: fail): " example1
	if [[ "${example1}" == "N" ]] || [[ "${example1}" == "n" ]]; then
		EXAMPLE1_RESULT=1
		echo -e "####################\033[31m example1:      fail \033[0m#####################"
		echo "##############################################################"
	else
		EXAMPLE1_RESULT=0
		echo -e "####################\033[32m example1:      pass \033[0m#####################"
		echo "##############################################################"
	fi
}

test_example2() {
	read -p "example2 test results(y: pass - n: fail): " example2
	if [[ "${example2}" == "N" ]] || [[ "${example2}" == "n" ]]; then
		EXAMPLE2_RESULT=1
		echo -e "####################\033[31m example2:      fail \033[0m#####################"
		echo "##############################################################"
	else
		EXAMPLE2_RESULT=0
		echo -e "####################\033[32m example2:      pass \033[0m#####################"
		echo "##############################################################"
	fi
}

test_example3() {
	sudo chmod 777 ${SCRIPT_DIR}/scripts/eth.sh
	sudo ${SCRIPT_DIR}/scripts/eth.sh eth0
	if [[ $? -eq 0 ]]; then
		EXAMPLE3_RESULT=0
		echo -e "####################\033[32m example3:      pass \033[0m#####################"
		echo "##############################################################"
	else
		EXAMPLE3_RESULT=1
		echo -e "####################\033[31m example3:      fail \033[0m#####################"
		echo "##############################################################"
	fi
}

test_exit() {
	exit 11
}

module_choice() {
	echo " "
	echo "**************** Test Module Selection (Failures Detected) ****************"
	echo " 0 (exit                              test)"

	if [[ ${example1_activation} == "0" ]]; then
		if [[ ${EXAMPLE1_RESULT} -eq 0 ]]; then
			echo -e " 1 (example1                          test) [\033[32m pass \033[0m]"
		else
			echo -e " 1 (example1                          test) [\033[31m fail \033[0m]"
		fi
	fi

	if [[ ${example2_activation} == "0" ]]; then
		if [[ ${EXAMPLE2_RESULT} -eq 0 ]]; then
			echo -e " 2 (example2                          test) [\033[32m pass \033[0m]"
		else
			echo -e " 2 (example2                          test) [\033[31m fail \033[0m]"
		fi
	fi

	if [[ ${example3_activation} == "0" ]]; then
		if [[ ${EXAMPLE3_RESULT} -eq 0 ]]; then
			echo -e " 3 (example3                          test) [\033[32m pass \033[0m]"
		else
			echo -e " 3 (example3                          test) [\033[31m fail \033[0m]"
		fi
	fi

	echo " R (Failure item                      test)"
	echo "***************************************************************************"

	read -p "please select a test module to rerun or exit: " MODULE_CHOICE
}

module_test() {
	MODULE_CHOICE=$(echo "$MODULE_CHOICE" | tr '[:upper:]' '[:lower:]')
	case ${MODULE_CHOICE} in
		0)
			test_exit
			;;
		1)
			if [[ ${example1_activation} == "0" ]]; then
				test_example1
			fi
			;;
		2)
			if [[ ${example2_activation} == "0" ]]; then
				test_example2
			fi
			;;
		3)
			if [[ ${example3_activation} == "0" ]]; then
				test_example3
			fi
			;;
		r)
			# Failure item选项,重新测试所有失败的项
			if [[ ${EXAMPLE1_RESULT} -eq 1 ]]; then
				test_example1
			fi
			
			if [[ ${EXAMPLE2_RESULT} -eq 1 ]]; then
				test_example2
			fi

			if [[ ${EXAMPLE3_RESULT} -eq 1 ]]; then
				test_example3
			fi
			;;
		# *)
			# echo "Invalid choice. Please try again."
			# ;;
	esac
}

check_all_pass() {
	local test_results=(
	    ${EXAMPLE1_RESULT}
	    ${EXAMPLE2_RESULT}
	    ${EXAMPLE3_RESULT}
	)

	all_zero=true

	# 如果有一个结果等于1,标记为false
	for all_result in "${test_results[@]}"; do
		if [[ "${all_result}" -eq 1 ]]; then
			all_zero=false
			break
		fi
	done

	# 获取全部测试结果 0通过 1不通过
	if [[ "$all_zero" == true ]]; then
		return 0  # 返回0表示所有结果为0
	else
		return 1  # 返回1表示至少有一个结果不为0
	fi
}

test_single() {
	while true; do
		module_choice
		module_test
		check_all_pass
		if [[ $? -eq 0 ]]; then
			echo "****************************************************************"
			echo -e "\033[32m$(figlet "PASS")\033[0m"
			echo "****************************************************************"
			break
		fi
		sleep 1
	done
}

test_all() {
	echo " "
	echo "******************** Test Execution Started ********************"
	echo "****************************************************************"
	echo " "
	if [[ ${example1_activation} == "0" ]]; then
		test_example1
		sleep 1
	fi

	if [[ ${example2_activation} == "0" ]]; then
		test_example2
		sleep 1
	fi

	if [[ ${example3_activation} == "0" ]]; then
		test_example3
		sleep 1
	fi

	echo " "
	echo " "
	echo "********************* Test Results Summary *********************"
	echo "****************************************************************"

	if [[ ${example1_activation} == "0" ]]; then
		if [[ ${EXAMPLE1_RESULT} -eq 0 ]]; then
		 	echo -e "example1:                       \033[32m pass \033[0m"
		else
			echo -e "example1:                       \033[31m fail \033[0m"
		fi
	fi

	if [[ ${example2_activation} == "0" ]]; then
		if [[ ${EXAMPLE2_RESULT} -eq 0 ]]; then
		 	echo -e "example2:                       \033[32m pass \033[0m"
		else
			echo -e "example2:                       \033[31m fail \033[0m"
		fi
	fi

	if [[ ${example3_activation} == "0" ]]; then
		if [[ ${EXAMPLE3_RESULT} -eq 0 ]]; then
		 	echo -e "example3:                       \033[32m pass \033[0m"
		else
			echo -e "example3:                       \033[31m fail \033[0m"
		fi
	fi

	echo " "
	check_all_pass
	if [[ $? -eq 0 ]]; then
		echo "****************************************************************"
		echo -e "\033[32m$(figlet "PASS")\033[0m"
		echo "****************************************************************"
	else
		echo "****************************************************************"
		echo -e "\033[31m$(figlet "FAIL")\033[0m"
		echo "****************************************************************"
		echo " " 
		echo " "
	fi
}

send_result() {
	echo "Upload test results."
}

main() {
	install
	test_all
	check_all_pass
	if [[ $? -eq 1 ]]; then
		test_single
	fi
	send_result
}

main

注释:文件必须 Unix(LF) 格式 ,可用通过 notepad++ 转换

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/952258.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity打包+摄像机组件

转换场景 使用程序集:using UnityEngine.SceneManagement; 切换场景相关代码:SceneManager.LoadScene(1);//括号内可放入场景名称,场景索引等 //Application.LoadLevel(""); 老版本Unity加载场景方法 打包相关 Bundle Identi…

【游戏设计原理】58 - 主题

一、理解这里的游戏主题 1. 什么是游戏的主题呢?用一句话描述。 游戏主题是游戏所要传达的中心思想。 2. Theme 和 Message 的区别 特性主题(Theme)主旨(Message)定义是游戏围绕的上下文或背景,指游戏的…

26、【OS】【Nuttx】用cmake构建工程

背景 之前wiki 14、【OS】【Nuttx】Nsh中运行第一个程序 都是用 make 构建,准备切换 cmake 进行构建,方便后续扩展开发 Nuttx cmake 适配 nuttx项目路径下输入 make distclean,清除之前工程配置 adminpcadminpc:~/nuttx_pdt/nuttx$ make …

donet (MVC)webAPI 的接受json 的操作

直接用对象来进行接收&#xff0c;这个方法还不错的。 public class BangdingWeiguiJiluController : ApiController{/// <summary>/// Json数据录入错误信息/// </summary>/// <param name"WeiguiInfos"></param>/// <returns></r…

从预训练的BERT中提取Embedding

文章目录 背景前置准备思路利用Transformer 库实现 背景 假设要执行一项情感分析任务&#xff0c;样本数据如下 可以看到几个句子及其对应的标签&#xff0c;其中1表示正面情绪&#xff0c;0表示负面情绪。我们可以利用给定的数据集训练一个分类器&#xff0c;对句子所表达的…

Kafka 会丢消息吗?

目录 01 生产者(Producer) 02 消息代理(Broker) 03 消费者(Consumer) 来源:Kafka 会丢消息吗? Kafka 会丢失信息吗? 许多开发人员普遍认为,Kafka 的设计本身就能保证不会丢失消息。然而,Kafka 架构和配置的细微差别会导致消息的丢失。我们需要了解它如何以及何时…

RPM包安装Nginx部署Zr.Admin Vue2前端

0、确认node环境 安装node 参考Linux Red Hat安装包安装nodejs 设置 registry 执行 npm set registry https://registry.npmmirror.com/ 1、安装依赖 进入代码根目录 cd /lsp/code/zradmin/ZR.Vue 安装依赖 执行 npm install 最后生成node_modules文件夹 2、测试运行 …

【SpringBoot】入门

【SpringBoot】入门 一、前言1 什么是 Spring Boot ?2 特点与优势3 发展历程 二、项目构建【基于IDEA】1 创建 Spring Boot 项目2 项目结构3 运行 Spring Boot 项目 三、补充1 Maven操作2 项目打 jar 包在本地运行 一、前言 1 什么是 Spring Boot ? Spring Boot最开始基于S…

如何在本地部署大模型并实现接口访问( Llama3、Qwen、DeepSeek等)

如何在本地部署大模型并实现接口访问&#xff08; Llama3、Qwen、DeepSeek等&#xff09; 如何在本地部署大模型并实现接口访问&#xff08; Llama3、Qwen、DeepSeek等&#xff09;模型地址模型下载模型部署指定显卡运行app.py 运行环境requirements 调用接口代码调用 结语 如何…

vmware-ubuntu22.04配置虚拟机win10,重新上网成功

打开问题显示 Hardware配置 Options配置 最后的Advanced&#xff0c;第一次用了BIOS&#xff0c;然后启动中有更新&#xff0c;然后关闭&#xff0c;再用UEFI启动

GDPU Android移动应用 重点习题集

目录 程序填空 ppt摘选 题目摘选 “就这两页ppt&#xff0c;你还背不了吗” “。。。” 打开ppt后 “Sorry咯&#xff0c;还真背不了&#x1f61c;” 更新日志 考后的更新日志 没想到重点勾了一堆&#xff0c;还愣是没考到其中的内容&#xff0c;翻了一下&#xff0c;原…

运行.Net 7 Zr.Admin项目(后端)

1.下载Zr.Admin代码压缩包 https://codeload.github.com/izhaorui/Zr.Admin.NET/zip/refs/heads/main 2.打开项目 我这里装的是VS2022社区版 进入根目录&#xff0c;双击ZRAdmin.sln打开项目 3.安装.net7运行时 我当时下载的代码版本是.net7的 点击安装 点击安装&#xff0…

代码随想录算法训练营第3天(链表1)| 203.移除链表元素 707.设计链表 206.反转链表

一、203.移除链表元素 题目&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 视频&#xff1a;手把手带你学会操作链表 | LeetCode&#xff1a;203.移除链表元素_哔哩哔哩_bilibili 讲解&#xff1a;代码随想录 注意&#xff1a; 针对头结点和非头结点的…

2024年总结及2025年目标之关键字【稳进】

1. 感受 时光荏苒&#xff0c;都731天&#xff08;2年时间&#xff09;下来了&#xff0c;从第一年的【坚持】&#xff0c;到第二年的【提速】&#xff0c;定目标&#xff0c;现在回头看&#xff0c;还是那句话【事非经过不知难】&#xff0c;那又怎么样呢&#xff0c;再难不是…

qt QLabel QPushButton 控件重写paintEvent后 控件消失

qt 继承自PushButton控件的类 重写paintEvent后 控件消失 解决办法&#xff0c;在paintevent结尾加上这条语句&#xff1a;QPushButton::paintEvent(event); void MyButton::paintEvent(QPaintEvent *event) {QPushButton::paintEvent(event); } 这里QPushButton不能写成Q…

苹果手机(IOS系统)出现安全延迟进行中如何关闭?

苹果手机&#xff08;IOS系统&#xff09;出现安全延迟进行中如何关闭&#xff1f; 一、设置二、隐私与安全性三、失窃设备保护关闭 一、设置 二、隐私与安全性 三、失窃设备保护关闭

ELK的搭建

ELK elk&#xff1a;elasticsearch logstatsh kibana统一日志收集系统 elasticsearch&#xff1a;分布式的全文索引引擎点非关系型数据库,存储所有的日志信息&#xff0c;主和从&#xff0c;最少需要2台 logstatsh&#xff1a;动态的从各种指定的数据源&#xff0c;获取数据…

从CentOS到龙蜥:企业级Linux迁移实践记录(龙蜥开局)

引言&#xff1a; 在我们之前的文章中&#xff0c;我们详细探讨了从CentOS迁移到龙蜥操作系统的基本过程和考虑因素。今天&#xff0c;我们将继续这个系列&#xff0c;重点关注龙蜥系统的实际应用——特别是常用软件的安装和配置。 龙蜥操作系统&#xff08;OpenAnolis&#…

【AI自动化渗透】大模型支持的自动化渗透测试,看蚂蚁和浙大的

参考文章: https://mp.weixin.qq.com/s/WTaO54zRxtNMHaiI1tfdGw 最近&#xff0c;美国西北大学&#xff0c;浙江大学&#xff0c;蚂蚁集团的一些专家学者联手发表了一篇论文&#xff0c;介绍了一个PentestAgent的方案&#xff0c;实现了渗透测试自动化。 01 技术方案 图的字…

探秘block原理

01 概述 在iOS开发中&#xff0c;block大家用的都很熟悉了&#xff0c;是iOS开发中闭包的一种实现方式&#xff0c;可以对一段代码逻辑进行封装&#xff0c;使其可以像数据一样被传递、存储、调用&#xff0c;并且可以保存相关的上下文状态。 很多block原理性的文章都比较老&am…